Cold-start dashboard responsiveness went from ~99s to ~6-11s. CPU profiling
identified two synchronous-spawn hotspots blocking the event loop:
- `GitHubTrackingReconciler` scanned up to 200 done tasks per startup,
each call into `getIssue` invoking `isGhAvailable()` + `isGhAuthenticated()`
via `execFileSync`. `gh auth status` makes a network roundtrip, so 400
sync spawns ≈ 71s of pure event-loop blocking (69% of cold-start CPU).
Memoized both checks with a 60s TTL; `resetGhAvailabilityCache()` is
exported for login/logout flows that need immediate invalidation.
- `PRAGMA integrity_check(100)` walks every page of the SQLite file (~7s
per database, multiple DBs × projects). The deferred check was scheduled
3s after init — right in the responsiveness-critical window. Pushed to
60s so the user is already interacting before it runs; check itself is
unchanged.
Also yields the event loop between major InProcessRuntime init phases and
between self-healing recovery steps (34 per project), defers orphan-task
AI agent resumption by 30s (env-overridable, auto-zero under Vitest), and
ships an opt-in `FUSION_TRACE_EL_LAG=/path/to/file` event-loop lag tracer
that diagnosed all of the above.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Subtask, mission-interview, and milestone/slice-interview sessions could pin
their `generating` state forever when the underlying provider stream stalled
silently or a tool call hung. Wrap each `agent.session.prompt()` in a new
GenerationGuard helper (per-session AbortController + timer) so a stuck turn
becomes a bounded error users can retry. Adds matching `stop*Generation`
exports and threads abort through cleanup so dismissing a modal cancels the
in-flight call instead of leaking it.
Also closes the gh-cli tool hang vector: `runGhAsync` / `runGhJsonAsync` now
accept `{ signal, timeoutMs }` (default 30s). Github-touching extension tools
forward the AI tool's signal so an aborted agent kills the `gh` child instead
of orphaning it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- no-useless-escape: drop needless backslashes in character classes and
URL/path regexes (gh-cli, store, task, modelFilter, useFileMention,
RoutineEditor, ScheduleForm).
- no-case-declarations: wrap case bodies in ProjectOverview and
SettingsModal with block scopes.
- prefer-const: convert a never-reassigned slug binding in agent-import;
annotate legitimate forward-declared let bindings in dashboard.ts that
callbacks close over before assignment.
- no-fallthrough: add missing break after settings-subcommand error.
- no-empty-interface/no-empty-object-type: convert ProjectManifest from
empty interface extension to a type alias.
- no-unused-expressions: replace `x && x.method()` short-circuits in
TerminalModal with optional chaining.
Then ratchet these rules from warn → error so regressions are blocked.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Create gh-cli utility module with auth detection and command execution
- Refactor GitHubClient to use gh CLI commands with REST API fallback
- Refactor PR Monitor to use gh CLI for PR operations
- Add listIssues() and getIssue() methods to GitHubClient
- Remove in-app GitHubRateLimiter (gh CLI handles rate limiting)
- Update all tests for gh CLI implementation
- Update AGENTS.md and extension docs for gh CLI auth preference