feat(daemon): auto-respawn via per-project watchdog (#116) - #119
Merged
Conversation
When the shared MCP daemon is killed (Stop-Process, kill -9, crash) while the proxy host is still running, the incremental file-watcher was lost until the user manually ran 'codegraph-vba sync'. This change adds a per-project daemon liveness watchdog inside the proxy that polls the daemon's .codegraph-vba/daemon.pid lockfile every 30s and respawns the daemon (via the same detached-spawn recipe the launcher uses) when the pid points at a dead process.
Architecture:
- src/mcp/daemon-watchdog.ts (new): DaemonWatchdog class. Constructor takes an injectable spawnFn so tests can stub the detached spawn without ESM-fragile vi.mock('child_process') patches. hasLiveDaemon(root) reads the lockfile via decodeLockInfo (the lockfile is the authoritative pointer; listDaemons filters dead entries from its return value, so it cannot be used to detect a dead daemon -- that was the trap in v1).
- src/mcp/index.ts: MCPServer (proxy mode) instantiates a watchdog per project root, starts it, and tears it down on stop(). Watchdog intervals are unref-ed so they never keep the proxy alive.
Why a watchdog (vs. spawn-on-demand at MCP request time): the issue's repro is Stop-Process -Id <pid> while the MCP keeps serving -- file edits are missed until the user manually runs 'codegraph-vba sync'. The watchdog closes that gap in <30s.
Tests (15/15 green across the daemon tests):
- __tests__/daemon-watchdog.test.ts (9 tests): covers hasLiveDaemon for the 3 lockfile states, checkAndRespawn (live=no-op, dead=respawn, no-.codegraph=no-op), tick -> respawn integration (single + double), start/stop behavior.
- __tests__/daemon-registry.test.ts: unchanged, still 6/6.
Closes #116.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The shared MCP daemon auto-respawns when killed while the proxy is still up. After \Stop-Process -Id \ (or any other death cause) the proxy per-project daemon watchdog detects the dead daemon via its .codegraph-vba/daemon.pid\ lockfile and respawns it within 30s — file edits are picked up automatically instead of needing a manual \codegraph-vba sync.
What is in
Acceptance
px vitest run tests/daemon-watchdog.test.ts\ — 9/9 passed
px vitest run tests/daemon-registry.test.ts\ — 6/6 (no regression)
px tsc --noEmit\ clean
Reopens the work from #118 after a rebase to resolve the CHANGELOG conflict with #117. Closes #116.