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
| Subcommand | Description | Exit |
|---|---|---|
state SESSION | GET_STATE → print STATE JSON | 0 ok, 1 error |
send SESSION --pane N --literal BYTES | Write to pane PTY | 0 ok, 3 denied |
wait SESSION --pane N [--timeout MS] | Wait for OSC 133;D | 0 idle, 2 timeout, 3 denied |
subscribe SESSION [--emit-output] | JSONL EVENT stream until Ctrl-C | 0 |
run-action SESSION -- ACTION | Mux 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.
| Type | Name | Payload |
|---|---|---|
| 16 | GET_STATE | {"v":1,"scrollback":200,"pane_id":0} |
| 17 | STATE | session + panes (text, cwd, cursor, busy) |
| 18 | WAIT_IDLE | {"pane_id":1,"timeout_ms":30000} (write role) |
| 19 | IDLE | {"pane_id":1} |
| 20 | WAIT_TIMEOUT | {"pane_id":1} |
| 21 | SUBSCRIBE | {"emit_output":false} |
| 22 | UNSUBSCRIBE | empty |
| 23 | EVENT | JSON 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
command_finished— OSC 133;Dcwd_changed— OSC 7title_changed— OSC 0/2layout_changed— after mux layout mutationpane_output— raw PTY (base64), rate-limited 50 KB/s/pane whenemit_output: true
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.