reapOrphanTabs
reapOrphanTabs(
herdr,prevShellOnly?):Promise<ReapResult>
Defined in: src/tab-reaper.ts:114
Reconciliation sweep: close any usage-probe / review / namer / distill helper tab whose pane is a husk — an idle shell with no agent process running in it. The teardown paths (herdr.stop / start rollback) stop most leaks at the source; this is the durable safety net for husks they can’t reach — agents that crashed, or anything orphaned across a shepherd restart (which clears in-memory review tracking). Returns a ReapResult.
Husk signal = per-pane process liveness (ground truth), not list-absence. Under
herdr 0.7 an exited helper agent leaves its pane alive as an idle zsh, and that pane
STILL appears in agent list (#721) — so the old “absent from agent list ⇒ orphan”
signal never fires. Instead we ask herdr for each helper pane’s foreground processes:
- non-shell proc present (
claude/node/node-MainThread/ …) → live → spare (sparedLive). - process-info throws (transient read failure / quirk) → spare (
sparedError). - empty proc list (undeterminable) → spare fail-closed (
sparedError); we never reap on no evidence. - shell-only (
procs.length > 0 && procs.every(SHELLS.has)) → husk CANDIDATE this sweep.
Two-sweep debounce. herdr’s own PTY is a zsh that runs the agent command, so a
just-spawned agent is briefly shell-only during its pre-exec window. To avoid reaping
that, a husk candidate is only closed when it was also shell-only on the previous sweep
(its tabId was in prevShellOnly). A first-time shell-only sighting is recorded in the
returned shellOnly set (caller threads it back in) but not closed.
panes() throw is fail-closed. If herdr.panes() itself throws it’s a transient
herdr read failure on a supported herdr — we reap nothing this sweep and preserve the
debounce set (return prevShellOnly unchanged) so a candidate isn’t lost mid-debounce.
(A per-pane paneForegroundProcs throw is sparedError, see above.)
Closed tabs are closed in arbitrary order — herdr 0.7 stable ids (#569, e.g. w1:t1)
don’t retarget on close, so close order is irrelevant.
Parameters
Section titled “Parameters”prevShellOnly?
Section titled “prevShellOnly?”Set<string> = ...
Returns
Section titled “Returns”Promise<ReapResult>