Skip to content

chore(daemon): #719 follow-ups — takeover notice, dev state-dir pruning, session state-dir command surface #737

@thymikee

Description

@thymikee

Follow-ups from the #719 review (worktree-scoped daemon state, merged as 0f7187f). Part of #722. Three small, independent items:

1. Emit a one-line info when the client replaces a running daemon

When readReusableLocalDaemon finds an existing daemon that is not reusable, it silently kills and replaces it (src/daemon-client.ts:592-601stopDaemonProcessForTakeover; further takeover sites at :691 and :861). With worktree-scoped state dirs this happens less often, but when it does happen (version bump, rebuilt binary → code-signature change, unreachable daemon, legacy global-dir migration) the user gets no signal that their daemon — possibly mid-session from another terminal — was just taken over.

  • Print one line to stderr at takeover, stating the reason and identity, e.g. Replacing daemon (pid 12345, v0.17.1) in <state-dir>: version mismatch (client v0.18.0). Reasons to distinguish: version mismatch, code-signature mismatch, unreachable.
  • Match the channel/style used for the update-available notice (one line, stderr, no decoration); never fail the command if printing fails.
  • Cover with a unit test alongside the existing daemon-client lifecycle tests (coordinate with test: characterization tests for daemon-client lifecycle (M0-1) #723, which is adding characterization tests around exactly this path).

2. Prune stale worktree-scoped state dirs

Every source worktree creates ~/.agent-device/dev/<slug>-<hash> (logs, sessions, daemon metadata) that outlives the worktree — nothing ever deletes these.

  • Add pruning to pnpm clean:daemon (or a --prune-dev flag / standalone script): for each dir under ~/.agent-device/dev/, if no live daemon owns it (check daemon.json PID + process-start-time, the same liveness check server-lifecycle.ts uses) and it is older than some threshold (e.g. 14 days since last modification), remove it.
  • Never touch the global ~/.agent-device root contents; scoped dirs only.
  • Print what was removed (one line per dir).

3. Fold session state-dir into the command surface

session state-dir is implemented as a pre-dispatch special case in cli.ts (tryPrintSessionStateDir), so the MCP server and typed client don't expose it, and it adds another branch to the function fallow ranks as the repo's cognitive-complexity maximum.

  • Move it into the regular command grammar/surface (it's a pure local resolution — no daemon round-trip needed; it can stay daemon-less the way connection/auth commands do).
  • Acceptance: cli.ts special case removed; command listed via the normal metadata (help output unchanged or improved); MCP tools/list exposes it; existing cli-session-state-dir.test.ts behavior preserved.
  • Reasonable to defer or fold into the eventual cli.ts decomposition if that lands first — note on the issue if so.

Items 1 and 2 are S each; item 3 is S-M. All three are independent of each other and of the #726/#727 chain.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions