smokeTestDaemonBroker mkdtemp'd its runtime dir directly under
os.tmpdir(), and the broker's startup sweep pruneDeadDaemonRuntimeDirs
reclaims path.dirname(runtimeDir). On a default session that is /tmp, so
--smoke-test recursively deleted every aged sibling with no live
broker/clients (tmux/ssh sockets, editor state, build trees) while still
exiting 0.
- client.ts: keep the smoke broker's project and runtime dirs under a
single private mkdtemp parent the process owns.
- presence.ts: refuse any prune root that is not the daemons container
and only prune entries named like a 16-hex daemon scope key, so a
relocated runtime dir can never rm -rf unrelated neighbours.
Fixes#8721
~/.omp/run/daemons/<hash> scopes accumulated forever: broker shutdown
removed only the socket and PID lease, and nothing swept dead scopes, so
inert broker state and the persistent shared Chromium profiles grew
without bound (reporter: 1.3GB / 198 dirs in ~4 weeks).
Each broker now sweeps its sibling daemon roots on startup and removes a
scope only when its broker.pid is absent/dead, no live client presence
remains, and it has been untouched past a stale grace. The caller's own
runtime dir and the machine-global daemon container are skipped. The
sweep is detached and non-throwing so it never delays client connects.
Fixes#8674
- Replaced time-based sleeps and polling loops with event-driven promise resolvers and fake timers across agent and tool tests.
- Migrated test suites to share in-memory auth storage and fixtures using lifecycle hooks.
- Updated catalog model definitions, metadata, and configurations.
The coding-agent CI runner collects test files only from packages/coding-agent/test (scripts/ci-test-ts.ts), so the regression at src/launch/broker.test.ts was skipped by bun run test and CI.
Relocated to test/launch/broker-idle-shutdown.test.ts and rewrote it to the in-process broker pattern used by the sibling broker tests: it awaits the broker's own run() promise (resolves on idle shutdown) instead of watching the PID file, so shutdown is an awaited signal rather than a poll.
Fixes#8110
Preserved zero-width readiness and wait matches across the daemon wire protocol, and isolated malformed completion events from unrelated pending RPCs.
Fixes#7908
Publish terminal daemon completions to the session that started the
process so idle agents can resume without polling hub status.
Persist every unacknowledged generation with a stable completion ID and
immutable snapshot. Replay the collection after reconnect or broker
recovery, and clear each event only after the owning client acknowledges
it.
Signed-off-by: Christian Stewart <christian@aperture.us>
startDaemonBrokerFromEnvironment now sets the kernel-visible name via
prctl, so restoring only process.title left the test runner's
/proc/self/comm as "omp daemon brok" for the rest of the Linux run.
A recovered detached daemon has no in-memory process handle, so two
concurrent refreshes can both enter settle for the same dead pid. The
initial guard runs before detached output is read; both continuations
could therefore pass it and then double-settle the generation.
Recheck generation and settled states after the awaited output read,
and cover concurrent refreshes against a recovered daemon. Without the
post-read guard the regression test observes restartCount 2 instead of
1.
Fixes#6852
A detached restart:"always" daemon that exits quickly parks in the
`restarting` state with process/pid cleared and a restartTimer armed.
Every subsequent op ran #refreshDetached, which only skips terminal
states, so it fell through to a re-entrant #settle. #settle's guard
only checked generation and terminalState, so re-entry proceeded:
restartCount++ and record.restartTimer was overwritten without clearing
the previously armed timer, orphaning it.
Consequences: stop cleared only the last timer, so an orphaned timer
later fired #launch (resetting stopRequested) and resurrected the
daemon; and restartCount phantom-inflated on every list/logs poll.
Add `restarting` to #settle's entry guard: it is a settled state
(child exited, relaunch timer pending) and no legitimate caller settles
while in it. Closes both the timer leak and the count inflation.
Fixes#6852