Every connection is an ordered sequence of frames:
| Offset | Size | Meaning |
|---|---|---|
| 0 | 1 | kind: 0 control, 1 stdin, 2 stdout |
| 1 | 4 | unsigned big-endian payload length |
| 5 | length | payload (maximum 16 MiB) |
Control payloads are UTF-8 JSON. Stdin/stdout payloads are PTY bytes and must not be interpreted by the transport. Clients send control and stdin; servers send control and stdout.
Requests use { "id": 1, "method": "list", "params": {} }. Responses use
either { "id": 1, "ok": true, "result": ... } or { "id": 1, "ok": false, "error": { "code": "...", "message": "..." } }. Asynchronous control
messages have an event field and no ID.
hello { version }: reports server and protocol version.create { command?, args?, cwd?, env?, cols?, rows?, name? }: creates a PTY session and returns its metadata. The default command is$SHELL.list {}: returns all live and exited session metadata.attach { sessionId }: selects the connection's session. Many connections may attach to one session. The server first sends an ANSI snapshot of the current terminal screen, then streams subsequent raw output.detach {}: removes the connection from its current session without ending it.resize { cols, rows }: changes the attached PTY size. Size is shared session state, so the most recent attached client request wins.kill { sessionId?, signal? }: signals a session.sessionIdmay be omitted when attached.
After attach the server emits attached, snapshot start/end events around
the stdout snapshot, then the attach response. Output produced while the
snapshot is generated is queued and delivered immediately after it. After
detach it emits detached.
When the child exits it emits exit with sessionId, exitCode, and signal.
The server keeps a raw transcript for logging but never replays it through the attach API. A headless terminal model separately maintains the current screen, alternate screen, modes, cursor, and bounded scrollback; attach serializes only the current screen as ANSI. Persistence across server restarts, transcript limits, access control, TLS, WebSocket, and SSH are separate policies.