关于 tuistory
tuistory 是通过虚拟 PTY 自动化终端 UI 会话的驱动技能,支持脚本输入、确定性等待、文本快照和录制,适用于日常 TUI 自动化与回归检查。
主要功能
- 01通过 tctl 启动会话
- 02发送文本和组合键
- 03等待指定文本或输出稳定
- 04采集终端文本快照
- 05将会话录制为 .cast 文件
适用场景
- 01自动执行日常 TUI 操作
- 02运行终端 UI 回归检查
- 03核验脚本输入后的输出
- 04录制终端会话以供回放
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ factory-ai/ factory-plugins --skill tuistory安装后在 Claude Code 中输入/tuistory确认已加载。
详细介绍
Tuistory Driver
编排器将你路由到了这里。使用这些机制执行计划。
在虚拟 PTY 中启动目标命令,通过 Playwright 风格的 CLI 进行输入、按键、等待、快照和录制。
适用场景
- 常规 TUI 自动化和回归检查
- 针对虚拟屏幕缓冲区进行确定性的
wait/wait-idle - 精确呈现用户所见内容的文本快照
- 无需证明真实终端键盘编码的场景
如果需要证明 Ghostty 或 Kitty 对特定按键实际发出了什么,请改用 true-input。
前提条件
npm install -g tuistory # or: bun add -g tuistory
可选:tmux(滚屏缓冲区流)、asciinema(录制)、agg(将 .cast 转换为 .gif)。
核心模式
TCTL=${DROID_PLUGIN_ROOT}/bin/tctl
$TCTL launch "droid-dev" -s demo --backend tuistory \
--repo-root /path/to/worktree \
--cols 120 --rows 36 \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
$TCTL -s demo wait ">" --timeout 15000
$TCTL -s demo type "hello"
$TCTL -s demo press enter
$TCTL -s demo snapshot --trim
$TCTL -s demo close
**注意:**启动 droid-dev 时必须提供 --repo-root — tctl 会强制要求此参数。
启动时始终传入 --env FORCE_COLOR=3 --env COLORTERM=truecolor。虚拟 PTY 不会声明支持颜色,因此 Node.js 应用(Ink/chalk)会在未设置这些参数时抑制所有颜色转义码。
命令参考(通过 tctl)
| 命令 | 用途 |
|---|---|
launch <cmd> -s <name> --backend tuistory | 启动 tuistory 会话 |
type <text> | 发送字面文本 |
press <key> [keys...] | 发送组合按键(例如,press shift enter) |
wait <pattern> | 阻塞,直到出现文本或 /regex/ |
wait-idle | 阻塞,直到输出稳定 |
snapshot [--trim] | 输出清理后的文本(--trim 会去除末尾空白) |
close | 拆除会话 |
启动选项:--cols <n>、--rows <n>、--cwd <path>(子进程工作目录;设置了 --repo-root 时默认使用该值)、--env KEY=VALUE、--record <path>。
录制
启动时传入 --record。tctl 会在 PTY 外层包装 asciinema rec,因此必须在启动时设置录制(原生 tuistory 无法录制):
$TCTL launch "droid-dev" -s demo --backend tuistory \
--repo-root /path/to/worktree \
--cols 120 --rows 36 --record /tmp/demo.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
# ... interact ...
$TCTL -s demo close # finalizes the .cast
前后对比 — 在不同的工作树上启动两个会话:
$TCTL launch "droid-dev" -s before --backend tuistory \
--repo-root /path/to/baseline-worktree \
--cols 120 --rows 36 --record /tmp/before.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
$TCTL launch "droid-dev" -s after --backend tuistory \
--repo-root /path/to/candidate-worktree \
--cols 120 --rows 36 --record /tmp/after.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
播放:asciinema play /tmp/demo.cast
tmux(仅限滚屏缓冲区流)
仅当演示需要终端模拟器滚屏缓冲区,且应用使用标准缓冲区(而非备用屏幕)时才需要。true-input 会话很少需要 tmux,因为真实终端负责原生滚屏缓冲区。
启动时使用 --tmux。tctl 会在 tmux 中运行命令,以 TERM=xterm-256color 启动 tmux,并预先配置 default-terminal=tmux-256color、terminal-features=...,xterm-256color:RGB、terminal-overrides=...,xterm-256color:Tc(tmux < 3.2 时的后备设置)、COLORTERM=truecolor(通过 set-environment)、escape-time=50 和 mode-keys=vi。
复制模式:按 ctrl-b [ 进入,g g 跳到顶部,shift-g 跳到底部,ctrl-u/ctrl-d 翻半页,/ 搜索,按 q 退出(不要按 esc)。
使用 tmux 启动:
$TCTL launch "droid-dev" -s demo --backend tuistory --tmux \
--repo-root /path/to/worktree \
--cols 120 --rows 36 --record /tmp/demo.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
录制内容包含 tmux 重绘时,asciinema 必须包装 tmux,而不是反过来。
已知误区
- 直接运行
asciinema rec:不要直接调用asciinema rec。tctl --record会在 PTY 外层包装asciinema rec,这样 tuistory-relay 仍拥有会话,交互式 TUI(Ink/React)也能正确接收 stdin。手动调用asciinema rec会绕过此连接 — stdin 转发会失效,输入的按键会回显到外层 PTY,而非传递给子进程;tuistory 命令(wait、snapshot、close)也无法找到会话。 - 通过 tctl 标志运行原生
tuistory launch:tuistory没有--record、--backend、--repo-root或--env标志。传入这些标志会导致tuistory-relay崩溃。所有启动操作都请使用tctl。
故障恢复
$TCTL -s demo press esc # bail out of a stuck dialog
$TCTL -s demo snapshot --trim # check visible state
$TCTL -s demo close # hard reset
应急方案:原生 tuistory(最后手段)
如果 tctl 本身损坏或不可用,可以退而使用原生 tuistory,但仅限不录制的会话。原生 tuistory 只接受 --cols、--rows 和 -s — 不接受任何其他标志。不要传入 --record、--backend、--repo-root、--env 或 --tmux。
tuistory launch "my-tui-app" -s demo --cols 120 --rows 36
tuistory -s demo wait ">" --timeout 15000
tuistory -s demo snapshot --trim
tuistory -s demo close