Agent Skillsanomalyco/terminal-control › terminal-control

terminal-control

GitHub

使用termctrl工具在真实终端中驱动和验证TUI、REPL等交互式应用,支持屏幕读取、键盘输入、会话管理及证据录制,用于自动化测试或操作CLI进程。

skills/terminal-control/SKILL.md anomalyco/terminal-control

Trigger Scenarios

需要自动化测试终端应用界面时 需要程序化控制交互式CLI或TUI流程时

Install

npx skills add anomalyco/terminal-control --skill terminal-control -g -y
More Options

Use without installing

npx skills use anomalyco/terminal-control@terminal-control

指定 Agent (Claude Code)

npx skills add anomalyco/terminal-control --skill terminal-control -a claude-code -g -y

安装 repo 全部 skill

npx skills add anomalyco/terminal-control --all -g -y

预览 repo 内 skill

npx skills add anomalyco/terminal-control --list

SKILL.md

Frontmatter
{
    "name": "terminal-control",
    "description": "Drive and verify terminal applications with the termctrl CLI in a real PTY - read visible screens, run named live sessions, send typed keyboard input, wait for text, save evidence, record timelines, and export edited videos. Use when an agent must operate or test a TUI, REPL, interactive CLI, shell process, or OpenTUI application."
}

Terminal Control

Use termctrl to observe the actual visible terminal state and drive interaction deterministically.

Start With The Smallest Workflow

Read a disposable terminal application's settled visible screen when no further interaction is required:

termctrl show -- my-terminal-app

Keep an application alive when interaction or repeated inspection is required:

termctrl start app -- my-terminal-app
termctrl wait app "Ready"
termctrl show app
termctrl send app text:help enter
termctrl wait app "Commands"
termctrl show app
termctrl stop app

Always stop named sessions after use unless the user explicitly wants the live process retained.

Enter a visible workspace that humans and agents control together:

termctrl run
termctrl run -- /usr/bin/nvim
termctrl run editor -- nvim
termctrl run workspace --tab-position top
termctrl run editor
termctrl attach editor
termctrl windows workspace --json
termctrl current --json
termctrl tab-position workspace top
termctrl move-window workspace editor --index 0
termctrl new-window workspace editor -- nvim
termctrl show workspace --window editor
termctrl panes workspace --json
termctrl layout workspace --grid 2x2
termctrl layout workspace --grid 2x2 -- nvim
termctrl send workspace --pane 1 text:opencode2 enter
termctrl focus workspace --pane 1
termctrl close-pane workspace --pane 1
termctrl resize-pane workspace --pane 1 --direction left --cells 5
termctrl zoom-pane workspace --pane 1

With no arguments, run starts $SHELL in the workspace/main window. The persistent tab strip shows selection, pane count, zoom, and output (+), bell (!), or surviving-window pane exit (x) activity. Use tab-position NAME top|bottom to move it live. Use ctrl-b p for the command palette, ctrl-b c/w to create/list windows, ctrl-b l for the last window, ctrl-b n for next, ctrl-b </> or tab dragging to reorder, and ctrl-b t to move tabs. Use ctrl-b % and ctrl-b " to split; use ctrl-b plus arrows or h/j/k, or a mouse click, to focus. Use ctrl-b H/J/K/L to resize, ctrl-b z to toggle zoom, ctrl-b d to detach, ctrl-b q to show stable pane IDs, and ctrl-b ? for help. ctrl-b x closes a pane, ctrl-b & closes the current window, and ctrl-b Q closes the workspace after y confirmation.

run NAME creates when absent and reattaches when the workspace already exists. attach NAME requires an existing workspace. Closing the terminal detaches without killing panes; ctrl-b Q followed by y, or termctrl stop NAME, ends the workspace. Only one human terminal may be attached, while agent controls remain available when detached.

Discover windows before panes. Window names are exact stable selectors; numeric indexes shift after reorder or close. Pane IDs are globally stable across windows; do not infer identity from geometry or titles. Inside a pane, use termctrl current --json; TERMCTRL_WORKSPACE and TERMCTRL_PANE_ID identify the caller while the daemon resolves its current window after moves or renames. Window-targeted show, send, wait, logs, panes, and layout do not change human selection. Only select-window and focus --pane ID intentionally move the visible human context.

Workspaces follow their current human terminal and reject termctrl resize. run --record records the composed workspace, including tabs, splits, window switches, resizes, and markers. Composed ANSI output is a rendered snapshot; pane-targeted ANSI is the original pane stream.

Choose The Correct Observation

  • Use show for current visible screen text. Prefer it for reasoning about full-screen TUIs.
  • Use logs for readable retained output from normal-screen tools and log-like commands.
  • Use save --format ... --out ... only when a persisted artifact is required.
  • Use video only after explicitly recording a timeline with --record.

Do not treat logs as the visible state of an alternate-screen TUI.

Named-session screen reads are immediate by default. Do not pass --settle-ms 0 or --deadline-ms 0; omit both options. Set them only to intentional nonzero values when a specific transition needs quiet-output settling.

wait defaults to a five-second maximum and returns as soon as its text appears. Do not pass --timeout 5000; omit it. Set --timeout only when intentionally choosing a different limit.

Semantic UI tree

The show command takes an option --format semantic which returns a semantic tree representing the interactable UI elements. This requires direct support from the application to work; once the app is ready you can run this and see if it returns anything. An empty tree means no provider was connected at that moment. If the application is still starting, wait for visible readiness and retry once; otherwise use the visible screen instead. Treat protocol and provider errors as actionable failures rather than retrying them blindly. The application must be launched with --host opentui; the full read command is termctrl show app --format semantic.

Attempt to use the semantic UI tree if you need to discover available UI elements.

Drive Input Precisely

Send plain text with text:<value> and named keys as separate input atoms:

termctrl send app text:/connect enter
termctrl send app down enter
termctrl send app ctrl-c
printf '%s' 'multiline prompt' | termctrl send app --stdin

Use wait after sending input instead of sleeping or assuming that the interface has updated.

Operate OpenTUI Applications

Use the OpenTUI host handshake for applications such as OpenCode:

termctrl start app --host opentui --cols 112 --rows 34 -- opencode
termctrl wait app "/connect"
termctrl show app

Use resize when the application requires more visible area. Use restart app to reuse stored launch settings after a deliberate application restart.

Retain Evidence Deliberately

Save only requested formats:

termctrl save app --format txt --format png --out artifacts/current

Record demos only when the user wants a retained timeline or video. Add markers while the session is running, inspect them after stopping, then export with an explicit edit plan:

termctrl start app --record artifacts/run.termctrl -- my-terminal-app
termctrl wait app "Ready"
termctrl mark app ready
termctrl send app text:demo enter
termctrl wait app "Done" --timeout 60000
termctrl mark app done
termctrl stop app
termctrl markers artifacts/run.termctrl
termctrl show --recording artifacts/run.termctrl --at-marker done
termctrl video artifacts/run.termctrl --edit artifacts/run-edit.json --footer --out artifacts/run.mp4

Use edit-plan speed values conservatively when terminal text should remain readable. Use hold_ms or --tail-ms when the final frame is the payoff. Pass --footer when a polished demo should show the clip caption, elapsed timecode, and TERMINAL CONTROL branding in a bottom footer; omit it for ordinary videos.

Treat .termctrl recordings, ANSI transcripts, screen artifacts, command arguments, and terminal input as potentially sensitive. Do not retain them unless needed, and do not expose their contents unnecessarily.

Recover From Problems

  • Run termctrl status app to inspect state and launch settings.
  • Run termctrl list for running sessions, or termctrl list --all to include retained exited and stale entries. Preview cleanup with termctrl prune --dry-run, then run termctrl prune.
  • MCP agents should use semantic workspace tools for context, windows, panes, layout, focus, movement, resize, zoom, and close operations instead of sending human prefix shortcuts. Use get_screen or interact for visible state and save_screen only for a retained PNG.
  • If a session socket path is too long, set TERMCTRL_RUNTIME_DIR to a short private directory under /tmp before starting sessions.
  • If termctrl is unavailable, install Terminal Control with cargo install terminal-control or ask the user which installed binary to use.

Version History

  • e9e3744 Current 2026-07-23 04:34

    新增持久化原生终端工作区功能,支持重连的工作区守护进程、堆叠窗格、语义快照及窗口导航。优化了工作区生命周期管理、Socket序列化性能及与tmux的控制对齐。修复了语义发布边缘情况并限定OpenTUI主机范围。

  • 64865df 2026-07-19 22:41

    重构文档结构,将示例前置并拆分深度指南;新增共享前台终端会话功能;精简技能描述。

  • 31ae4fd 2026-07-05 18:22

Metadata

Files
0
Version
e9e3744
Hash
1d391468
Indexed
2026-07-05 18:22

Home - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-05 04:28
浙ICP备14020137号-1 $Map of visitor$