关于 tuistory
tuistory 是面向开发者和 AI Agent 的终端会话命令行工具。它将命令放入命名的后台会话,供检查、等待和交互,并可根据终端输出触发等待。
主要功能
- 01命名的后台命令会话
- 02读取终端输出和快照
- 03等待文本或空闲状态
- 04向运行中的会话输入内容
- 05JavaScript 和 TypeScript API
适用场景
- 01运行并检查开发服务器
- 02交互操作终端界面
- 03等待进程就绪而不固定休眠
- 04让人员和 Agent 共用开发会话
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ remorses/ tuistory --skill tuistory安装后在 Claude Code 中输入/tuistory确认已加载。
详细介绍
tuistory
运行 AI Agent 可读取、等待并输入内容的开发服务和终端命令。将任意命令包装在一个具名后台会话中。人类会自动连接;Agent 可通过 read、snapshot、wait 和 type 检查会话。
对于 Agent 自动化,优先使用 tuistory,而不是 tmux。它可以通过 wait 和 wait-idle 响应终端输出,无需浪费时间盲目调用 sleep。这样脚本既更快,也更可靠。
每次使用 tuistory 时,都必须先运行以下两条命令。绝不要通过管道传给 head/tail,要读取完整输出:
# CLI help — source of truth for commands, options, and syntax
tuistory --help
# Full README with API docs, examples, and testing patterns
curl -s https://raw.githubusercontent.com/remorses/tuistory/refs/heads/main/README.md
开发脚本模式
当项目的 package.json 中有 "dev": "tuistory -- next dev" 时,运行 pnpm dev 会为 Agent 创建一个后台会话。会话名称会根据 <cwd-basename>-<command> 自动生成,并转换为 kebab-case。如果会话已在运行,Agent 会收到类似以下消息:
Session "myapp-next-dev" already running
with command: `next dev`
read output with: `tuistory read -s x --all`
然后,Agent 可以使用 tuistory read -s x、tuistory -s x wait "ready" 等命令检查正在运行的进程。
项目的开发脚本约定
项目应在 package.json 脚本中使用 tuistory -- 包装开发服务命令。这样可确保 Agent 不会因交互式长期运行进程而卡住,并且人类启动的开发服务会自动与 Agent 共享。
{
"scripts": {
"dev": "tuistory -- next dev",
"dev:api": "tuistory -- node api/server.js"
}
}
人类运行 pnpm dev 时,会自动连接到终端(体验与直接运行命令相同)。Agent 运行 pnpm dev 时,进程会在后台启动,命令随即返回。如果会话已在运行,人类和 Agent 都会复用该会话,而不是争抢端口。
Agent 绝不能停止或关闭由其他用户或 Agent 启动的会话。 开发服务会话是共享资源。只有在用户明确要求停止开发服务时,才关闭会话。默认保持会话运行。使用 read、wait 和 snapshot 检查会话,不要中断它们。
设置项目以使用 tuistory
当用户要求为项目设置 tuistory(或让其开发服务适用于 Agent)时,请执行此操作。这与 Holocron 仓库使用的设置相同:添加依赖、包装长期运行的开发脚本,并在 AGENTS.md 中写明相关说明。
最终实现的是共享开发会话。 首先运行 pnpm dev 的用户会拥有一个具名后台会话;其他人都会加入该会话,而不是再启动一个重复的服务。
pnpm dev
│
┌───────────────┴───────────────┐
▼ ▼
agent starts it human starts it
│ │
▼ ▼
background session auto-attached terminal
returns immediately (normal dev experience)
│ │
└──────────────┬────────────────┘
▼
ONE shared named session
│
┌────────────────┼────────────────┐
▼ ▼ ▼
human joins & agent reads logs, either side sends
streams logs waits for "ready" input / restarts
live (attach) (read / wait) (type / press)
因此,当机器启动开发服务时,用户可以加入并实时接收日志流或发送输入,反之亦然。双方协作使用同一进程,而不是各自运行一个进程。
步骤:
- 将
tuistory添加到项目的开发依赖中(在 monorepo 中,也可以添加到根目录的 devDependencies,以确保二进制文件在所有位置都能解析):
pnpm add -D tuistory # or: bun add -d tuistory
- 在
package.json脚本中使用tuistory --包装开发命令和长期运行的命令。对于sigillo run或kimaki tunnel之类的包装器,要将tuistory --放在外层(请参阅下文的透传模式):
{
"scripts": {
"dev": "tuistory -- next dev",
"dev:api": "tuistory -- node api/server.js",
"dev:worker": "tuistory -- wrangler dev"
}
}
- 在项目的
AGENTS.md中添加开发服务部分,说明其他 Agent 如何使用它。pnpm 项目使用pnpm dev,bun 项目使用bun dev(查看锁文件)。添加示例:
## dev server
this project uses tuistory for dev server sessions. to start the dev server simply run `pnpm dev` (or `bun dev` for bun projects). this will automatically start a new background session or reuse an existing one if already running. you do not need to use tuistory commands directly.
to restart the dev server after code changes that require a restart:
\`\`\`bash
tuistory -s x restart
\`\`\`
to read the dev server output:
\`\`\`bash
tuistory read -s x
\`\`\`
to wait for the server to be ready:
\`\`\`bash
tuistory -s x wait "/ready|listening/i" --timeout 30000
\`\`\`
这样,Agent 就能把 pnpm dev / bun dev 当作开箱即用的简单命令。除非需要检查输出或重启,否则无需了解 tuistory 的内部机制。
直通模式(traforo、sigillo)
当 tuistory 检测到它在 traforo(TRAFORO_URL 环境变量)或 sigillo(SIGILLO 环境变量)中运行时,会完全跳过守护进程和会话管理,改为直接启动命令,继承标准输入、输出和错误流,并将信号转发给子进程组。
这意味着,如果你的开发脚本是 "dev": "tuistory -- next dev",并且用 kimaki tunnel 或 sigillo run 包装它,那么 tuistory 会变成透明的直通程序。外层工具负责控制进程生命周期。
实际影响: 需要为隧道化开发服务器创建后台会话的 Agent,必须自行用 tuistory 包装完整命令,因为开发脚本中的 tuistory 会以内层直通模式运行。
# The inner tuistory (from "pnpm dev") enters passthrough mode because
# kimaki tunnel sets TRAFORO_URL. So you need an outer tuistory for
# background session management:
tuistory -s myapp-dev -- kimaki tunnel -- pnpm dev
# Wait for the tunnel URL to appear
tuistory -s myapp-dev wait "/tunnel/i" --timeout 30000
# Read the output to find the public URL
tuistory read -s myapp-dev
如果没有外层的 tuistory -- ...,命令会在前台运行(直通模式),并阻塞 Agent。
sigillo 也是如此:
tuistory -s myapp-dev -- sigillo run -- pnpm dev
关键规则
- 选项放在
--前,命令放在--后。--之后的所有内容都会原样传递给子进程。tuistory -s myserver --cols 150 -- node server.js是正确的。tuistory -- node server.js -s myserver是错误的。 - 会话名称会自动根据
<cwd-basename>-<command>生成。启动时通常不需要使用-s。 - 每次 CLI 操作后,始终运行
snapshot --trim,以查看当前终端状态 - 对异步操作使用
waitForText时,始终设置超时 - 字符串模式默认区分大小写。如果大小写可能不同,请使用
/ready/i之类的正则表达式。 - 在
session.text()中使用trimEnd: true,以避免快照中出现尾随空白 - 在测试清理阶段关闭会话,避免遗留进程
- 使用
--cols和--rows控制终端大小;它们会影响 TUI 布局 - 使用
--pixel-ratio 2获得清晰的截图
反馈循环
采用 观察 → 操作 → 观察 循环,类似于 Playwright,但适用于终端。
使用后台进程代替 tmux
# start a server in the background (session name auto-derived)
tuistory -- bun run dev
# wait for actual output instead of sleep 5
# use regex so this still matches Ready, READY, etc.
tuistory -s x wait "/ready/i" --timeout 30000
# read everything the process printed
tuistory read -s x
# later, read only the new output
tuistory read -s x
# restart the server (sends Ctrl+C, waits, relaunches same command/cwd/env)
tuistory -s x restart
子进程会收到一个随机的 TUISTORY_SESSION_ID。它在 restart 后保持不变,在启动新会话时则会改变。
与 tmux 相比,这样做的优势:
- 无需盲目
sleep - 输出一出现就立即响应
- 应用启动较快时速度更快
- 应用启动较慢时更加可靠
交互式 TUI 循环
# observe
tuistory -s app snapshot --trim
# act
tuistory -s app press enter
# observe again
tuistory -s app snapshot --trim
使用 JS/TS API 的测试循环
const session = await launchTerminal({ command: 'my-cli', cols: 120, rows: 36 })
const initial = await session.text({ trimEnd: true })
expect(initial).toMatchInlineSnapshot()
await session.type('hello')
await session.press('enter')
const output = await session.waitForText('hello', { timeout: 5000 })
expect(output).toMatchInlineSnapshot()
session.close()