@remixmate/cli 0.9.11 → 0.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +9 -5
  2. package/README.zh-CN.md +10 -6
  3. package/dist/cli.js +4 -1
  4. package/dist/manifest.json +21 -25
  5. package/dist/skill-schema.d.ts +1 -1
  6. package/package.json +2 -2
  7. package/skills/gen-script/SKILL.md +20 -1
  8. package/skills/prepare-video-assets/SKILL.md +17 -1
  9. package/skills/render-video/SKILL.md +13 -0
  10. package/skills/web-record/SKILL.md +236 -20
  11. package/skills/web-record/skill.json +2 -2
  12. package/skills/web-screenshot/SKILL.md +255 -0
  13. package/skills/{web-capture → web-screenshot}/skill.json +3 -3
  14. package/skills/web-screenshot/version.json +7 -0
  15. package/skills/web-capture/SKILL.md +0 -474
  16. package/skills/web-capture/version.json +0 -7
  17. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/__init__.py +0 -0
  18. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/bootstrap.py +0 -0
  19. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/browser.py +0 -0
  20. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/cli_args.py +0 -0
  21. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/arrow.js +0 -0
  22. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/caption.js +0 -0
  23. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/clear_overlay.js +0 -0
  24. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/cursor_bootstrap.js +0 -0
  25. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/cursor_hide.js +0 -0
  26. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/cursor_move.js +0 -0
  27. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/cursor_ripple.js +0 -0
  28. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/element_zoom.js +0 -0
  29. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/element_zoom_restore.js +0 -0
  30. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/fade_out_overlays.js +0 -0
  31. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/focus.js +0 -0
  32. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/highlight.js +0 -0
  33. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/overlay_bootstrap.js +0 -0
  34. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/page_zoom_in.js +0 -0
  35. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/page_zoom_out.js +0 -0
  36. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/page_zoom_restore.js +0 -0
  37. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/redact.js +0 -0
  38. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/scroll.js +0 -0
  39. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/scroll_through.js +0 -0
  40. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/sequence.js +0 -0
  41. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/settled_check.js +0 -0
  42. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js/title_card.js +0 -0
  43. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/js_loader.py +0 -0
  44. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/overlay.py +0 -0
  45. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/recording.py +0 -0
  46. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/__init__.py +0 -0
  47. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/arrow.py +0 -0
  48. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/caption.py +0 -0
  49. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/click.py +0 -0
  50. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/code_lines.py +0 -0
  51. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/focus.py +0 -0
  52. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/highlight.py +0 -0
  53. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/hover.py +0 -0
  54. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/redact.py +0 -0
  55. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/scroll.py +0 -0
  56. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/sequence.py +0 -0
  57. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/title_card.py +0 -0
  58. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/type.py +0 -0
  59. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/wait.py +0 -0
  60. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/scenes/zoom.py +0 -0
  61. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/screenshot.py +0 -0
  62. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/storyboard.py +0 -0
  63. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/template.py +0 -0
  64. /package/skills/{web-capture → web-screenshot}/scripts/_media_screenshot/trim.py +0 -0
  65. /package/skills/{web-capture → web-screenshot}/scripts/_media_upload.py +0 -0
  66. /package/skills/{web-capture → web-screenshot}/scripts/record.py +0 -0
  67. /package/skills/{web-capture → web-screenshot}/scripts/screenshot.py +0 -0
  68. /package/skills/{web-capture → web-screenshot}/templates/github-code-tour.json +0 -0
  69. /package/skills/{web-capture → web-screenshot}/templates/github-readme-tour.json +0 -0
  70. /package/skills/{web-capture → web-screenshot}/templates/github-repo-intro.json +0 -0
package/README.md CHANGED
@@ -94,7 +94,7 @@ cp .env.example .env
94
94
  source .env
95
95
  ```
96
96
 
97
- Python skills (6 of 11) require `python3 >= 3.10`. `web-capture` requires Playwright (auto-installs chromium on first run). `ffmpeg` is only needed for `video-parser`'s optional local tool (`deconstruct_video.py`); the default `video-parser` entry runs server-side via ab-render and needs no local ffmpeg.
97
+ Python skills (8 of 12) require `python3 >= 3.10`. `web-screenshot` / `web-record` require Playwright (auto-installs chromium on first run). `ffmpeg` is only needed for `video-parser`'s optional local tool (`deconstruct_video.py`); the default `video-parser` entry runs server-side via ab-render and needs no local ffmpeg.
98
98
 
99
99
  ## Skills
100
100
 
@@ -119,7 +119,8 @@ This project contains 11 AI media generation skills covering the full pipeline f
119
119
  ├─────────────────────────────────────────────────────────────┤
120
120
  │ Tool Skills │
121
121
  │ video-parser Video deconstruction (audio / ASR / kf) │
122
- │ web-capture Web page screenshot / scroll-record
122
+ │ web-screenshot Web page screenshot (png / jpg)
123
+ │ web-record Web page recording / storyboard video │
123
124
  └─────────────────────────────────────────────────────────────┘
124
125
  ```
125
126
 
@@ -140,7 +141,8 @@ This project contains 11 AI media generation skills covering the full pipeline f
140
141
  │ ├── render-video/ # orchestration: Phase 3 Remotion render (canonical render_video.py)
141
142
  │ ├── export-jianying/ # orchestration: export Jianying draft ZIP
142
143
  │ ├── video-parser/ # tool: video deconstruction & analysis
143
- └── web-capture/ # tool: headless-browser screenshot / recording
144
+ ├── web-screenshot/ # tool: headless-browser screenshot (also hosts record.py)
145
+ │ └── web-record/ # tool: headless-browser recording (entry -> web-screenshot/scripts/record.py)
144
146
  └── README.md
145
147
  ```
146
148
 
@@ -158,7 +160,8 @@ This project contains 11 AI media generation skills covering the full pipeline f
158
160
  | render-video | orchestration | job_id → Remotion render → upload | python `scripts/render_video.py` |
159
161
  | export-jianying | orchestration | Asset URLs → Jianying draft ZIP (auto-converts from RenderPlan) | python `scripts/gen_jianying_draft.py` |
160
162
  | video-parser | tool | Video → audio + ASR + keyframes + scene segmentation | python `scripts/parse_via_render.py` |
161
- | web-capture | tool | Web page screenshot / scroll-record / storyboard video | python `scripts/screenshot.py`, `scripts/record.py` |
163
+ | web-screenshot | tool | Web page screenshot (png / jpg) | python `scripts/screenshot.py` |
164
+ | web-record | tool | Web page recording / scroll-through / storyboard video (webm -> mp4 -> VOD) | python `../web-screenshot/scripts/record.py` |
162
165
 
163
166
  ### Core workflows
164
167
 
@@ -217,7 +220,8 @@ remixmate prepare-video-assets --help
217
220
  remixmate render-video --help
218
221
  remixmate export-jianying --help
219
222
  remixmate video-parser --help
220
- remixmate web-capture --help
223
+ remixmate web-screenshot --help
224
+ remixmate web-record --help
221
225
  remixmate template-registry --help
222
226
 
223
227
  # http skills (gen-image, gen-video, gen-voice, gen-digital-human) take no
package/README.zh-CN.md CHANGED
@@ -70,11 +70,11 @@ cp .env.example .env
70
70
  source .env
71
71
  ```
72
72
 
73
- Python 技能(11 个中的 6 个)需要 `python3 >= 3.10`。`web-capture` 需要 Playwright(首次运行自动安装 chromium)。`ffmpeg` 仅 `video-parser` 的可选本地工具(`deconstruct_video.py`)需要;`video-parser` 默认入口走 ab-render 服务端解构,无需本地 ffmpeg。
73
+ Python 技能(12 个中的 8 个)需要 `python3 >= 3.10`。`web-screenshot` / `web-record` 需要 Playwright(首次运行自动安装 chromium)。`ffmpeg` 仅 `video-parser` 的可选本地工具(`deconstruct_video.py`)需要;`video-parser` 默认入口走 ab-render 服务端解构,无需本地 ffmpeg。
74
74
 
75
75
  ## 技能
76
76
 
77
- 本项目包含 11 个 AI 媒体生成技能,覆盖从素材生成、脚本编排、模板绑定、视频渲染到剪映导出的完整视频内容生产链路。
77
+ 本项目包含 12 个 AI 媒体生成技能,覆盖从素材生成、脚本编排、模板绑定、视频渲染到剪映导出的完整视频内容生产链路。
78
78
 
79
79
  ### 技能分层
80
80
 
@@ -95,7 +95,8 @@ Python 技能(11 个中的 6 个)需要 `python3 >= 3.10`。`web-capture`
95
95
  ├─────────────────────────────────────────────────────────────┤
96
96
  │ 工具层 Skills │
97
97
  │ video-parser 视频解构(音频提取 / ASR / 关键帧) │
98
- │ web-capture 网页截图 / 滚动录屏 / 分镜视频
98
+ │ web-screenshot 网页截图(png / jpg)
99
+ │ web-record 网页录屏 / 滚动录屏 / 分镜视频 │
99
100
  └─────────────────────────────────────────────────────────────┘
100
101
  ```
101
102
 
@@ -116,7 +117,8 @@ Python 技能(11 个中的 6 个)需要 `python3 >= 3.10`。`web-capture`
116
117
  │ ├── render-video/ # 编排: Phase 3 Remotion 渲染(含 render_video.py 实现)
117
118
  │ ├── export-jianying/ # 编排: 导出剪映草稿 ZIP
118
119
  │ ├── video-parser/ # 工具: 视频解构与分析
119
- └── web-capture/ # 工具: 无头浏览器截图 / 录屏
120
+ ├── web-screenshot/ # 工具: 无头浏览器截图(record.py 也放在这里)
121
+ │ └── web-record/ # 工具: 无头浏览器录屏(入口指向 web-screenshot/scripts/record.py)
120
122
  └── README.md
121
123
  ```
122
124
 
@@ -134,7 +136,8 @@ Python 技能(11 个中的 6 个)需要 `python3 >= 3.10`。`web-capture`
134
136
  | render-video | 编排 | job_id → Remotion 渲染 → 上传 | python `scripts/render_video.py` |
135
137
  | export-jianying | 编排 | 素材 URL → 剪映草稿 ZIP(支持从 RenderPlan 自动转换) | python `scripts/gen_jianying_draft.py` |
136
138
  | video-parser | 工具 | 视频 → 音频 + ASR + 关键帧 + 场景分段 | python `scripts/parse_via_render.py` |
137
- | web-capture | 工具 | 网页截图 / 滚动录屏 / 分镜视频 | python `scripts/screenshot.py`、`scripts/record.py` |
139
+ | web-screenshot | 工具 | 网页截图(png / jpg) | python `scripts/screenshot.py` |
140
+ | web-record | 工具 | 网页录屏 / 滚动录屏 / 分镜视频(webm → mp4 → VOD) | python `../web-screenshot/scripts/record.py` |
138
141
 
139
142
  ### 核心链路
140
143
 
@@ -170,7 +173,8 @@ remixmate prepare-video-assets --help
170
173
  remixmate render-video --help
171
174
  remixmate export-jianying --help
172
175
  remixmate video-parser --help
173
- remixmate web-capture --help
176
+ remixmate web-screenshot --help
177
+ remixmate web-record --help
174
178
  remixmate template-registry --help
175
179
 
176
180
  # http 技能(gen-image、gen-video、gen-voice、gen-digital-human)没有
package/dist/cli.js CHANGED
@@ -33,7 +33,10 @@ function resolveBaseDir() {
33
33
  }
34
34
  function describeEntryTail(s) {
35
35
  if (s.entry.type === 'python') {
36
- return `(scripts/${s.entry.scriptPath.replace(/^scripts\//, '')})`;
36
+ // scriptPath 可以指向别的 skill 目录(如 web-record → ../web-screenshot/…),
37
+ // 这种相对路径原样打印,只给同目录脚本补上 scripts/ 前缀。
38
+ const p = s.entry.scriptPath;
39
+ return `(${p.startsWith('.') ? p : `scripts/${p.replace(/^scripts\//, '')}`})`;
37
40
  }
38
41
  return `[${s.entry.handler}]`;
39
42
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.9.11",
4
- "generatedAt": "2026-07-27T06:23:26.117Z",
3
+ "version": "0.9.13",
4
+ "generatedAt": "2026-08-12T07:37:17.101Z",
5
5
  "skills": [
6
6
  {
7
7
  "id": "export-jianying",
@@ -241,25 +241,21 @@
241
241
  ]
242
242
  },
243
243
  {
244
- "id": "web-capture",
244
+ "id": "web-record",
245
245
  "tier": "tool",
246
246
  "category": "consuming",
247
- "title": "Web Page Capture",
248
- "summary": "Drive a headless browser (Playwright Python) to capture any URL to a local STILL IMAGE (png/jpg): full-page / viewport / element / region screenshots, with device emulation, waiting, hide/mask/redact, and static annotations (highlight / arrow / caption / numbered sequence / redact). Images only for video / recording / scroll-through / storyboard clips (webm) use the web_record tool instead.",
247
+ "title": "Web Page Recording",
248
+ "summary": "Drive a headless browser (Playwright Python) to RECORD any URL to a video, then (by default) transcode to mp4, grab a cover frame, upload to VOD and return a playable CDN URL. Modes: fixed-duration recording, condition-triggered stop (element appears / disappears), auto-scroll from top to bottom, custom storyboards, and parameterized templates. Storyboard scenes: highlight / focus / zoom / scroll / virtual-cursor click / type / hover / caption / title-card / arrow / numbered sequence / redact / code-line highlight. For still images (png/jpg) use the web_screenshot tool instead. Use this tool whenever the user wants a video / recording / screencast of a web page: record a page, scroll-through video, page-from-top-to-bottom clip, demo of clicks/typing/hover, storyboard / multi-scene intro video, or a template-based clip.",
249
249
  "triggers": [
250
- "网页截图、网页截屏、整页截图、长截图、full page screenshot",
251
- "截某个元素 / 区域、局部截屏、focus 某个区域",
252
- "录屏、网页录制、录制视频、录一段操作、生成 webm",
250
+ "录屏、网页录制、录制视频、录一段操作、生成 webm、screencast",
253
251
  "滚动录屏、页面从头划到尾的视频",
254
252
  "多场景视频、分镜视频、storyboard、按时间线编排",
255
253
  "演示点击 / 输入 / 悬停(虚拟鼠标 + 涟漪 / 打字机 / 触发 tooltip)",
256
- "加箭头、加字幕条、加标题卡 / 片头片尾、按顺序编号高亮多个区域",
257
- "截图前隐藏元素 / 涂盖打码、给静态截图加注释(红框 / 箭头 / 标签)",
258
- "移动端 / 设备模拟、带 cookie / 登录态截屏 / 录屏"
254
+ "模板视频一行出片、按顺序编号高亮多个区域并录制"
259
255
  ],
260
256
  "entry": {
261
257
  "type": "python",
262
- "scriptPath": "scripts/screenshot.py"
258
+ "scriptPath": "../web-screenshot/scripts/record.py"
263
259
  },
264
260
  "runtime": "python",
265
261
  "envVars": [
@@ -267,25 +263,27 @@
267
263
  "WEB_CAPTURE_OUTPUT_BASE",
268
264
  "WEB_CAPTURE_NO_SANDBOX",
269
265
  "WEB_CAPTURE_ALLOW_PRIVATE_HOSTS",
270
- "PLAYWRIGHT_BROWSERS_PATH"
266
+ "PLAYWRIGHT_BROWSERS_PATH",
267
+ "REMOTION_RENDER_API_URL",
268
+ "PRIV_TOKEN"
271
269
  ]
272
270
  },
273
271
  {
274
- "id": "web-record",
272
+ "id": "web-screenshot",
275
273
  "tier": "tool",
276
274
  "category": "consuming",
277
- "title": "Web Page Recording",
278
- "summary": "Drive a headless browser (Playwright Python) to RECORD any URL to a video, then (by default) transcode to mp4, grab a cover frame, upload to VOD and return a playable CDN URL. Modes: fixed-duration recording, condition-triggered stop (element appears / disappears), auto-scroll from top to bottom, custom storyboards, and parameterized templates. Storyboard scenes: highlight / focus / zoom / scroll / virtual-cursor click / type / hover / caption / title-card / arrow / numbered sequence / redact / code-line highlight. For still images (png/jpg) use the web_capture tool instead. Use this tool whenever the user wants a video / recording / screencast of a web page: record a page, scroll-through video, page-from-top-to-bottom clip, demo of clicks/typing/hover, storyboard / multi-scene intro video, or a template-based clip.",
275
+ "title": "Web Page Screenshot",
276
+ "summary": "Drive a headless browser (Playwright Python) to capture any URL to a local STILL IMAGE (png/jpg): full-page / viewport / element / region screenshots, with device emulation, waiting, hide/mask/redact, and static annotations (highlight / arrow / caption / numbered sequence / redact). Images only for video / recording / scroll-through / storyboard clips (webm) use the web_record tool instead.",
279
277
  "triggers": [
280
- "录屏、网页录制、录制视频、录一段操作、生成 webm、screencast",
281
- "滚动录屏、页面从头划到尾的视频",
282
- "多场景视频、分镜视频、storyboard、按时间线编排",
283
- "演示点击 / 输入 / 悬停(虚拟鼠标 + 涟漪 / 打字机 / 触发 tooltip)",
284
- "模板视频一行出片、按顺序编号高亮多个区域并录制"
278
+ "网页截图、网页截屏、整页截图、长截图、full page screenshot",
279
+ "截某个元素 / 区域、局部截屏、focus 某个区域",
280
+ "截图前隐藏元素 / 涂盖打码、给静态截图加注释(红框 / 箭头 / 标签)",
281
+ "高亮某文件的 L5-L20 代码行并截图",
282
+ "移动端 / 设备模拟截图、带 cookie / 登录态截图"
285
283
  ],
286
284
  "entry": {
287
285
  "type": "python",
288
- "scriptPath": "../web-capture/scripts/record.py"
286
+ "scriptPath": "scripts/screenshot.py"
289
287
  },
290
288
  "runtime": "python",
291
289
  "envVars": [
@@ -293,9 +291,7 @@
293
291
  "WEB_CAPTURE_OUTPUT_BASE",
294
292
  "WEB_CAPTURE_NO_SANDBOX",
295
293
  "WEB_CAPTURE_ALLOW_PRIVATE_HOSTS",
296
- "PLAYWRIGHT_BROWSERS_PATH",
297
- "REMOTION_RENDER_API_URL",
298
- "PRIV_TOKEN"
294
+ "PLAYWRIGHT_BROWSERS_PATH"
299
295
  ]
300
296
  }
301
297
  ]
@@ -27,7 +27,7 @@ export type SkillEntry = {
27
27
  * - "authoring": 创建 / 编辑模板期间使用,例如 template-registry / gen-script /
28
28
  * render-video(用于 try_render) / prepare-video-assets。
29
29
  * - "consuming": 消费已有模板生成媒体,例如 export-jianying / video-parser /
30
- * web-capture(与"创建模板"无关,是消费侧场景)。
30
+ * web-screenshot / web-record(与"创建模板"无关,是消费侧场景)。
31
31
  * - "asset": 生成单一类型素材的原子 skill:gen-image / gen-voice /
32
32
  * gen-video / gen-digital-human。authoring 也会用,但通过 stub
33
33
  * 方式占位;consuming 场景下是真调用。
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@remixmate/cli",
3
- "version": "0.9.11",
4
- "description": "AI media generation skills for Claude Code / Codex — 11 skills covering image, video, voice, digital human, web capture, script, template registry, rendering, Jianying export, and video deconstruction.",
3
+ "version": "0.9.13",
4
+ "description": "AI media generation skills for Claude Code / Codex — 12 skills covering image, video, voice, digital human, web screenshot, web recording, script, template registry, rendering, Jianying export, and video deconstruction.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -9,6 +9,8 @@ description: |
9
9
  - Turn a topic into a video structure / video content plan
10
10
 
11
11
  Even when the user does not say "generate the DSL", use this skill whenever they want to turn a topic into a structured video plan.
12
+
13
+ ⚠️ Stop-and-confirm gate: after this skill returns a DSL, show the full script and wait for the user's explicit confirmation. Never call `prepare_video_assets` in the same turn.
12
14
  triggers:
13
15
  - Write a video script, generate a video script, plan a video, write storyboards
14
16
  - Create a short video, plan video content, generate a Video DSL
@@ -19,6 +21,13 @@ triggers:
19
21
 
20
22
  Turns a user-supplied **topic** into a **Video DSL v1alpha1** JSON describing what the final video should look like (scene structure, asset requirements, narration text, visual layout). It never produces any asset itself.
21
23
 
24
+ > ⚠️ **Stop-and-confirm gate (mandatory, do not skip).**
25
+ > This skill produces a *draft* for the user to review, not an input to chain onward automatically.
26
+ > After it returns, show the full script and **stop your turn** — wait for the user to explicitly confirm.
27
+ > **Never** call `prepare_video_assets` in the same turn as `gen_script`: asset generation spends
28
+ > image and TTS credits that cannot be refunded, and a wrong narration line means paying for the
29
+ > whole batch twice. See **"Agent behavior: script confirmation"** below for the required summary format.
30
+
22
31
  ## Core concepts
23
32
 
24
33
  - **Video DSL**: a declarative description language for videos — describes the final structure, not the orchestration calls.
@@ -84,9 +93,19 @@ This skill does not hit any external API; no token required. The script only doe
84
93
  ### Confirmation flow
85
94
 
86
95
  1. After the agent generates or modifies the DSL, **show the script summary first; do not pass it downstream yet**.
87
- 2. Wait for the user to explicitly confirm (e.g. "OK", "looks good", "continue with template binding") before handing it to `prepare-video-assets` (or `template-registry` for a list-only lookup).
96
+ 2. **End your turn there and wait** for the user to explicitly confirm (e.g. "OK", "looks good", "continue with template binding") before handing it to `prepare-video-assets` (or `template-registry` for a list-only lookup).
88
97
  3. If the user asks for changes (adjust narration, add or remove scenes, change durations), the agent updates the DSL and shows the summary again, then waits for confirmation once more.
89
98
 
99
+ > ⚠️ **Never** call `prepare_video_assets` before the user has confirmed — not even when the original
100
+ > request was a single end-to-end instruction like "make me a video about X". That request authorizes
101
+ > the *pipeline*, not the skipping of its review steps. "Finish the task in one go" does **not** apply
102
+ > here: stopping for confirmation **is** the correct completion of this step.
103
+
104
+ ### Showing the script
105
+
106
+ Show **every scene in full** — do not collapse them with phrases like "scenes 2–6 same as above".
107
+ The user is reviewing the narration word by word; a summary they cannot proofread defeats the gate.
108
+
90
109
  ### Summary content
91
110
 
92
111
  The agent should show the following in clear Markdown:
@@ -9,6 +9,8 @@ description: |
9
9
  - Regenerate one asset (image / audio) for a specific scene
10
10
 
11
11
  Next step: after the user confirms the resolved assets, call `render_video` with the `job_id` returned by this skill.
12
+
13
+ ⚠️ Stop-and-confirm gate: this skill runs only after the user has confirmed the script, and after it returns you must show the resolved assets and wait for the user's explicit confirmation. Never call `render_video` in the same turn.
12
14
  triggers:
13
15
  - Generate / prepare video assets
14
16
  - Resolve missing assets in a DSL
@@ -20,6 +22,14 @@ triggers:
20
22
 
21
23
  Phase 1 of the two-phase video pipeline. Takes a Video DSL plus a template binding, walks every `AssetRef` declared in the DSL, calls the matching atomic skills to fill in missing assets (`gen-image`, `gen-voice`, `gen-video`, `gen-digital-human`), persists the resulting RenderPlan to ab-api, and prints a `job_id` for the user-confirmation step.
22
24
 
25
+ > ⚠️ **Stop-and-confirm gate (mandatory, do not skip) — both sides of this skill.**
26
+ > **Before**: only run this skill after the user has confirmed the script produced by `gen_script`.
27
+ > **After**: show the resolved assets (images inline, audio as links) and **stop your turn** — wait for
28
+ > the user to explicitly confirm before rendering. **Never** call `render_video` in the same turn as
29
+ > `prepare_video_assets`. This is the last checkpoint where a bad image or a wrong TTS take can be
30
+ > fixed for the price of one asset instead of a whole re-render.
31
+ > See **"Pre-render user confirmation (Phase 2)"** below for the required summary format.
32
+
23
33
  > **Next step**: after the user reviews the assets and confirms, call **`render_video`** with the `job_id` returned by this skill.
24
34
 
25
35
  ## Pipeline (this skill's part only)
@@ -94,7 +104,13 @@ python3 <SkillDir>/scripts/prepare_video_assets.py \
94
104
 
95
105
  ## Pre-render user confirmation (Phase 2)
96
106
 
97
- This skill is the **first half** of a two-phase user-confirmation flow. After it returns, the agent must show the user the resolved assets and wait for confirmation before calling `render_video`. The recommended summary format:
107
+ This skill is the **first half** of a two-phase user-confirmation flow. After it returns, the agent **must** show the user the resolved assets, then **end its turn and wait** for confirmation before calling `render_video`.
108
+
109
+ > ⚠️ **Never** start the final render before the user confirms. An end-to-end request ("make me a video
110
+ > about X") authorizes the pipeline, not the skipping of its review steps — stopping here **is** the
111
+ > correct completion of this step, not an unfinished task.
112
+
113
+ Read the `job_id` from the stdout line `📦 render job jobId: N` and remember it; asset URLs come from the `🔊 TTS audio:` and `🖼 Image assets:` sections. Show images inline (`![name](https://...)`) and audio as links (`[🔊 listen](http://cdn.../x.mp3)`) so the user can actually review them. The recommended summary format:
98
114
 
99
115
  ```markdown
100
116
  ## Render confirmation
@@ -9,6 +9,8 @@ description: |
9
9
  - Render with Remotion
10
10
 
11
11
  Prerequisite: assets must already be generated via `prepare_video_assets`. This skill never resolves or regenerates assets — pass it a `job_id` from a previous `prepare_video_assets` call.
12
+
13
+ ⚠️ Stop-and-confirm gate: never call this skill until the user has explicitly confirmed the assets prepared by `prepare_video_assets`. If those assets were prepared in the current turn and the user has not replied since, stop and ask instead of rendering.
12
14
  triggers:
13
15
  - Render the video, composite the video, export the video
14
16
  - Turn the prepared assets into the final clip
@@ -22,6 +24,17 @@ Loads a persisted RenderPlan from the database (or a local file fallback), compi
22
24
 
23
25
  > **Prerequisite**: assets must already be generated via `prepare_video_assets`. That skill returns a `job_id` integer; pass it here.
24
26
 
27
+ > ⚠️ **Stop-and-confirm gate (mandatory, do not skip).**
28
+ > **Never** call this skill until the user has explicitly confirmed the assets shown after
29
+ > `prepare_video_assets`. If those assets were prepared in the current turn and the user has not
30
+ > replied since, **stop and ask** — do not render. This step spends render credits and uploads the
31
+ > result; it is the one action in the pipeline that cannot be walked back cheaply.
32
+ >
33
+ > "Confirmed" means the user said so **in a message of their own** (e.g. "confirm", "go ahead",
34
+ > "looks good", "continue"). An end-to-end instruction from earlier in the conversation
35
+ > ("make me a video about X") is **not** confirmation — it authorizes the pipeline, not the
36
+ > skipping of its review steps. Stopping to ask **is** the correct completion of this step.
37
+
25
38
  ## Render pipeline (this skill's part only)
26
39
 
27
40
  ```
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: web-record
3
3
  description: |
4
- 网页录屏 / 分镜视频技能(输出 webm),基于 Playwright Python,对任意 URL 落盘到本地。
4
+ 网页录屏 / 分镜视频技能(录制 webm,默认转码 mp4 + 抽封面 + 上传 VOD 并返回 CDN 地址),基于 Playwright Python
5
5
  支持:固定时长 / 条件触发(元素出现 / 消失)停止、自动滚动录屏(从头划到尾)、自定义分镜(storyboard)、参数化模板。
6
6
  分镜场景:高亮 / 聚焦 / 放大 / 滚动 / 虚拟光标点击 / 打字 / 悬停 / 字幕 / 标题卡 / 箭头 / 编号序列 / 打码 / 代码行高亮。
7
7
 
8
- 只出视频(.webm)。要静态截图(png/jpg)请用 web-capture / web_capture。
8
+ 只出视频。要静态截图(png/jpg)请用 web-screenshot / `web_screenshot`。
9
9
 
10
10
  当用户提到以下任何需求时,立即使用本 skill:
11
11
  - 录屏、网页录制、录制视频、录一段操作、生成 webm、screencast
@@ -23,39 +23,255 @@ triggers:
23
23
 
24
24
  # 网页录屏 / 分镜视频 Skill(web_record)
25
25
 
26
- 录屏入口,输出 **`.webm`**。底层复用 web-capture 的 `scripts/record.py` `_media_screenshot/` 包
27
- (本 skill 的 `entry.scriptPath` 相对指向 `../web-capture/scripts/record.py`)。静态截图请改用
28
- **web-capture / `web_capture`**。
26
+ 录屏入口。静态截图请改用 **web-screenshot / `web_screenshot`**。
29
27
 
30
- 完整的参数说明、storyboard 场景类型、模板列表与用法,见 **web-capture `SKILL.md`「录屏 `record.py`」章节**——本 skill 就是把那条录屏路径独立成一个工具,避免把 `.webm` 误喂给截图入口。
28
+ **脚本位置**:本 skill 没有自己的 `scripts/`,复用 web-screenshot 目录下的 `record.py`
29
+ `_media_screenshot/` 包(`skill.json` 的 `entry.scriptPath` 相对指向
30
+ `../web-screenshot/scripts/record.py`)。下文命令里的 **`<RecordScript>`** 一律替换为:
31
31
 
32
- ## 常见用法
32
+ ```
33
+ <SkillDir>/../web-screenshot/scripts/record.py
34
+ ```
35
+
36
+ > 路径约定:读取系统注入的 `Base directory for this skill: <path>` 作为 `<SkillDir>`,切勿硬编码绝对路径。`python` 在 macOS 上可能需写成 `python3`。
37
+
38
+ ## 前置依赖
39
+
40
+ - **Python 3.9+**
41
+ - **`playwright` pip 包 + chromium 内核**:首次运行**自动 bootstrap**(`pip install playwright` + `playwright install chromium`)。
42
+ - **ffmpeg**(可选):只在 `--no-upload` 的单机路径下用于裁掉开头加载段。默认的上传路径由 ab-render 在转码同一 pass 里裁,本机不需要 ffmpeg。
43
+
44
+ ## 输出与上传
45
+
46
+ 默认行为(**不是**只落一个 webm):录制 `.webm` → 交给 ab-render 转码 mp4 + 抽封面 → 上传 VOD → 打印可播放的 CDN 地址,并**删除本地 webm**(VOD 已持有)。
47
+
48
+ - `--no-upload`:跳过收尾,只保留本地 `.webm`(此时用本机 ffmpeg 尽力裁开头,缺 ffmpeg 则保留原片并提示)。
49
+ - `--keep-webm`:上传成功后仍保留本地 `.webm`。
50
+ - `--cover-at-sec`:封面抽帧时间点,默认 `0.5` 秒(避开首帧白屏)。
51
+ - `--vod-title`:VOD 资源标题,默认取输出文件名。
52
+
53
+ 需要 env **`PRIV_TOKEN`**(鉴权)与 **`REMOTION_RENDER_API_URL`**(ab-render 地址)。未设 `PRIV_TOKEN` 时自动降级为「仅本地文件」并在 stderr 提示;上传过程出错同样降级,不会丢掉已录好的文件。
54
+
55
+ ## 录屏用法
56
+
57
+ ### 固定时长录屏
58
+
59
+ ```bash
60
+ python3 <RecordScript> \
61
+ --url "https://example.com" \
62
+ --output "demo.webm" \
63
+ --viewport "1280,720" \
64
+ --duration 8000
65
+ ```
66
+
67
+ ### 等条件结束(推荐配合 max-duration 防卡死)
68
+
69
+ ```bash
70
+ # 等到 "加载完成" 元素出现就停
71
+ python3 <RecordScript> \
72
+ --url "https://example.com" \
73
+ --output "loaded.webm" \
74
+ --stop-when-selector "div.loaded" \
75
+ --max-duration 30000
76
+
77
+ # 等到 loading 转圈消失就停
78
+ python3 <RecordScript> \
79
+ --url "https://example.com" \
80
+ --output "spinner_done.webm" \
81
+ --stop-when-hidden ".spinner" \
82
+ --max-duration 30000
83
+ ```
84
+
85
+ ### 组合:先满足谁就停
86
+
87
+ ```bash
88
+ python3 <RecordScript> \
89
+ --url "https://example.com" \
90
+ --output "race.webm" \
91
+ --duration 15000 \
92
+ --stop-when-selector ".done" \
93
+ --max-duration 20000
94
+ ```
33
95
 
34
- 固定时长:
96
+ ### 录屏前等页面就绪
35
97
 
36
98
  ```bash
37
- python3 <SkillDir>/../web-capture/scripts/record.py \
38
- --url "https://example.com" --output "demo.webm" \
39
- --viewport "1280,720" --duration 8000
99
+ python3 <RecordScript> \
100
+ --url "https://app.example.com" \
101
+ --output "after_login.webm" \
102
+ --storage-state "./auth.json" \
103
+ --wait-for-selector "#dashboard" \
104
+ --duration 6000
40
105
  ```
41
106
 
42
- 自动滚动(从头划到尾):
107
+ ### 自动滚动录屏(从头划到尾)
43
108
 
44
109
  ```bash
45
- python3 <SkillDir>/../web-capture/scripts/record.py \
46
- --url "https://example.com" --output "scroll.webm" \
47
- --viewport "1440,900" --scroll-through \
48
- --scroll-pause-top 1000 --scroll-pause-bottom 1500
110
+ python3 <RecordScript> \
111
+ --url "https://example.com" \
112
+ --output "scroll.webm" \
113
+ --viewport "1440,900" \
114
+ --scroll-through \
115
+ --scroll-step 50 \
116
+ --scroll-interval 60 \
117
+ --scroll-pause-top 1000 \
118
+ --scroll-pause-bottom 1500
49
119
  ```
50
120
 
51
- 模板出片:
121
+ ### 模板视频(快捷出片)
122
+
123
+ `templates/` 下提供参数化的 storyboard 模板,常见结构一行命令出片:
52
124
 
53
125
  ```bash
54
- python3 <SkillDir>/../web-capture/scripts/record.py \
126
+ # 列出可用模板
127
+ python3 <RecordScript> --list-templates
128
+
129
+ # 用 github-repo-intro 模板录任意 GitHub 仓库
130
+ python3 <RecordScript> \
55
131
  --template github-repo-intro \
56
132
  --param repo_url=https://github.com/user/repo \
57
133
  --output repo.webm
58
134
  ```
59
135
 
60
- 至少需提供 `--duration` / `--stop-when-selector` / `--stop-when-hidden` / `--scroll-through`
61
- / `--storyboard` / `--template` 之一。模板 / storyboard JSON 可自带 `url`。
136
+ 可重复 `--param key=value` 覆盖模板里的默认值(标签文字、颜色、缩放倍数等)。模板内 `_meta.params` 声明可接收的参数。
137
+
138
+ **当前模板**:
139
+
140
+ | 名字 | 说明 | 必填参数 |
141
+ |------|------|---------|
142
+ | `github-repo-intro` | GitHub 仓库三连:项目名红框 → star 页面 zoom → README 滚动 | `repo_url` |
143
+ | `github-readme-tour` | 标题卡 → 项目名 → 光标 hover star → README 滚动 → 结尾呼吁 | `repo_url` |
144
+ | `github-code-tour` | 跳转到文件 → 高亮行范围 → 字幕讲解 | `file_url` / `start_line` / `end_line` |
145
+
146
+ **新增模板**:在 `<SkillDir>/../web-screenshot/templates/` 下放一个 JSON,按 storyboard 格式写场景,里面用 `{{var_name}}` 占位。可选加 `_meta.params` 声明参数(标 `required: true` / `default: ...`)。占位单独成串时会自动转 int/float/bool(如 `"scale": "{{zoom_scale}}"` 渲染后是数字)。
147
+
148
+ ### 自定义分镜(storyboard)
149
+
150
+ 把一系列「场景」组合成一段视频,场景间用 overlay 淡入淡出过渡(**不会黑屏**)。
151
+
152
+ ```bash
153
+ python3 <RecordScript> \
154
+ --url "https://github.com/user/repo" \
155
+ --output "story.webm" \
156
+ --viewport "1440,900" \
157
+ --storyboard story.json
158
+ ```
159
+
160
+ `story.json` 示例:
161
+
162
+ ```json
163
+ {
164
+ "url": "https://github.com/user/repo",
165
+ "viewport": [1440, 900],
166
+ "waitForReadySelectors": ["article.markdown-body"],
167
+ "settleMs": 1200,
168
+ "transition": { "fadeOutMs": 320, "gapMs": 180 },
169
+ "scenes": [
170
+ {
171
+ "type": "highlight",
172
+ "selector": "strong[itemprop=\"name\"] a",
173
+ "color": "#ff3b30",
174
+ "lineWidth": 5,
175
+ "padding": 10,
176
+ "label": "项目名称",
177
+ "duration": 3000
178
+ },
179
+ {
180
+ "type": "zoom",
181
+ "target": "page",
182
+ "selector": "#repo-stars-counter-star",
183
+ "scale": 2.4,
184
+ "rampInMs": 900,
185
+ "holdMs": 2200,
186
+ "rampOutMs": 700,
187
+ "label": "⭐ Star 数量"
188
+ },
189
+ {
190
+ "type": "scroll",
191
+ "fromSelector": "article.markdown-body",
192
+ "step": 50,
193
+ "interval": 70,
194
+ "duration": 10000,
195
+ "holdAtEnd": 800
196
+ }
197
+ ]
198
+ }
199
+ ```
200
+
201
+ **场景类型**:
202
+
203
+ *视觉强调*
204
+ - `highlight` — 元素红框 + 标签,`padding` / `lineWidth` / `color` / `duration`
205
+ - `focus` — 周围暗化(spotlight)+ 元素描边 + 标签
206
+ - `zoom` — 放大动画
207
+ - `target: "element"` (默认) — 缩放目标元素本身(弹性曲线)
208
+ - `target: "page"` — 像浏览器 zoom 一样整个页面以目标元素中心放大
209
+ - `scale` / `rampInMs` / `rampOutMs` / `holdMs` / `dim` / `label` / `color`
210
+ - `scroll` — 滚动到目标。`fromSelector` 起点、`toSelector` 终点、`step` / `interval` / `duration` / `holdAtEnd`
211
+ - `wait` — 单纯停顿 `duration`
212
+
213
+ *交互模拟(虚拟光标)*
214
+ - `click` — 光标飞向元素 → 涟漪 → 真实触发 `el.click()`。`moveMs` / `preHoldMs` / `postHoldMs` / `rippleMs` / `color` / `realClick`(默认 true,可设 false 只动画不点)
215
+ - `type` — 光标飞向输入框 → focus → 逐字打字。`text` / `delay`(ms/字) / `clearFirst` / `moveCursor`
216
+ - `hover` — 光标移到元素并触发原生 hover,常用于悬出 tooltip / hover card。`moveMs` / `holdMs`
217
+
218
+ *注释表达*
219
+ - `arrow` — 从一个锚点画 SVG 弧线箭头指向另一个锚点。锚点 `from` / `to` 形如 `{selector, side}`(side: center/left/right/top/bottom)或 `{x, y}`。`color` / `lineWidth` / `label` / `duration`
220
+ - `sequence` — 多个 selector 顺序出 ①②③ 圆形 badge + 红框 + 标签。`items: [{selector, label}, ...]` / `stepMs` 控制每步间隔 / `color` / `holdMs`
221
+ - `caption` — 顶部/底部滑入字幕条。`text` / `position: top|bottom` / `background` / `color` / `fontSize` / `duration`
222
+ - `title-card` — 全屏开场/结尾大标题卡。`title` / `subtitle`(可选) / `background` / `accent` / `duration`
223
+ - `redact` — 局部打码:blur / pixelate / 实色。`selectors: [...]` 或 `selector` / `mode: "blur" | "pixelate" | "solid"` / `color`(实色时) / `duration`
224
+
225
+ *GitHub 专属*
226
+ - `code-lines` — 高亮连续代码行范围(默认匹配新版 React blob `[data-line-number="{n}"]`;老版 blob 表格用 `linePattern: "#LC{n}"`)。`startLine` / `endLine` / `linePattern` / `color` / `label` / `duration`
227
+
228
+ **自动裁剪**:storyboard 模式录制时会等待页面真正稳定(networkidle + skeleton 消失),并在事后用 ffmpeg 帧精度裁掉开头加载段,最终视频长度 ≈ 各场景总时长。
229
+
230
+ ### 完整参数
231
+
232
+ | 参数 | 说明 | 默认 |
233
+ |------|------|------|
234
+ | `-u` / `--url` | 目标 URL(必填) | — |
235
+ | `-o` / `--output` | 本地输出 `.webm` 路径 | `recording.webm` |
236
+ | `-b` / `--browser` | `chromium` / `firefox` / `webkit`(建议 chromium) | `chromium` |
237
+ | `--device` | 设备模拟 | 无 |
238
+ | `--viewport` | `"宽,高"` | 无 |
239
+ | `--duration` | 固定录制时长(ms) | 无 |
240
+ | `--stop-when-selector` | 选择器出现就停 | 无 |
241
+ | `--stop-when-hidden` | 选择器消失就停 | 无 |
242
+ | `--max-duration` | 条件模式安全上限(ms) | 60000 |
243
+ | `--scroll-through` | 自动从顶部滚到底部 | 关 |
244
+ | `--scroll-step` | 每步像素 | 60 |
245
+ | `--scroll-interval` | 每步间隔(ms) | 50 |
246
+ | `--scroll-pause-top` | 顶部停留(ms) | 800 |
247
+ | `--scroll-pause-bottom` | 底部停留(ms) | 1200 |
248
+ | `--storyboard` | 分镜 JSON 文件路径 | 无 |
249
+ | `--template` | 模板名(templates/<name>.json);与 `--storyboard` 互斥 | 无 |
250
+ | `--param` | 模板参数 `key=value`,可重复 | 无 |
251
+ | `--list-templates` | 列出可用模板并退出 | — |
252
+ | `--wait-for-selector` | 开始录前等待出现 | 无 |
253
+ | `--wait-for-timeout` | 开始录前固定等待(ms) | 无 |
254
+ | `--color-scheme` | prefers-color-scheme | 无 |
255
+ | `--user-agent` | 覆盖 UA | 无 |
256
+ | `--timeout` | Playwright 全局超时(ms) | 无 |
257
+ | `--ignore-https-errors` | 忽略证书错误 | 关 |
258
+ | `--storage-state` | storageState JSON 文件 | 无 |
259
+ | `--cookies` | cookies JSON 字符串或文件 | 无 |
260
+ | `--no-upload` | 录完不上传,只保留本地 webm | 关(默认上传) |
261
+ | `--vod-title` | 上传到 VOD 的标题 | 输出文件名 |
262
+ | `--cover-at-sec` | 封面抽帧时间点(秒) | 0.5 |
263
+ | `--keep-webm` | 上传成功后保留本地 webm | 关(默认删除) |
264
+
265
+ 至少需提供 `--duration` / `--stop-when-selector` / `--stop-when-hidden` / `--scroll-through` / `--storyboard` / `--template` 之一;组合使用时**先满足谁就停**,同时受 `--max-duration` 兜底。模板 / storyboard JSON 可自带 `url`,此时可省略 `--url`。
266
+
267
+ ## 错误处理
268
+
269
+ - **首次跑慢**:脚本自动 `pip install playwright` + `playwright install chromium`,耐心等一次即可。
270
+ - **`ModuleNotFoundError: playwright`**:bootstrap 没装上,手动跑 `pip install playwright && playwright install chromium`。
271
+ - **`Executable doesn't exist`**:浏览器内核没装,跑 `playwright install chromium`。
272
+ - **`Timeout ... exceeded`**:拉大 `--timeout`、`--wait-for-timeout`,或换更稳的 `--wait-for-selector`。
273
+ - **录屏文件没产生**:检查 `--output` 后缀是否 `.webm`;查看 stderr 的 `stop reason`。
274
+ - **只拿到本地路径、没有 CDN 地址**:多半是没设 `PRIV_TOKEN`,或收尾失败降级了,stderr 里有原因。
275
+ - **storyboard 开头还有加载残影**:加大 `settleMs` / `waitForReadySelectors`;`--no-upload` 路径还需本机装 ffmpeg。
276
+ - **登录态失效**:重新导出 `storageState` 或更新 `cookies` JSON;`domain` / `path` 必须匹配。
277
+ - **HTTPS 证书报错**:测试环境可加 `--ignore-https-errors`。