showrunner 是做什么的?
将用户的“给我制作此应用的演示视频”需求转化为可重复、可审查的文件。CLI: node ~/.showrunner/bin/showrunner.mjs
(如果已链接,也可直接使用 showrunner)。从仓库中使用 ./install-skill.sh 完成一次性安装。
何时使用
用户希望录制一个Web 界面的视频(你可以在浏览器中打开):产品演示、功能导览、 “展示发生了什么变化”的录制、教程。不适用于原生桌面应用或需要音频旁白的场景。
协议:先思考,后执行
- 确认录制安全。 仅允许本地、预发环境或一次性数据。绝不要在包含真实客户数据
的生产环境中录制。永远不要将令牌写入场景;应使用
${env:NAME}。 - 启动应用并植入真实数据。 空白状态会给出糟糕的演示。创建故事所需的数据记录 (成功案例、失败案例、进行中的案例)。
- 先写故事板,再写 JSON。 演示控制在 4 分钟内:一个标题卡片,8-12 个场景, 每个场景 8-20 秒,一个结尾总结卡片。每个场景只有一个核心想法。字幕应说明观众 应该注意什么,而不是鼠标的动作。
- 使用
probe查找目标。 对每个页面运行showrunner probe <url>;粘贴它输出的{role,name}对象。优先使用角色(role)和可见名称,而不是 CSS 选择器。 - 验证,然后空跑。 先运行
showrunner check s.json,然后运行showrunner run s.json --fast --strict。空跑的时长大约是正式录制的四分之一。 在正式录制前修复每一个报告的错误步骤。 - 开始正式录制(
showrunner run s.json --out out)。它以真实速度运行, 因此请让它在后台启动并等待其完成;不要阻塞工具调用数分钟之久。 - 审核视频帧。 运行
showrunner sheet out/<name>.mp4 --every 5, 然后打开生成的 PNG。检查:字幕是否遮挡了主体(可使用"position": "left"), 是否有报错的场景,是否有弹出窗口或引导提示泄露进来,主题是否正确。 - 报告视频路径、时长、分辨率、场景列表以及任何出现问题的部分。除非用户要求, 否则不要提交或推送视频。
可能导致大量时间浪费的陷阱
| 现象 | 原因 | 修复方法 |
|---|---|---|
| 运行挂起数分钟 | 一个错误的选择器加上 30 秒的默认超时,并重复出现 | Showrunner 的默认超时是 8 秒,超时则会放弃当前场景;先使用 --fast --strict 运行 |
| 链接或按钮“不可见” | 侧边栏折叠,或该状态下菜单已关闭 | 先 goto 一个已知页面,或直接定位到页面 URL |
| 首次运行引导提示在视频中间弹出 | 应用对新用户显示引导提示 | 在应用的 storage 中设置“引导已查看”键,或在场景的 dismiss 中列出“Skip”按钮 |
getByText 匹配到隐藏的重复元素 | 文本也出现在隐藏的节点中 | 使用 { "role": "button", "name": "/^ITEM-1\\b/" } |
| 文档侧边栏的条目无反应 | 它们是 <button> 元素,而不是链接 | 定位时使用 { "role": "button", ... } |
| 字幕遮挡了抽屉或表单 | 底部居中的字幕与侧面板重叠 | 使用 "position": "left" 或 "right" |
| Shell 退出导致录制失败 | 后台任务与终端绑定 | 将其作为正确的后台任务运行,并轮询其完成状态 |
| 视频为空白或平铺状 | 录制的是 IDE 中嵌入的浏览器 | 使用 Showrunner 自带的独立无头 Chrome,而不是 WebView |
| 字幕轻微偏移 | 提示时间是从页面创建时刻开始计算的 | 适用于审查,不是精确到帧 |
场景速查表
{
"name": "demo", "baseUrl": "http://127.0.0.1:3000", "viewport": {"width":1440,"height":900},
"storage": { "token": "${env:DEMO_TOKEN}" },
"dismiss": ["text=Skip"],
"scenes": [
{ "name": "Title", "steps": [ {"goto":"/"}, {"card":{"title":"Acme","text":"Demo","hold":3000}} ] },
{ "name": "Create", "steps": [
{"caption":{"title":"1 · Create","text":"One click.","position":"left","hold":1500}},
{"click":{"role":"button","name":"New"}},
{"type":{"into":{"label":"Name"},"text":"Launch plan"}},
{"press":"Enter"}, {"wait":1500}
]},
{ "name": "Summary", "steps": [ {"caption":null}, {"card":{"title":"Summary","items":["A","B"],"hold":4000,"keep":true}} ] }
]
}
可用动作:goto click hover type press scroll wait waitFor caption card storage(任何步骤都可加上 "optional": true)。
完整参考:仓库的 README。
安全性
- 场景只包含数据:不执行代码,不运行 Shell。字幕文本已转义。
- 失败的步骤只会放弃当前场景;使用
--strict参数时,退出码为 1。 - 除非用户要求,否则不要提交、推送或分享视频。