Skip to content
cccskills
FreePublished on GitHub

termscope

Drive and inspect terminal applications programmatically. Use for TUI testing, visual regression, debugging rendering issues, and automating interactive CLI tools. Provides snapshot capture, keyboard/text input, text search, and a JSON-lines session protocol.

The English summary is being prepared. Showing the original description.

mwunsch/termscope19 stars(GitHub 19 + cccskills 0)

Run score Not tested

See how to install

Files included (21)

  • SKILL.md5.5 KB
  • .github/workflows/release.yml1.8 KB
  • .gitignore21 B
  • build.zig1.9 KB
  • build.zig.zon444 B
  • CLAUDE.md3.0 KB
  • install.sh2.5 KB
  • LICENSE16.3 KB
  • man/termscope-session.74.1 KB
  • man/termscope.13.9 KB
  • README.md2.9 KB
  • src/config.zig4.4 KB
  • src/input.zig7.4 KB
  • src/main.zig17.1 KB
  • src/pty.zig7.0 KB
  • src/render_html.zig340 B
  • src/render_svg.zig2.6 KB
  • src/session.zig16.0 KB
  • src/snapshot.zig9.8 KB
  • src/terminal.zig16.1 KB
  • src/wait.zig3.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

termscope

Drive and inspect terminal applications — Playwright for the terminal.

Prerequisites

termscope must be installed and on $PATH. Verify:

termscope --version

If not installed:

curl -fsSL https://raw.githubusercontent.com/mwunsch/termscope/main/install.sh | sh

When to use termscope

  • Inspect the visual state of a TUI application
  • Debug rendering issues by capturing terminal snapshots
  • Run visual regression tests in CI
  • Automate interactive terminal applications (fill prompts, navigate menus)
  • Verify that a CLI tool produces expected output with styling

One-shot mode

Snapshot

Capture the terminal state of a command:

# Plain text (default) — best for reading in context
termscope snapshot -- htop

# JSON — structured data for programmatic processing
termscope snapshot --format json -- my-app

# With custom terminal size
termscope snapshot --cols 120 --rows 40 -- btop

# Write to file
termscope snapshot --format svg -o screenshot.svg -- my-tui

Exec (linear sequence)

Chain actions left-to-right:

# Wait for prompt, type, press enter, snapshot
termscope exec \
  --wait-for-text "Search:" \
  --type "hello" \
  --press RET \
  --wait-idle 200 \
  --snapshot \
  -- my-tui

# Assert text is present (exit 0/1 for CI)
termscope exec --expect "Error" -- my-app

Exec flags are processed in order. Each flag is a step.

Session mode (agent driving)

Start a persistent session:

termscope session -- vim test.txt

Send JSON-line requests on stdin, receive JSON-line responses on stdout. Stderr is for diagnostics only — never protocol data.

Protocol

Request format: {"id": N, "method": "name", "params": {...}}

Response format: {"id": N, "result": {...}} or {"id": N, "error": {"code": "...", "message": "..."}}

Methods

snapshot — Capture terminal state

{"id":1,"method":"snapshot"}
{"id":1,"method":"snapshot","params":{"format":"json"}}

type — Send text characters

{"id":2,"method":"type","params":{"text":"hello world"}}

press — Send a key using Emacs notation

{"id":3,"method":"press","params":{"key":"RET"}}
{"id":3,"method":"press","params":{"key":"C-c"}}
{"id":3,"method":"press","params":{"key":"C-x C-s"}}

wait_for_text — Block until text appears

{"id":4,"method":"wait_for_text","params":{"pattern":"Ready","timeout":5000}}

wait_for_idle — Wait for output to settle

{"id":5,"method":"wait_for_idle","params":{"duration":200}}

query — Get terminal metadata

{"id":6,"method":"query"}
// Returns: cols, rows, cursor, cursor_style, cursor_visible, title, alt_screen

resize — Change terminal dimensions

{"id":7,"method":"resize","params":{"cols":120,"rows":40}}

close — End the session

{"id":8,"method":"close"}
// Returns: exit_code

Session lifecycle

  • Session starts when termscope session -- <cmd> launches
  • Session ends when: (a) agent sends close, (b) child exits, or (c) termscope receives SIGTERM
  • If child exits: {"event":"child_exit","exit_code":N} then EOF
  • Errors do NOT end the session — the agent decides what to do

Key notation

Emacs-style key notation:

NotationMeaning
C-cCtrl+C
C-xCtrl+X
M-xAlt+X
C-M-aCtrl+Alt+A
RETEnter
TABTab
ESCEscape
SPCSpace
DELBackspace
<delete>Forward delete
<up> <down> <left> <right>Arrow keys
<home> <end>Home/End
<prior> <next>Page Up/Down
<f1> … <f12>Function keys

Key sequences (space-separated): C-x C-s means Ctrl+X then Ctrl+S.

Output formats

  • text (default) — Numbered lines with header. Best for LLM token efficiency.
  • spans — Text + per-line style runs. For understanding UI structure.
  • json — Structured JSON with metadata and lines array.
  • html — Styled <pre> with <span> elements.
  • svg — Visual screenshot as SVG.

Common patterns

Navigate a list

{"id":1,"method":"wait_for_text","params":{"pattern":"Select:"}}
{"id":2,"method":"press","params":{"key":"<down>"}}
{"id":3,"method":"press","params":{"key":"<down>"}}
{"id":4,"method":"press","params":{"key":"RET"}}

Fill a text field

{"id":1,"method":"wait_for_text","params":{"pattern":"Name:"}}
{"id":2,"method":"type","params":{"text":"John Doe"}}
{"id":3,"method":"press","params":{"key":"TAB"}}

Wait for a prompt then respond

{"id":1,"method":"wait_for_text","params":{"pattern":"Continue? [y/n]"}}
{"id":2,"method":"type","params":{"text":"y"}}
{"id":3,"method":"press","params":{"key":"RET"}}

Check for errors

{"id":1,"method":"snapshot","params":{"format":"json"}}
// Check if any line contains "Error" or "fatal"

Test at multiple sizes

{"id":1,"method":"resize","params":{"cols":80,"rows":24}}
{"id":2,"method":"wait_for_idle","params":{"duration":200}}
{"id":3,"method":"snapshot"}
{"id":4,"method":"resize","params":{"cols":40,"rows":12}}
{"id":5,"method":"wait_for_idle","params":{"duration":200}}
{"id":6,"method":"snapshot"}

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Report a problem with this skill