Repository navigation
fix(terminal-pane): quitting Claude or Codex in cmd.exe or Git Bash removes it from the running list - #27742
Conversation
…from the running list In shells that send no command-finished mark (cmd.exe, Git Bash), quitting Claude or Codex left the pane's live agent row behind: the pane's process monitor confirmed the exit, but only the OSC 133;D path ever dropped the row. The monitor's confirmed exit now arms the same drop and main-side reconcile pair a confirmed 133;D uses, settled behind the existing host-verifiability gate: a pane whose owner process the host can verify keeps the host's decision; every other pane drops the row and keeps its resume identity. Skipped when a 133;D drop is already armed, for remote panes, and when the row belongs to another agent.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: 🔵 Low · up to A newly started agent could briefly lose its live row until its next status update. This is a bounded, recoverable race; the change remains mergeable with owner awareness. Pre-merge checks |
|
|
Quitting real Claude in cmd.exe previously left a stale sidebar row and Resume in New Native Chat action. Windows high-spec QA with #27520 passes all mandatory rows: running row/action present; Fresh live QA on Windows high spec, with real Claude and the existing login in place. Both PRs were applied together: #27520 Optional real Codex was skipped because it needs a separate wrapper/profile. Real-home settings and |
ELI5
If you quit Claude or Codex inside a Windows cmd.exe terminal (or Git Bash), Orca kept treating the agent as running in that terminal. The sidebar still listed it, and the tab's right-click menu still offered "Resume in New Native Chat". Now, once Orca's own process check confirms the agent's process is gone, the agent drops out of the running list. Its saved session is kept, so you can still resume it later.
What Changed
The problem. Orca keeps one "live agent row" per terminal pane. The sidebar, the tab menu and everything else that asks "is an agent running here?" read that row. There were only two ways a pane's row went away while its shell kept running:
SessionEndhook ends the pane. This only works when the hook carries Claude's process identity, which macOS and Linux capture. The Windows hook (a.cmdfile) carries none, so on native WindowsSessionEndis ignored.The pane already has a process monitor that polls its foreground process. It confirms an agent exited only when no agent is in the foreground, the shell has no child processes, and that has held for more than 1.5 s across polls (a read that can't answer never counts). On that confirmation it reset the tab title and the launch record, but it never touched the live row. So in cmd.exe, after
/exit, the row stayed until the tab was closed. We saw this on Windows with Claude v2.1.296.Before: quit Claude/Codex in a cmd.exe or Git Bash pane, and the sidebar keeps listing it. The tab menu keeps offering "Resume in New Native Chat", the option PR #27520 limits to panes whose agent is still running.
After: within a few seconds after Orca confirms the agent's process is gone, the row is removed and the sidebar stops listing it. The tab menu follows #27520's rule. The resume identity (the session id Orca uses to resume) is kept, exactly as after a normal exit in a zsh pane.
Mechanism. When the pane's process monitor confirms the agent exited, the pane now arms the same pair a confirmed 133;D arms:
preserveResumeIdentity).It then settles that pair behind the existing
hasVerifiableAgentProcessgate. If the execution host can verify the owner process itself (an identified macOS/Linux Claude), the host keeps the decision and nothing changes. Otherwise (native Windows Claude, Codex, other hook agents) the row is dropped and reconciled.Files:
pty-connection/confirmed-process-exit-row-retire.ts(new): the retire step and its skip rules.pty-connection/terminal-keydown-fit.ts: the monitor's confirmed-exit callback calls it next to the existing tracker call. It doesn't depend on the tracker having published its own process read. A pane known only from hooks never gets that read, and the tracker skips it.pty-connection/pane-agent-identity.ts: the existing settle step takes aprocessExitConfirmedoption, so the non-verifiable branch also runs the reconcile. Today that branch only drops, which is right when there is no proof of exit. The reconcile helper is exposed on the session so the new file reuses it.Skipped (unchanged behavior):
Why
The common pattern is that the agent's own lifecycle decides "running", and a confirmed process exit takes the agent out of the running list while its resume data is kept separately. Nothing relies on a shell's command-finished marker for this. Orca already had both pieces: a process monitor that proves the exit, and a drop/reconcile pair that retires a row. They just weren't connected.
Alternatives considered:
SessionEndends the pane on the host. This is the real fix for Claude, but it means capturing the parent process from a.cmdhook. That needs the EDR review in AGENTS.md (no per-hook PowerShell). It also doesn't help Codex or other hook agents, which carry no identity on any platform. It is the follow-up below.The guards from the earlier drop/reconcile changes
The drop/reconcile code came from #23947 and #23948. This change keeps what they guard against:
acceptedStatusSeqcheck, so if the pane reported anything after the exit was armed, the latches are left alone.SessionEndmaps to no status at all. The identity follow-up closes it fully.Other edge cases:
Deviation
SessionEnd. The renderer path is then only the backstop for crashes and killed agents. This needs the EDR review first.Linked Issue
N/A (internal). This unblocks PR #27520's "only while the agent is running" rule for "Resume in New Native Chat" on cmd.exe and Git Bash panes.
Visual Proof
Fresh live QA on Windows high spec, with real Claude and the existing login in place. Both PRs were applied together: #27520
06d746eb1219c2c54e4ef3d4f0b6399f21868d3d, #2774250c5600c91d777dc445ac6720bd21de914b3ea65, combined QA commit34ee6f3321cf18109b131a570d5d250f6f16d1e1. The baseline used the same current-main base,d4a55f583e880b6bbbbca11faa0a45d88646d3a6.Before — same baseline, after
/exit: native Claude had exited, but the sidebar still listed it and the tab menu still offered Resume in New Native Chat.After — both PRs, after
/exit: the sidebar row and menu item disappear. The displayed tab title stays QA27742 exact reply. Claude PID 53412 was first observed absent 1.047 s after the command; the sidebar row was first observed absent at 4.199 s (present at 3.143 s). These are sampling times, not an exact process-exit timestamp.Conversation retained: Agent Session History still lists the same conversation after exit.
PowerShell control: the pane shell was verified as native
powershell.exe. After real Claude exits, the sidebar row and the menu item both disappear.Rows 1, 2, 3 and 5 passed. Optional real Codex row 4 was skipped: the reviewed launcher wraps only Claude, so Codex required a separate wrapper/profile setup. Other platforms and shells were not exercised in this run. Windows were hidden and driven through Chrome DevTools Protocol (CDP); no desktop input or focus changes. SHA-256 checks of the real Claude settings and
.orcatree matched before activation and after teardown; no hooks were installed into the real home. Screenshots are unaltered and include existing startup notices.Testing
New
pty-connection-process-exit-row-retire.test.tsruns the real pane wiring (connectPanePty):paneRemoved(resume identity kept), andreconcileEndedProcessruns.Each skip rule was checked by removing it and seeing its test fail. The existing terminal-pane suites (
pty-connection*,pane-foreground*,agent-completion-coordinator*,pty-connection/*; 102 files, 920 tests) pass.orca-ci-checks: 25 of 26 checks pass, including lint, the changed-code quality gate andpnpm run typecheck. The one failure istypecheck:ci, which fails on this machine because the local Bun is 1.3.14 and CI uses 1.4.3 ("Script not found "check"" for every project). That is local tooling, not this change.Live Windows QA: cmd.exe running/exit/history and the native PowerShell control passed on the combined build; the same-base baseline retained the stale row and menu item. Optional real Codex was skipped. No automated suites or CI checks were rerun by this QA lane.
AI Disclosure
Review
Agent skill upstream boundary
Notes
Ensure no issues in: Security, Cross-platoform support (Linux, Windows, Mac), Remote SSH, Mobile, general backwards compatibility, performance
Checklist
pnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)