Summary
Closed agents persist in the sidebar indefinitely. The only way to clear them is to fully close and reopen opensessions (server restart). Toggling the sidebar does not help.
Root causes
Bug 1 (primary): prune_terminal() and prune_stuck() are implemented but never called
packages/runtime-rs/src/tracker.rs has both pruning methods:
prune_terminal — removes terminal-status agents (Done / Error / Interrupted / Stale) after TERMINAL_PRUNE_MS (5 min), skipping unseen and still-alive ones
prune_stuck — removes Running / ToolRunning agents that have received no update past a configurable timeout and are not alive
Neither is called anywhere in apps/server-rs/src/lib.rs. The background loops (run_agent_watcher_loop, run_tmux_state_poll_loop) never invoke them, so the AgentTracker only grows — entries are never pruned until the server process restarts.
Bug 2 (contributing): /pane-exited hook handler ignores the agent tracker
apps/server-rs/src/lib.rs:1062 — the handler for the pane-exited tmux hook:
"/pane-exited" => {
// kills orphaned sidebar panes, enforces width
// returns None — no state broadcast, no tracker update
}
It does not call sync_agent_pane_presence() and returns None, so the sidebar is not refreshed when a pane exits. The next update only happens on the 2-second TMUX_STATE_POLL_MS tick.
Bug 3 (minor): /pane-died hook is installed but silently rejected
tmux_provider.rs installs a pane-died tmux hook alongside pane-exited, but is_ok_hook_path() only whitelists /pane-exited — not /pane-died. Requests for /pane-died are rejected before reaching the handler.
Expected fix
- Call
tracker.prune_terminal() and tracker.prune_stuck(timeout_ms) on each tick inside run_tmux_state_poll_loop or run_agent_watcher_loop
- In the
/pane-exited handler, call self.sync_agent_pane_presence() and return Some(self.snapshot_json()) to push an immediate update
- Add
/pane-died to is_ok_hook_path and handle it the same as /pane-exited
Environment
- opensessions latest (
a383e9f)
- macOS, tmux
Summary
Closed agents persist in the sidebar indefinitely. The only way to clear them is to fully close and reopen opensessions (server restart). Toggling the sidebar does not help.
Root causes
Bug 1 (primary):
prune_terminal()andprune_stuck()are implemented but never calledpackages/runtime-rs/src/tracker.rshas both pruning methods:prune_terminal— removes terminal-status agents (Done / Error / Interrupted / Stale) afterTERMINAL_PRUNE_MS(5 min), skipping unseen and still-alive onesprune_stuck— removes Running / ToolRunning agents that have received no update past a configurable timeout and are not aliveNeither is called anywhere in
apps/server-rs/src/lib.rs. The background loops (run_agent_watcher_loop,run_tmux_state_poll_loop) never invoke them, so theAgentTrackeronly grows — entries are never pruned until the server process restarts.Bug 2 (contributing):
/pane-exitedhook handler ignores the agent trackerapps/server-rs/src/lib.rs:1062— the handler for thepane-exitedtmux hook:It does not call
sync_agent_pane_presence()and returnsNone, so the sidebar is not refreshed when a pane exits. The next update only happens on the 2-secondTMUX_STATE_POLL_MStick.Bug 3 (minor):
/pane-diedhook is installed but silently rejectedtmux_provider.rsinstalls apane-diedtmux hook alongsidepane-exited, butis_ok_hook_path()only whitelists/pane-exited— not/pane-died. Requests for/pane-diedare rejected before reaching the handler.Expected fix
tracker.prune_terminal()andtracker.prune_stuck(timeout_ms)on each tick insiderun_tmux_state_poll_looporrun_agent_watcher_loop/pane-exitedhandler, callself.sync_agent_pane_presence()and returnSome(self.snapshot_json())to push an immediate update/pane-diedtois_ok_hook_pathand handle it the same as/pane-exitedEnvironment
a383e9f)