Primary guide

Agent-compatible terminal API

traa.sh is built for automation agents and scripts: query terminal state as JSON, send input, wait for shell idle (OSC 133), and subscribe to events — all over the existing mux socket, with no GUI.

Why traa.sh for agents

Structured state, not ANSI soup

Query

Pane text (UTF-8 + scrollback), cwd, title, cursor, and a busy flag — one JSON response via traash agent state.

Act & wait

Send keystrokes with agent send, then block on agent wait until the shell emits OSC 133;D — no polling the screen grid.

Subscribe

JSONL events for command finished, cwd/title changes, layout updates, and optional raw PTY output.

Secure attach

Encrypted sessions support read-only agents (observe only) vs write agents (send + wait). Same mux socket as the GUI.

01 — Bootstrap

Start the mux host

traash --server --create dev
traash agent state dev          # JSON on stdout

Socket: $XDG_RUNTIME_DIR/traash/mux.sock. Optional TCP: traash --server --bind 127.0.0.1:9477.

02 — Shell integration

OSC 133 + OSC 7

Panes set TRAASH_SHELL_INTEGRATION=1 for child shells. Source the snippet once in your shell rc:

eval "$(traash shell-init bash)"   # or zsh / fish

Snippets are installed under share/traash/shell/. Without shell integration, traash agent wait cannot detect command completion.

03 — CLI

traash agent

SubcommandDescriptionExit
state SESSIONGET_STATE → print STATE JSON0 ok, 1 error
send SESSION --pane N --literal BYTESWrite to pane PTY0 ok, 3 denied
wait SESSION --pane N [--timeout MS]Wait for OSC 133;D0 idle, 2 timeout, 3 denied
subscribe SESSION [--emit-output]JSONL EVENT stream until Ctrl-C0
run-action SESSION -- ACTIONMux action (split-h, new-window, …)0 ok, 3 denied

Shared flags: --read-only, --password-fd, --host, --port.

04 — Wire protocol

JSON message types

Same length-prefixed frame envelope as the GUI mux protocol. Payloads are UTF-8 JSON unless noted.

TypeNamePayload
16GET_STATE{"v":1,"scrollback":200,"pane_id":0}
17STATEsession + panes (text, cwd, cursor, busy)
18WAIT_IDLE{"pane_id":1,"timeout_ms":30000} (write role)
19IDLE{"pane_id":1}
20WAIT_TIMEOUT{"pane_id":1}
21SUBSCRIBE{"emit_output":false}
22UNSUBSCRIBEempty
23EVENTJSON event (see below)

Read-only clients may use GET_STATE and SUBSCRIBE. INPUT, WAIT_IDLE, and mutating actions return ACTION_DENIED (type 8).

05 — Events

SUBSCRIBE stream

06 — Example

Wait loop (bash)

traash agent send dev --pane 1 --literal $'ls -la\n'
traash agent wait dev --pane 1 --timeout 10000
traash agent state dev | jq '.panes[0].text'

07 — Security

Roles and transport

Encrypted sessions use the same dual-password model as GUI attach. TCP has no TLS in v1 — use Unix socket or a trusted LAN. Passwords belong in tty or --password-fd, never argv.