{"skill":{"slug":"headless-terminal","displayName":"headless-terminal","summary":"Drive hostile or full-screen terminal UIs through the `ht` CLI from montanaflynn/headless-terminal. Use when an agent needs reliable PTY-backed interaction,...","description":"---\nname: headless-terminal\ndescription: Drive hostile or full-screen terminal UIs through the `ht` CLI from montanaflynn/headless-terminal. Use when an agent needs reliable PTY-backed interaction, screen snapshots, or wait/synchronization for tools like `vim`, `top`, `htop`, `git add -p`, SSH-driven TUIs, installers, auth prompts, or REPLs. Prefer this over plain shell I/O when redraw behavior, alternate screen handling, cursor state, or deterministic waits matter; fall back to exec/process or tmux for ordinary shell commands and human-operated sessions.\n---\n\n# Headless Terminal\n\n## Overview\n\nUse `ht` from <https://github.com/montanaflynn/headless-terminal> as the special-purpose tool for terminal programs that behave badly under plain stdin/stdout control. It gives a real PTY, terminal-state snapshots, and explicit wait conditions so the agent can drive a TUI without guessing when the screen settled.\n\nDo not let the hammer make everything look like a nail. `ht` is powerful but heavyweight; if a normal command, pipe, `exec` with `pty=true`, or tmux session fits better, use that instead.\n\n## Workflow\n\n1. Confirm `ht` exists before committing to this path.\n2. Decide whether the task actually needs `ht`; explicitly reject hammer/nail overuse and try simpler shell or host-agent primitives first when they fit.\n3. Create a uniquely named session with `ht run`.\n4. Send the smallest meaningful keystrokes.\n5. Wait for a deterministic condition.\n6. Snapshot with `ht view`.\n7. Stop and remove the session when done, unless the user explicitly wants a persistent session.\n\n## Choose `ht` vs other tools\n\nUse `ht` when:\n- a program needs a real tty and redraws the whole screen\n- alternate-screen behavior matters\n- cursor position or screen state matters\n- the task needs reliable waits after keys are sent\n- you want a text or PNG snapshot of the terminal state\n\nPrefer `exec` / `process` when:\n- the command is ordinary shell I/O\n- output is line-oriented and does not depend on screen state\n- no full-screen TUI is involved\n- `exec` with `pty=true` is enough to satisfy a TTY check without needing screen snapshots\n\nPrefer tmux when:\n- a human will monitor or resume the session directly\n- persistence and shared human visibility matter more than terminal snapshots\n\n## Preflight\n\nCheck availability first:\n\n```bash\ncommand -v ht\n```\n\nIf `ht` is missing, say so plainly and switch to another tool or ask whether to install it. The expected install source is Montana Flynn's headless-terminal:\n\n```bash\nbrew install montanaflynn/tap/ht\n```\n\nWithout Homebrew, use a release tarball from <https://github.com/montanaflynn/headless-terminal/releases> that matches the host OS/architecture, then put the `ht` binary on `PATH`.\n\nSecurity/trust posture for publishing:\n- Tap installs and release tarballs are still trust decisions; name the repo/owner explicitly.\n- Prefer the tap or release artifacts over random packages or copy-pasted scripts.\n- If a user is security-sensitive, suggest reviewing the GitHub repo and release page before installation.\nImportant disambiguation: not every package named `ht` or `headless-terminal` is this CLI. On macOS/Homebrew, the core formula `ht` refers to HTE, a viewer/editor/analyzer for executables, not this terminal automation tool. The public npm package `headless-terminal` is an old library and may not provide the expected `ht run` / `ht send` CLI. Do not install either as a guess; verify that the candidate explicitly supports the commands this skill uses.\n\n## Core commands\n\n```bash\nht run --name demo-$(date +%s) <cmd...>\nht send demo \"keys...\" --wait-idle 200ms --view\nht view demo\nht view demo --format png > screenshot.png\nht wait demo --wait-text \"READY\"\nht stop demo\nht remove demo\n```\n\nTreat command names and flags as version-sensitive. If `ht --help` is available, check it before relying on less-common flags such as PNG output or cursor waits.\n\n## Waiting strategy\n\nThis is the main reason to use `ht`.\n\nPrefer, in order:\n1. `--wait-text` when a known string should appear\n2. `--wait-cursor` when the cursor position is predictable\n3. `--wait-idle` when the app redraws and then settles\n4. `--wait-duration` only when nothing better exists\n\nDo not rely on blind sleeps when a real wait condition is available.\n\n## Practical patterns\n\n### Drive vim safely\n\n```bash\nht run --name notes vim /tmp/notes.md\nht send notes \"ihello<Esc>\" --wait-idle 200ms --view\nht send notes \":wq<CR>\" --wait-exit\nht remove notes\n```\n\n### Drive a remote TUI over SSH\n\n```bash\nht run --name remote ssh user@host.example\nht send remote \"top<CR>\" --wait-idle 500ms --view\nht send remote \"q\" --wait-idle 200ms\nht send remote \"exit<CR>\" --wait-exit\nht remove remote\n```\n\n### Inspect `git add -p`\n\n```bash\nht run --name addp git add -p\nht view addp\n```\n\nThen send one choice at a time and wait after each response.\n\n## Operating guidance\n\n- Use unique named sessions so follow-up commands stay readable and do not collide with older runs.\n- Send the minimum keystrokes needed; avoid giant pasted blobs.\n- After any state-changing input, capture a fresh view before assuming success.\n- If the screen looks wrong, inspect with `ht view` before sending more keys.\n- Clean up exited sessions with `ht remove`.\n- Ask before using `ht` for privacy-sensitive auth flows, remote systems, or destructive TUI operations. A real PTY can make it easy to do real damage quickly.\n\n## Failure modes\n\n- If the program exits immediately, check the command, working directory, and whether the program refuses non-interactive/unknown terminals.\n- If waits time out, use a different wait condition instead of stacking longer sleeps.\n- If the captured screen is stale or blank, check whether the app uses an alternate screen, requires a larger terminal size, or has already exited.\n- If a task is simple enough for plain shell control, stop using `ht` and simplify.\n- If the session is for a human to keep around, tmux is usually the better container.\n\n## References\n\n- `references/examples.md`: quick fit checks, sample command patterns, and wait-strategy examples\n- `references/keys.md`: vim-style key notation such as `<CR>`, `<Esc>`, arrows, control/meta keys, and raw bytes\n- `references/waits.md`: wait strategy decision tree and timeout guidance\n- `references/recipes.md`: recipes for vim, REPLs, installers, watch, terminal sizing, screenshots, and recording\n- `references/troubleshooting.md`: exit codes, stale views, wait timeouts, zombies, daemon issues, and `ht debug`\n","topics":["Git"],"tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":354,"installsAllTime":13,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1777925517990,"updatedAt":1778492846193},"latestVersion":{"version":"1.0.0","createdAt":1777925517990,"changelog":"Initial public release. Adds ht guidance, wait/sync strategy, install-source trust notes, and anti-overuse guardrails.","license":"MIT-0"},"metadata":null,"owner":{"handle":"inertia186","userId":"s17fj5zp0f74hydhsqe0bq9ayh83g45c","displayName":"Anthony Martin","image":"https://avatars.githubusercontent.com/u/494368?v=4"},"moderation":null}