Terminal testing
Skill ironbee-ai/ironbee-devtools-skills/skills/terminal-testing
Skills for IronBee DevTools MCP/CLI
npx -y skills add ironbee-ai/ironbee-devtools-skills --skill terminal-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Drive and test interactive terminal programs — shells, language REPLs (python/node/psql), full-screen TUIs (vim/htop/less), SSH sessions, and any CLI that prompts — over a pseudo-terminal (PTY). Use to spawn a program attached to a TTY, type commands and keystrokes, wait for expected output before sending more input, read raw scrollback or the rendered screen, send signals, and assert on output. The platform spawns the process itself (no attaching to a pre-existing external process). For one-shot non-interactive commands prefer `pty run`. For web pages use browser-testing; for server APIs use backend-testing.
SKILL.md
6.7 KB, as published. Nobody here has run it
Terminal Testing Skill
Drive interactive terminal programs over a PTY using the Terminal DevTools CLI. Spawn a shell / REPL / TUI attached to a pseudo-terminal, type into it, synchronize on its output, and read what it produced — the way a human (or tmux) would.
When to Use
This skill activates when:
- User wants to test or automate a CLI, REPL, or full-screen TUI
- User needs a program to run on a real TTY (colors, readline, password prompts, ncurses UIs)
- User wants to type commands/keystrokes into an interactive program and assert on its output
- User wants a one-shot command's full output + exit code
- User mentions a PTY, pseudo-terminal, shell session,
expect-style automation, or drivingvim/psql/python
The platform spawns the process itself — it does not attach to a pre-existing external process. For web pages use browser-testing; for server APIs use backend-testing; for Node.js process debugging use the node CLI.
Synchronization model (wait, don't sleep)
There is no assert tool and no fixed-delay step. After sending input, block on expected output with sync wait-for (regex) or sync wait-for-idle (output went quiet) before sending more input or reading. Chain incremental reads by passing the returned cursor as --since to the next content capture / sync wait-for, so you only ever see new output. Guessing with sleeps is unreliable; matching on output is not.
Capabilities
Pane lifecycle
ironbee-terminal-devtools-cli --json pty start # default shell
ironbee-terminal-devtools-cli --json pty start --command python --cols 100 --rows 30
ironbee-terminal-devtools-cli --json pty list
ironbee-terminal-devtools-cli pty resize --pane-id <id> --cols 120 --rows 40
ironbee-terminal-devtools-cli pty stop --pane-id <id>
Send input (tmux key syntax)
ironbee-terminal-devtools-cli interaction send-keys --pane-id <id> --keys '["ls -la","Enter"]'
ironbee-terminal-devtools-cli interaction send-keys --pane-id <id> --keys '["C-c"]'
ironbee-terminal-devtools-cli interaction send-text --pane-id <id> --text "SELECT 1;"
Synchronize on output
ironbee-terminal-devtools-cli --json sync wait-for --pane-id <id> --pattern '\$ $'
ironbee-terminal-devtools-cli --json sync wait-for --pane-id <id> --pattern 'Server listening' --since 1024
ironbee-terminal-devtools-cli --json sync wait-for-idle --pane-id <id>
Read output
ironbee-terminal-devtools-cli --json content capture --pane-id <id> --since 4096 --strip-ansi
ironbee-terminal-devtools-cli --json content capture --pane-id <id> --mode screen # rendered grid for TUIs
ironbee-terminal-devtools-cli --json content get-cursor --pane-id <id>
Signals and one-shots
ironbee-terminal-devtools-cli pty signal --pane-id <id> --signal SIGINT
ironbee-terminal-devtools-cli --json pty run --command "npm test"
Basic Testing Workflow
- Spawn:
pty start(a shell, or--commanda specific program); keep thepaneId. - Wait for ready:
sync wait-foron the prompt / banner before sending input. - Send:
interaction send-keys(type a command +Enter) orinteraction send-text. - Wait:
sync wait-foron the next prompt (orsync wait-for-idlewhen there is no clean marker). - Read:
content capturewith--since <cursor>for only the new output (--mode screenfor TUIs). - Verify: judge the captured output yourself; repeat from step 3.
- Stop:
pty stopthe pane.
End-to-End: drive a psql session
SESSION="--session-id psql"
PANE=$(ironbee-terminal-devtools-cli $SESSION --json pty start --command psql --args '["-U","app","appdb"]' | jq -r '.paneId')
# Wait for the psql prompt, run a query, wait for the next prompt, read the result
ironbee-terminal-devtools-cli $SESSION --json sync wait-for --pane-id "$PANE" --pattern 'appdb=#'
ironbee-terminal-devtools-cli $SESSION interaction send-keys --pane-id "$PANE" --keys '["SELECT count(*) FROM users;","Enter"]'
CUR=$(ironbee-terminal-devtools-cli $SESSION --json sync wait-for --pane-id "$PANE" --pattern 'appdb=#' | jq -r '.cursor')
ironbee-terminal-devtools-cli $SESSION --json content capture --pane-id "$PANE" --strip-ansi
ironbee-terminal-devtools-cli $SESSION interaction send-keys --pane-id "$PANE" --keys '["\\q","Enter"]'
ironbee-terminal-devtools-cli $SESSION pty stop --pane-id "$PANE"
End-to-End: assert a TUI renders correctly
SESSION="--session-id tui"
PANE=$(ironbee-terminal-devtools-cli $SESSION --json pty start --command htop --cols 120 --rows 40 | jq -r '.paneId')
# Let it paint, then read the rendered grid (not the raw stream)
ironbee-terminal-devtools-cli $SESSION --json sync wait-for-idle --pane-id "$PANE"
ironbee-terminal-devtools-cli $SESSION --json content capture --pane-id "$PANE" --mode screen
# Quit
ironbee-terminal-devtools-cli $SESSION interaction send-keys --pane-id "$PANE" --keys '["q"]'
ironbee-terminal-devtools-cli $SESSION pty stop --pane-id "$PANE"
Best Practices
- Use sessions (
--session-id) for multi-step flows — panes are pinned to the session. - Always
sync wait-forbefore sending more input — never guess with delays. - Chain
--since <cursor>across captures/waits so you only read new output. screenmode for TUIs,streammode for shells/REPLs — pick the capture mode to match the program.C-ckeystroke vspty signal—send-keys ["C-c"]may be trapped by the program;pty signal --signal SIGINTdelivers a real process signal.pty runfor non-interactive commands — one call returns full output + exit code; no pane lifecycle to manage.- Stop panes you no longer need — long-idle panes may be reaped by the daemon.
- Batch tight flows with
run execute --code "..."andcallTool()to cut round-trips (onlycallToolis available — nopage).