2 unstable releases

Uses new Rust 2024

new 0.2.0 Mar 10, 2026
0.1.0 Mar 9, 2026

#742 in Network programming

MIT license

60KB
2K SLoC

t4a - terminals for agents

USAGE t4a [args...] T4A_SOCKET=/tmp/t4a.sock (default) Daemon auto-starts on first command.

COMMANDS create [-- cmd...] Create terminal (80x24, $SHELL) send 'input\n' Send keystrokes. Use single quotes! t4a parses: \n \t \x03 \e \x7f send < file Reads stdin if no string arg events [id] Stream events as NDJSON, never exits. Omit id to stream all terminals.

screenshot Low-res PNG to stdout (~250 tokens) screenshot -o PNG to file text All viewport lines (~400 tokens) text 0:5 Last 5 lines (indexed from bottom)

Screenshots are intentionally low-res to minimize tokens. Use screenshot to glance at overall state. Use text to read exact lines.

attach Raw PTY byte stream. Interactive. list List terminals as NDJSON kill Kill terminal (SIGHUP) cursor {row, col, visible} resize Resize terminal

EVENTS command_done Shell finished a command. {"code": 0} idle No output for 2s. {"after_ms": 2001} activity Output resumed after idle. exit Shell process exited. {"code": 0} bell BEL character received. title Window title changed. {"title": "vim"}

Typical sequence after sending a command: activity -> command_done -> idle

command_done uses shell integration (bash/zsh). It fires for every command, including builtins like cd. Does not fire inside programs like vim or python — use idle for those.

EXAMPLE $ t4a create {"ok":true,"id":"t1","cols":80,"rows":24,"pid":1234,"socket":"/tmp/t4a.sock"}

$ t4a send t1 'cargo build\n' $ t4a events t1 | head -3 {"event":"activity","terminal":"t1"} {"event":"command_done","terminal":"t1","code":0} {"event":"idle","terminal":"t1","after_ms":2001}

$ t4a text t1 0:3 error[E0308]: mismatched types --> src/main.rs:42:5

$ t4a screenshot t1 -o s.png $ t4a send t1 '\x03' # ctrl+c $ t4a kill t1

Long-running commands (e.g. cargo build) can run for minutes. Instead of polluting the context window with "Compiling x" lines, kick it off and wait for the command_done event.

NOTES IDs: t1, t2, ... assigned sequentially. Screenshots: indexed-color PNG, ~2-10KB. events never exits — pipe through head, grep -m1, etc.

Dependencies

~18MB
~335K SLoC