You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Opt-in reaper for idle subscription-engine tmux sessions #141
On the subscription engine, every chat keeps its tmux session (ccs-<id>) alive
indefinitely: the interactive claude plus every MCP server it spawned. Nothing
reaps an idle one; CLAUDE_IDLE_TIMEOUT_MS only bounds a single turn. Memory
therefore grows with the number of chats opened since the last restart.
Measured on Docker (CLI 2.x, a typical MCP set): ~1.2 GB per open session
(claude ~300 MB + MCP servers ~900 MB). Two idle chats ~2.4 GB, on a
12 GB host.
Proposal
An opt-in idle reaper, e.g. CCS_ENGINE_IDLE_KILL_MS (unset = current behaviour):
kill ccs-<id> when no turn ran and no viewer is attached for that long;
Implemented on main in eb26917a (PR #142). It ships in the next release.
CCS_ENGINE_IDLE_KILL_MS is opt-in — unset or 0 keeps today's behaviour. When set, a ccs-<id> pane with no turn and no attached viewer for that long is killed, and the next message respawns it with --resume <cid> — the same path the config-change respawn already uses — so no history is lost.
The skip rules are the three you listed, plus one:
a running turn — read from the studio's own liveness registries (activeTasks / activeChatSessions / an in_progress Kanban task), which also covers the autoSkill window before the subprocess exists;
an attached view=engine viewer — and while attached the clock keeps being refreshed, so closing the pane does not hand the reaper an expired timer;
a pane with no recorded age (created before this feature, or after a restart that lost the tmux environment) — its clock is started instead of trusted, so nothing is killed on the first tick after an upgrade.
The idle clock is stamped when a turn ends, not when the pane spawns, so a long first turn never counts as idle time.
Docs list the variable in .env.example and the three READMEs. test/engine-idle-reaper.test.js covers the decision table and drives a real tmux pane, where a control-mode client must count as a viewer. CI is green on both matrix legs (Node 20 and 24).
Activity
engine: opt-in idle reaper for subscription tmux sessions (#141) (#142)
Lexus2016 commentedon Nov 12, 2026
Implemented on
mainineb26917a(PR #142). It ships in the next release.CCS_ENGINE_IDLE_KILL_MSis opt-in — unset or0keeps today's behaviour. When set, accs-<id>pane with no turn and no attached viewer for that long is killed, and the next message respawns it with--resume <cid>— the same path the config-change respawn already uses — so no history is lost.The skip rules are the three you listed, plus one:
activeTasks/activeChatSessions/ anin_progressKanban task), which also covers the autoSkill window before the subprocess exists;view=engineviewer — and while attached the clock keeps being refreshed, so closing the pane does not hand the reaper an expired timer;The idle clock is stamped when a turn ends, not when the pane spawns, so a long first turn never counts as idle time.
Docs list the variable in
.env.exampleand the three READMEs.test/engine-idle-reaper.test.jscovers the decision table and drives a real tmux pane, where a control-mode client must count as a viewer. CI is green on both matrix legs (Node 20 and 24).