feat(booterm): structured pty_exited WS notifications. Plan-validated, impl-validated, code-reviewed green (contracts build clean, contracts test 29/29, booterm + web typecheck clean). wip: in-progress inference/provider refactor (agents.ts, provider.ts, new llama-providers.ts, removed llama-args-validator), plus arena, dispatcher, compaction, schema changes. openspec: pty-exit-notifications complete; x-agent-flags planned (not yet implemented).
3.4 KiB
3.4 KiB
ADDED Requirements
Requirement: Structured pty_exited frame on WS protocol
The system MUST send a structured exit notification when a PTY process exits.
- WHEN a process running in a booterm terminal pane exits (via
handle.onExit) - THEN booterm MUST send a structured
pty_exitedJSON text frame on the WS connection containing:type,exit_code,last_lines(array of recent output lines from the ring buffer),session_id,session_title,session_description,parent_agent,timed_out(boolean)
Scenario: Normal process exit with metadata
- WHEN a user's SSH shell process exits with code 0 after producing output
- AND the terminal pane was registered with title "build", description "run tests", parentAgent "claude"
- THEN the
pty_exitedframe MUST containexit_code: 0, at least onelast_linesentry,session_title: "build",session_description: "run tests",parent_agent: "claude", andtimed_out: false
Scenario: Process exit with no output
- WHEN a process exits immediately without producing output
- THEN the
pty_exitedframe MUST contain an emptylast_linesarray and valid session metadata
Scenario: Timeout-triggered exit
- WHEN a process is killed by the idle timeout sweep (requires sweepExpired to be wired to an interval, which is a separate change)
- THEN the
pty_exitedframe MUST containtimed_out: trueand the exit code from the tmux kill
Requirement: pty_exited frame type in WsFrame contract
The system MUST register pty_exited as a valid frame type in the cross-app wire contract.
- WHEN the
pty_exitedframe schema is added toWsFrameSchemainpackages/contracts/src/ws-frames.ts - THEN it MUST be included in
KNOWN_FRAME_TYPESand validate against the discriminated union
Scenario: Frame validates against schema
- WHEN a
pty_exitedframe with all required fields is parsed - THEN the Zod validation MUST pass and the frame MUST NOT be dropped
Scenario: Frame missing required fields
- WHEN a
pty_exitedframe is missing theexit_codefield - THEN the Zod validation MUST fail and the frame MUST be dropped with a log warning
Requirement: Client parse of pty_exited frame
The web frontend MUST recognize and parse pty_exited frames from the booterm WS.
- WHEN the web frontend receives a
pty_exitedframe over the terminal WS - THEN
parseServerFrameMUST recognize it and return a structured object withsession_id,pane_id,exit_code,last_lines, and session metadata
Scenario: Client receives pty_exited
- WHEN the browser receives a
pty_exitedframe - THEN the terminal MUST display a styled exit notification with the exit code and last output line(s)
Scenario: Client receives pty_exited with timeout
- WHEN the browser receives a
pty_exitedframe withtimed_out: true - THEN the terminal MUST display a timeout-specific notification message
Requirement: Backward compatibility with bare exit frame
The client MUST NOT break when receiving the legacy bare exit frame.
- WHEN a booterm instance sends the old
{type: 'exit', code: N}frame (pre-upgrade) - THEN the client MUST gracefully handle it as before (display exit message, no crash)
Scenario: Legacy exit frame received
- WHEN the client receives
{type: 'exit', code: 1} - THEN the terminal MUST display the exit code message without throwing