Skip to content
Install

docs/tui-rest.md

TUI control REST (B84)

Control a running terminal over the adapter with a full token.

The existing HTTP adapter stays off by default and binds loopback only. Every /tui route requires a full remote token; read-only tokens and browser Origin requests are denied. Start a terminal with --tui-control to opt it into control of its project. Without an owner, UI requests return 409. No TUI command is classified read-only: prompts and control requests may contain private content.

RoutePayload / behavior
POST /tui/append-prompt{text} inserts into the prompt, moves to its end, saves the draft
POST /tui/open-helpOpens Help
POST /tui/open-sessionsOpens the session picker
POST /tui/open-themesOpens Themes; arrows/search preview, Esc restores, Enter persists
POST /tui/open-modelsOpens the model search picker
POST /tui/submit-promptSubmits through the normal prompt path
POST /tui/clear-promptClears prompt, attachments and shell mode
POST /tui/execute-command{command} invokes a registered built-in action
POST /tui/show-toast{title?, message, variant, duration?}; variant info/success/warning/error, duration defaults to 5000 ms
POST /tui/publish{type, properties} for tui.prompt.append, tui.command.execute, tui.toast.show, tui.session.select
POST /tui/select-session{sessionID}; unknown session 404, different project 403
GET /tui/control/nextClaims a polling owner; returns {requestID, path, body}, or 204 after 25 seconds
POST /tui/control/response{requestID, response: boolean}, or legacy boolean for the sole outstanding request

UI actions return true when processed, false when declined by the terminal (unknown command, another focused editor, failed selection). Provider results still arrive through the ordinary session protocol. Opening pickers preserves the draft. Themes use the shared bordered grid and header hints, with one column below 70 columns. The v1 open-themes misroute to session.list is corrected.

The v1 underscore command aliases are accepted: session_new, session_share, session_interrupt, session_compact, messages_page_up/down, messages_line_up/down, messages_half_page_up/down, messages_first/last, agent_cycle. Published dotted IDs include help.show, theme.list, model.list, session.list/new/share/interrupt/compact/page.up/page.down/line.up/line.down/half.page.up/half.page.down/first/last, prompt.clear/submit, agent.cycle. Native key-action IDs are also supported; unknown IDs return false. Existing provider/sharing configuration and approval rules apply to actions requiring them.

The daemon allows one owner per canonical project, at most 128 owners and 32 outstanding requests per project. It delivers requests serially and waits at most 15 seconds for each result. There is no global broadcast, durable queue or automatic resend of UI actions after disconnect. A persistent terminal owns by connection, never by a caller-supplied client ID. Polling clients own by authenticated token, with a 30-second lease; use a dedicated token and one polling loop. Only that owner can answer its current request. Revocation, cancellation, disconnect and daemon stop release waiters. An action already delivered may finish after its caller cancels; cancellation does not undo it. Native command IDs keep the existing replay-cache guarantees. Legacy bare responses are ordered; use requestID for reliable correlation and never retry an uncorrelated response as a new request.

Native clients use registerTuiControl, sendTuiControl, nextTuiControl, respondTuiControl or the additive tui.control.* commands. Targeted tui.control.request frames are ephemeral and never enter session/global logs. HTTP uses the same broker and protocol validation. No new dependency, provider or external service is introduced.

bun scripts/render-frames.ts .agents-frames/B84 --b84 100x30 180x50