3.2 KiB
Example: TUI / interactive terminal app
Interactive terminal apps (text editors, REPLs, curses-based UIs) can't
be driven directly by an agent's bash tool — they take over the terminal.
The skill must show how to wrap them in tmux so the agent can send
input, capture output, and take screenshots.
The tmux pattern
This is the standard approach:
- Start the TUI inside a detached tmux session
- Send keystrokes with
tmux send-keys - Read screen contents with
tmux capture-pane - Clean up with
tmux kill-session
The skill's SKILL.md should present this as the primary way to drive
the app. A small driver.sh that wraps the launch+attach sequence can
live in the skill directory, but for most TUIs the raw tmux commands in
the skill body are enough.
Example snippet
Run (interactive, for agents)
Start the TUI inside tmux:
tmux new-session -d -s app -x 120 -y 40 './myapp'Poll until the ready marker appears (faster + more reliable than a fixed sleep — returns the instant the app is up, fails loudly if it isn't):
timeout 10 bash -c 'until tmux capture-pane -t app -p | grep -q "Ready"; do sleep 0.2; done' tmux capture-pane -t app -pSend input (this example navigates to the Settings screen and toggles an option):
tmux send-keys -t app 's' timeout 5 bash -c 'until tmux capture-pane -t app -p | grep -q "Settings"; do sleep 0.2; done' tmux send-keys -t app 'Down' 'Down' 'Space' # navigate + toggle timeout 5 bash -c 'until tmux capture-pane -t app -p | grep -qF "[x]"; do sleep 0.2; done' tmux capture-pane -t app -pIf you find yourself writing more than a couple of these poll lines, pull them into a
wait_for()helper in adriver.shnext to the skill.Quit:
tmux send-keys -t app 'q' tmux kill-session -t app 2>/dev/null || trueKey reference
Key Action j/korDown/UpNavigate list EnterSelect sSettings qQuit
Details worth documenting
- Terminal size. Some TUIs break or hide content at small widths.
Specify a known-good size in the
tmux new-session -x -yargs. - Startup time. Poll for a ready marker (
until tmux capture-pane | grep -q X) rather than a fixedsleep N— returns the instant the app is up, and fails usefully when it never does. Say what string means ready. - Keybinding reference. A table of the main keys. This is the "API" of a TUI — an agent needs it to drive the app.
- Exit cleanly. Show the quit keystroke and
tmux kill-sessionas a fallback. - Color/unicode quirks. If
capture-paneoutput is hard to read, note flags that help (-efor escape sequences,-Jto join wrapped lines).
Also document the direct invocation
For a human running the app interactively, tmux is overkill. Include the one-liner too:
Run (direct, for humans)
./myappPress
qto quit.