Expand description
Shell drawer HTTP handlers and the agent shell lock. Split out of server/mod.rs unchanged (SPEC_LARGE_FILE_MODULE_ANALYSIS_2026_09_30.md §4.1).
Constants§
- AGENT_
LOCK_ 🔒WINDOW_ MS - META_
KEY_ 🔒AGENT_ LOCK_ UNTIL - META_
KEY_ 🔒PTYSHELL_ BOOT_ ID - Block meta on a
PtyShellblock: the srv boot id of the run that created it.
Functions§
- broadcast_
meta_ 🔒update - Merge
meta_updateintoblock_id’s meta and broadcast awaveobj:updateWS event so every subscribed frontend (the drawer, if open) picks it up immediately — the same two steps thesetmetaWS handler performs (websocket.rs’sCOMMAND_SET_METAhandler), factored out sinceptyshell/*needs the identical pattern from a plain HTTP handler with noWshRpcEnginein scope. - clear_
shell_ 🔒pointer_ if - Clear the agent block’s shell pointer, if it still names
id(see the exited-shell branch oftry_attach_to_existing_shellfor why it is compare-before-clear), so the next create claims a fresh shell. - connection_
conflict 🔒 - 409 when the pane’s running shell is on another connection than
wanted. PtyShellStop releases the keyboard lock and leaves the shell running, so ending the shell is the way to switch. - handle_
shell_ 🔒create POST /api/v1/shell/create— start a persistent background shell.- handle_
shell_ 🔒input POST /api/v1/shell/input— write text to a running shell’s stdin (Phase 3b).- handle_
shell_ 🔒status POST /api/v1/shell/status— query a shell’s running state (Phase 3b).- handle_
shell_ 🔒stop POST /api/v1/shell/stop— stop a running persistent shell.- is_
owned_ 🔒by_ agent - Whether
shell_idis a realview:"term"sub-block PARENTED TOagent_block_id— the actual safety property Codex asked for (PR #3177):shell_idlives in the same block-id namespace as every other pane, andLayoutexposes block ids for ordinary panes, so without this check an agent could pointPtyShellInput/PtyShellStop/etc. at any controller-backed block (another agent’s own CLI pane, a human’s terminal pane) and inject input into it or tear it down. Framed as parentage rather than “didPtyShellcreate it” (the original, narrower check) specifically so it also covers the reuse case above: a shell the HUMAN created via the drawer is just as legitimate a target as onePtyShellcreated itself, as long as it’s this agent’s own pane. - try_
attach_ 🔒to_ existing_ shell - Shared by both the top-level reuse check and the “lost the atomic
claim” fallback in
handle_pty_shell_create: resyncid’s controller and reply, or returnNoneifiddoesn’t resolve to a real block (stale pointer), OR if its shell has already exited, so the caller falls through to creating a fresh one. A pane has one agent shell: asking for it, while it runs, on another connection than its own is refused (409), not answered with the shell on the wrong machine. An exited one is replaced whatever its connection was.