@remixmate/cli 0.1.0

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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/dist/argv.d.ts +15 -0
  4. package/dist/argv.js +51 -0
  5. package/dist/cli.d.ts +13 -0
  6. package/dist/cli.js +83 -0
  7. package/dist/handlers/gen-image.d.ts +13 -0
  8. package/dist/handlers/gen-image.js +161 -0
  9. package/dist/handlers/gen-voice.d.ts +16 -0
  10. package/dist/handlers/gen-voice.js +110 -0
  11. package/dist/handlers/index.d.ts +13 -0
  12. package/dist/handlers/index.js +14 -0
  13. package/dist/handlers/template-bind.d.ts +15 -0
  14. package/dist/handlers/template-bind.js +149 -0
  15. package/dist/http.d.ts +52 -0
  16. package/dist/http.js +110 -0
  17. package/dist/index.d.ts +9 -0
  18. package/dist/index.js +8 -0
  19. package/dist/manifest.json +260 -0
  20. package/dist/progress.d.ts +23 -0
  21. package/dist/progress.js +15 -0
  22. package/dist/registry.d.ts +33 -0
  23. package/dist/registry.js +72 -0
  24. package/dist/runner.d.ts +17 -0
  25. package/dist/runner.js +63 -0
  26. package/package.json +54 -0
  27. package/skills/export-jianying/SKILL.md +251 -0
  28. package/skills/export-jianying/scripts/gen_jianying_draft.py +1099 -0
  29. package/skills/export-jianying/skill.json +24 -0
  30. package/skills/export-jianying/version.json +7 -0
  31. package/skills/gen-digital-human/SKILL.md +211 -0
  32. package/skills/gen-digital-human/scripts/gen_digital_human_video.py +574 -0
  33. package/skills/gen-digital-human/skill.json +23 -0
  34. package/skills/gen-digital-human/version.json +7 -0
  35. package/skills/gen-image/SKILL.md +130 -0
  36. package/skills/gen-image/skill.json +22 -0
  37. package/skills/gen-image/version.json +7 -0
  38. package/skills/gen-script/SKILL.md +283 -0
  39. package/skills/gen-script/scripts/gen_script.py +1208 -0
  40. package/skills/gen-script/skill.json +41 -0
  41. package/skills/gen-script/version.json +7 -0
  42. package/skills/gen-video/SKILL.md +170 -0
  43. package/skills/gen-video/scripts/gen_video.py +591 -0
  44. package/skills/gen-video/skill.json +24 -0
  45. package/skills/gen-video/version.json +7 -0
  46. package/skills/gen-voice/SKILL.md +104 -0
  47. package/skills/gen-voice/skill.json +21 -0
  48. package/skills/gen-voice/version.json +7 -0
  49. package/skills/prepare-video-assets/SKILL.md +192 -0
  50. package/skills/prepare-video-assets/scripts/prepare_video_assets.py +57 -0
  51. package/skills/prepare-video-assets/skill.json +23 -0
  52. package/skills/prepare-video-assets/version.json +7 -0
  53. package/skills/render-video/SKILL.md +187 -0
  54. package/skills/render-video/scripts/_chrome_vendor.py +305 -0
  55. package/skills/render-video/scripts/_video_probe.py +174 -0
  56. package/skills/render-video/scripts/_vod_polling.py +86 -0
  57. package/skills/render-video/scripts/remote_renderer_client.py +236 -0
  58. package/skills/render-video/scripts/render_video.py +2288 -0
  59. package/skills/render-video/scripts/upload_video.py +193 -0
  60. package/skills/render-video/skill.json +21 -0
  61. package/skills/render-video/version.json +7 -0
  62. package/skills/template-bind/README.md +63 -0
  63. package/skills/template-bind/SKILL.md +234 -0
  64. package/skills/template-bind/scripts/check_contracts.py +196 -0
  65. package/skills/template-bind/scripts/match_template.py +215 -0
  66. package/skills/template-bind/scripts/registry_loader.py +379 -0
  67. package/skills/template-bind/scripts/render_job_client.py +162 -0
  68. package/skills/template-bind/scripts/sync_registry.py +44 -0
  69. package/skills/template-bind/scripts/template_paths.py +72 -0
  70. package/skills/template-bind/skill.json +20 -0
  71. package/skills/template-bind/version.json +7 -0
  72. package/skills/template-bind/video_dsl/README.md +97 -0
  73. package/skills/template-bind/video_dsl/runtime/__init__.py +11 -0
  74. package/skills/template-bind/video_dsl/runtime/dsl_validator.py +495 -0
  75. package/skills/template-bind/video_dsl/runtime/prompt_enhancer.py +274 -0
  76. package/skills/template-bind/video_dsl/runtime/template_binder.py +87 -0
  77. package/skills/template-bind/video_dsl/runtime/timeline_compiler.py +312 -0
  78. package/skills/template-bind/video_dsl/schema/render-plan-v1alpha1.json +193 -0
  79. package/skills/template-bind/video_dsl/schema/template-binding-v1alpha1.json +122 -0
  80. package/skills/template-bind/video_dsl/schema/template-definition-v1alpha1.json +247 -0
  81. package/skills/template-bind/video_dsl/schema/video-dsl-v1alpha1.json +378 -0
  82. package/skills/video-parser/SKILL.md +238 -0
  83. package/skills/video-parser/scripts/analyze_video.py +1038 -0
  84. package/skills/video-parser/scripts/deconstruct_video.py +602 -0
  85. package/skills/video-parser/scripts/parse_via_render.py +148 -0
  86. package/skills/video-parser/skill.json +21 -0
  87. package/skills/video-parser/version.json +7 -0
  88. package/skills/web-capture/SKILL.md +183 -0
  89. package/skills/web-capture/scripts/web_capture.py +461 -0
  90. package/skills/web-capture/skill.json +29 -0
  91. package/skills/web-capture/version.json +7 -0
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: gen-image
3
+ description: |
4
+ AI image generation skill: produce an image from a text prompt, or do image-to-image with reference images. Backed by ab-api's `/model/genImg` (Seedream and Gemini families).
5
+
6
+ Use this skill immediately whenever the user asks for any of:
7
+ - AI image generation, text-to-image, "draw me ...", "generate an image of ..."
8
+ - Image-to-image, reference image, style transfer, image variation
9
+ - Generate an image with Doubao / Seedream / Gemini
10
+ - Provide a prompt and ask for an image
11
+
12
+ Even without an explicit "use AI", any request that turns a description into an image should route here.
13
+ triggers:
14
+ - AI image generation, text-to-image, "draw me ...", "generate an image of ..."
15
+ - Image-to-image, reference image, style transfer, image variation
16
+ - Generate an image with Doubao / Seedream / Gemini
17
+ - Provide a prompt and ask for an image
18
+ ---
19
+
20
+ # AI Image Generation Skill
21
+
22
+ Wraps ab-api's `POST /model/genImg` (the same endpoint the web studio uses), authenticated with the **Tianyan privateToken**, routed through LiteLLM to **Seedream** or **Gemini**.
23
+
24
+ ## Models and sizes
25
+
26
+ Aligned with `gen_image.py`'s `GEN_IMG_MODEL_PRESETS` and the backend `ModelGenImgDTO`:
27
+
28
+ | LiteLLM `model` | Display name | Provider |
29
+ |-----------------|--------------|----------|
30
+ | `doubao/doubao-seedream-4-5-251128` | Seedream 4.5 | Volcano |
31
+ | `doubao/doubao-seedream-5-0-260128` | Seedream 5.0 Lite | Volcano |
32
+ | `gemini-3-pro-image` | Gemini 3 Pro | Google |
33
+ | `gemini-3.1-flash-image-preview` | Gemini 3.1 Flash | Google |
34
+
35
+ - **Seedream**: `--size` is an aspect ratio (e.g. `1:1`, `9:16`) or `WxH`; the backend may auto-upscale the 4.5 model to meet a minimum pixel count.
36
+ - **Gemini**: `--size` is a backend-allowed aspect ratio (e.g. `1:1`, `16:9`); add `--resolution`: `1K` / `2K` / `4K` (default `1K`).
37
+
38
+ ## Auth & environment
39
+
40
+ No skill-local env file — the executing process inherits the system environment. Examples say `python`; on macOS you may need `python3`.
41
+
42
+ - **Enterprise OpenClaw**: auth is already injected, **no need** for `PRIV_TOKEN` / `--priv-token`.
43
+ - **Other environments**: configure the token. Without a token, non-interactive runs fail; interactive ones may prompt.
44
+
45
+ | Env var | Description | Default |
46
+ |---------|-------------|---------|
47
+ | `PRIV_TOKEN` | Tianyan token; `--priv-token` overrides | none |
48
+ | `MM_IMAGE_MODEL` | Default model id | `doubao/doubao-seedream-4-5-251128` |
49
+ | `MM_API_BASE_URL` | API root | see `gen_image.py` default |
50
+ | `AGENT_NAME` | Optional `x-invoke-agent` header | none |
51
+
52
+ ## Operations
53
+
54
+ > This skill was migrated from a Python script to an ab-skill CLI HTTP handler (`entry.type: http`). The agent invocation is unchanged (same tool name `gen_image`, same params as in `skill.json`); local repro goes through `ab-skill gen-image ...`.
55
+
56
+ 1. **Prompt**: be specific about subject, style, lighting, composition. Either English or Chinese works.
57
+ 2. By default only the URL is printed (good for showing to the user); the legacy local-download flag has been dropped — image URLs are persisted in the cloud.
58
+
59
+ ### Text-to-image
60
+
61
+ ```bash
62
+ ab-skill gen-image \
63
+ --prompt "<image description>" \
64
+ --size "9:16"
65
+ ```
66
+
67
+ ```bash
68
+ ab-skill gen-image \
69
+ --prompt "<image description>" \
70
+ --model gemini-3-pro-image \
71
+ --size "16:9" \
72
+ --resolution "2K"
73
+ ```
74
+
75
+ ### Image-to-image (reference image)
76
+
77
+ Reference images accept local file paths, HTTPS URLs, or data URIs. Pass `--reference` multiple times for multiple references.
78
+
79
+ - **Seedream**: up to **14** reference images, `--image-strength` controls reference influence.
80
+ - **Gemini**: up to **4** reference images.
81
+
82
+ ```bash
83
+ # URL reference
84
+ ab-skill gen-image \
85
+ --prompt "Convert this photo to an oil-painting style" \
86
+ --reference "https://example.com/photo.jpg"
87
+ ```
88
+
89
+ ```bash
90
+ # Local-file reference + reference strength
91
+ ab-skill gen-image \
92
+ --prompt "Match the style of this reference" \
93
+ --reference ./ref.png \
94
+ --image-strength 0.6
95
+ ```
96
+
97
+ ```bash
98
+ # Multiple references
99
+ ab-skill gen-image \
100
+ --prompt "Blend these styles" \
101
+ --reference ./a.png \
102
+ --reference ./b.png
103
+ ```
104
+
105
+ 3. **Surface results**: stdout prints one image URL per line; show them directly to the user.
106
+
107
+ ## Common CLI flags
108
+
109
+ | Flag | Description | Default |
110
+ |------|-------------|---------|
111
+ | `-p` / `--prompt` | Description (required) | — |
112
+ | `-m` / `--model` | Model id | see `MM_IMAGE_MODEL` |
113
+ | `-s` / `--size` | Seedream: ratio or WxH; Gemini: ratio | `1:1` |
114
+ | `--resolution` | Gemini only: `1K` / `2K` / `4K` | `1K` |
115
+ | `-n` | Number of images, 1–4 | `1` |
116
+ | `-g` / `--guidance-scale` | Guidance scale (when supported) | backend default |
117
+ | `--reference` | Reference image (repeatable; local path / URL / data URI) | none |
118
+ | `--image-strength` | Reference strength 0–1 (Seedream only) | backend default |
119
+ | `--negative-prompt` | Things to avoid | none |
120
+ | `--seed` | Random seed (reproducibility) | none |
121
+ | `--watermark` | Add a watermark (no `--no-watermark` opt-out) | backend default |
122
+ | `--api-base-url` | Override API root | see above |
123
+ | `--priv-token` | Override token | see above |
124
+
125
+ ## Error handling
126
+
127
+ - **401** / **token missing** (non-OpenClaw): set `PRIV_TOKEN`.
128
+ - **Business `code != 0`**: read `msg` on stderr.
129
+ - **429**: rate-limited; retry later.
130
+ - **Network**: verify connectivity and `MM_API_BASE_URL`.
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "gen-image",
3
+ "toolName": "gen_image",
4
+ "tier": "atomic",
5
+ "title": "AI Image Generation",
6
+ "description": "AI image generation: produce an image from a text prompt. Supports Seedream and Gemini models, plus image-to-image with reference images.",
7
+ "envVars": ["PRIV_TOKEN", "MM_API_BASE_URL", "AGENT_NAME", "MM_IMAGE_MODEL"],
8
+ "entry": { "type": "http", "handler": "gen-image" },
9
+ "parameters": {
10
+ "type": "object",
11
+ "properties": {
12
+ "prompt": { "type": "string", "description": "Image description (required)" },
13
+ "model": { "type": "string", "description": "Model id" },
14
+ "size": { "type": "string", "description": "Aspect ratio or WxH, e.g. 1:1, 9:16" },
15
+ "resolution": { "type": "string", "enum": ["1K", "2K", "4K"], "description": "Output resolution (Gemini only)" },
16
+ "n": { "type": "number", "description": "Number of images, 1-4" },
17
+ "reference": { "type": "string", "description": "Reference image path or URL" },
18
+ "negative_prompt": { "type": "string", "description": "Negative prompt — content to avoid" }
19
+ },
20
+ "required": ["prompt"]
21
+ }
22
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "skillName": "gen-image",
3
+ "repoName": "agent-skill-media-maker",
4
+ "skillId": "337",
5
+ "version": "V6",
6
+ "skillDescription": "AI 生图技能,根据文字描述生成图片,也支持参考图进行图生图(调用 ab-api /model/genImg,支持 Seedream 与 Gemini)。\n\n当用户提到以下任何需求时,立即使用本 skill:\n- AI 生图、AI 画图、文生图、文字生成图片、生成图像、帮我画、生成一张图\n- 图生图、以图生图、参考图、风格迁移、图片变体\n- 使用 doubao / 豆包 / seedream、Gemini 等生成图片\n- 用户提供图片提示词并希望生成图片\n\n即使用户没有明确说「使用 AI」,只要他们想要根据描述生成图片,也要使用本 skill。"
7
+ }
@@ -0,0 +1,283 @@
1
+ ---
2
+ name: gen-script
3
+ description: |
4
+ Video-script generation skill. Turns a user-supplied topic into a structured Video DSL (JSON) that describes the full video — scene structure, asset requirements, and narrative flow.
5
+
6
+ Use this skill as soon as the user mentions any of these intents:
7
+ - Write a video script, generate a video script, plan a video, write storyboards
8
+ - Create a short video, plan video content, generate a Video DSL
9
+ - Turn a topic into a video structure / video content plan
10
+
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
+ triggers:
13
+ - Write a video script, generate a video script, plan a video, write storyboards
14
+ - Create a short video, plan video content, generate a Video DSL
15
+ - Turn a topic into a video structure / video content plan
16
+ ---
17
+
18
+ # Video Script Generation Skill
19
+
20
+ 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
+
22
+ ## Core concepts
23
+
24
+ - **Video DSL**: a declarative description language for videos — describes the final structure, not the orchestration calls.
25
+ - **AssetRef**: an asset reference declaring which images / audio / video clips are needed; the downstream Render Skill is responsible for producing them.
26
+ - **Scene**: the unit cell of the video timeline.
27
+ - **Image `payload.model`**: must match the `gen-image` skill and the backend `ModelGenImgDTO`. **Only** values from the LiteLLM `model` allowlist below may be used. When editing narration or prompts you **must not** rewrite this field.
28
+
29
+ ## DSL schema
30
+
31
+ The full schema is `template-bind` skill's `video_dsl/schema/video-dsl-v1alpha1.json`; examples live in `video_dsl/schema/examples/` (locate them through `template-bind`'s `Base directory for this skill`).
32
+
33
+ ## Agent behavior: DSL generation when a template is selected
34
+
35
+ **When the user explicitly specifies a template id, the agent must first read the existing `*.dsl.json` and `*.binding.json` examples in `template-bind`'s `video_dsl/schema/examples/`, then generate the DSL in the template's native shape using both those examples and the template's `template.json`. The agent must not generate the DSL from scratch ignoring the examples, and must not produce a generic DSL first and rely on `template-bind` to force-match the template later.**
36
+
37
+ The intent is to reuse the validated example shapes already in the repo and to avoid the failure mode where "the generic DSL looks compatible on the surface, but is missing template-specific fields, has the wrong nesting, or binds incorrectly — only to fail later at binding or render time". Examples:
38
+
39
+ - `html-slide` depends on `scene.templateData.slideId`.
40
+ - Different templates' `binding.json` may reflect different `slotMapping` choices, asset-binding styles, and scene organization.
41
+
42
+ ### Mandatory steps
43
+
44
+ 1. Visit `template-bind/video_dsl/schema/examples/` and locate the closest existing `*.dsl.json` and `*.binding.json` for the requested template.
45
+ 2. Read those examples and understand the actual DSL shape, the `templateData` fields, the scene organization, and the binding style the template uses.
46
+ 3. Read the template's `template.json`.
47
+ 4. Combine the examples and `template.json` to understand the template's `slotMapping`, `requiredProps`, `optionalProps`, `propExtractors`, `assetRequirements`, `supportedAspectRatios`, and `scenePatterns`.
48
+ 5. Generate the DSL using the example's shape and the template's native requirements — not the generic DSL shape.
49
+ 6. Make sure the DSL explicitly contains every template-specific field, e.g. `templateData.words`, `templateData.slideId`, `visuals.avatar.assetRef`.
50
+ 7. After generation, run the schema check and show the script summary to the user for confirmation.
51
+
52
+ ### Hard constraints
53
+
54
+ - **Forbidden**: the user specified a template, but the agent generated the DSL without reading any of the existing examples under `template-bind/video_dsl/schema/examples/`.
55
+ - **Forbidden**: only reading `template.json` while ignoring the existing `*.dsl.json` and `*.binding.json` examples.
56
+ - **Forbidden**: the user specified a template, but the agent first generated a generic DSL and then passed `--template-id` to `template-bind` to force-bind it.
57
+ - **Forbidden**: continuing into binding / rendering despite knowing that template-specific fields, scene shapes, or binding details are missing.
58
+ - **Forbidden**: silently degrading to a generic DSL because the current script cannot support a template, leaving the failure to the downstream stage.
59
+
60
+ ### When a template is not yet supported
61
+
62
+ If `template-bind/video_dsl/schema/examples/` has no matching example for the requested template, or `gen_script.py` cannot yet build the required DSL shape, the agent must clearly tell the user "this template is not yet supported for auto-generation from existing examples" and explain what key fields, structure, or binding info are missing. Possible next steps:
63
+
64
+ 1. Ask the user to switch to a template that has an example and is already supported.
65
+ 2. Have the agent take the closest `*.dsl.json` / `*.binding.json` as a reference and hand-craft the required DSL structure for this template, then show it to the user for confirmation.
66
+ 3. Stop the flow and wait for the user to decide, rather than emitting a DSL that "looks like it matches but cannot render".
67
+
68
+ ### Design principle
69
+
70
+ When the user specifies a template, `gen-script`'s goal is no longer "produce a generally-compatible DSL" but "produce a template-native DSL based on the existing examples in `template-bind`".
71
+
72
+ ## Authentication & environment
73
+
74
+ This skill does not hit any external API; no token required. The script only does local DSL generation and schema validation.
75
+
76
+ | Env var | Description | Default |
77
+ |---------|-------------|---------|
78
+ | `VIDEO_DSL_SCHEMA_PATH` | DSL schema file path. | Reads `template-bind` skill's `video_dsl/schema/video-dsl-v1alpha1.json` by default. |
79
+
80
+ ## Agent behavior: script confirmation
81
+
82
+ **After the agent has generated a DSL it must first show the script summary to the user and get explicit confirmation before forwarding to downstream skills (template-bind / prepare-video-assets / render-video).** This lets the user review and adjust the scene structure, narration text, etc. before any asset is produced.
83
+
84
+ ### Confirmation flow
85
+
86
+ 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-bind` for a list-only lookup).
88
+ 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
+
90
+ ### Summary content
91
+
92
+ The agent should show the following in clear Markdown:
93
+
94
+ **1. Scene structure**
95
+ - Each scene's purpose, duration, and full narration text.
96
+
97
+ **2. Asset plan**
98
+ - Count by type (images, TTS, video, digital human).
99
+ - Key descriptions per asset (e.g. an image prompt summary).
100
+
101
+ **3. Estimated total duration**
102
+ - Sum of per-scene durations.
103
+
104
+ ### Summary format example
105
+
106
+ ```markdown
107
+ ## Script confirmation
108
+
109
+ ### Video info
110
+ - Topic: 3 AI study hacks
111
+ - Platform: douyin | Aspect ratio: 9:16 | Estimated duration: 45s
112
+
113
+ ### Scene structure
114
+ | # | Purpose | Duration | Narration |
115
+ |---|---------|----------|-----------|
116
+ | 1 | opening | 5s | Spending hours studying with no real progress? |
117
+ | 2 | point | 10s | Hack 1: Feynman + AI — explain a concept in your own words... |
118
+ | 3 | point | 10s | Hack 2: spaced repetition with AI — schedule reviews scientifically... |
119
+ | 4 | point | 10s | Hack 3: AI mock exam — close gaps anytime, anywhere... |
120
+ | 5 | cta | 10s | If this helped, like and follow for more AI study tips! |
121
+
122
+ ### Asset plan
123
+ - Images: 5 (one background per scene)
124
+ - TTS: 5 segments (one per scene narration)
125
+
126
+ > Reply "continue" to proceed to template matching, or tell me what to change.
127
+ ```
128
+
129
+ ## Test mode: skip asset generation (`--stub-image-url` / `--stub-video-url`)
130
+
131
+ **Purpose**: during dev / debug the user wants to exercise the whole pipeline without burning gen-image / gen-video quota. In the DSL this becomes: image / video AssetRefs are written as `source:"existing"` + `status:"generated"` + `url:<stub>`, no `payload.prompt`; the downstream `prepare-video-assets` resolver skips the matching atomic skill.
132
+
133
+ ### When the agent must add the flag
134
+
135
+ If the user expresses any of "test", "don't actually generate images / videos", "use a unified image / placeholder / stub URL", "save credits", the agent **must** add the corresponding flag to the `gen_script.py` invocation:
136
+
137
+ - Image-related intent → add `--stub-image-url <URL>`.
138
+ - Video-related intent → add `--stub-video-url <URL>`.
139
+ - Both → add both.
140
+
141
+ Typical phrasings (non-exhaustive):
142
+ - "Just testing — don't really generate images, use this URL: <URL>"
143
+ - "Use <URL> for every image"
144
+ - "Don't burn money on images — placeholder is fine: <URL>"
145
+ - "Use this stub for video assets first: <URL>"
146
+
147
+ ### Usage rules
148
+
149
+ - The URL is passed **verbatim**; do not rewrite the host, path, or query.
150
+ - If the user expressed the intent but did not supply a URL, the agent must ask which fallback URL to use — never invent one or recycle one from history.
151
+ - Narration audio (`gen-voice`) is unaffected; TTS still runs so the script stays audible.
152
+ - If the user does not re-state test mode in the next turn, the agent **must not** carry the previous stub URL forward — default back to real generation.
153
+
154
+ ### Command examples
155
+
156
+ ```bash
157
+ python3 <SkillDir>/scripts/gen_script.py \
158
+ --topic "English picture-book story" \
159
+ --template-id picture-book-en \
160
+ --stub-image-url "https://cdn.example.com/placeholder.jpg"
161
+ ```
162
+
163
+ ```bash
164
+ python3 <SkillDir>/scripts/gen_script.py \
165
+ --topic "GitHub project tour" \
166
+ --template-id screen-walkthrough \
167
+ --stub-image-url "https://cdn.example.com/img.jpg" \
168
+ --stub-video-url "https://cdn.example.com/demo.mp4"
169
+ ```
170
+
171
+ Env vars `STUB_IMAGE_URL` / `STUB_VIDEO_URL` also work — their priority is lower than the CLI flag.
172
+
173
+ ## Steps
174
+
175
+ 1. **Script path**: read the system-injected `Base directory for this skill: <path>` as `<SkillDir>`. Every command below uses `<SkillDir>/scripts/gen_script.py`; never hard-code paths.
176
+ 2. **Understand the request**: extract topic, target platform, duration, style, audience, etc.
177
+ 3. **If the user specifies a template, read it first**: load the matching `template.json` via `template-bind` and confirm its template-specific fields and asset requirements. Do not skip this step.
178
+ 4. **Generate the DSL**: pick the right command or DSL shape for the target template (see the per-template commands below).
179
+ 5. **Schema validation**: make sure the output DSL conforms to v1alpha1.
180
+ 6. **User confirmation**: show the script summary and wait for confirmation, per the rules above.
181
+
182
+ ### Generic-template DSL (image-slide / knowledge-slides, etc.)
183
+
184
+ ```bash
185
+ python3 <SkillDir>/scripts/gen_script.py \
186
+ --topic "3 AI hacks that double your study efficiency" \
187
+ --platform douyin \
188
+ --duration 30 \
189
+ --style "tech" \
190
+ --ratio "9:16"
191
+ ```
192
+
193
+ ### Validate an existing DSL via the CLI
194
+
195
+ ```bash
196
+ python3 <SkillDir>/scripts/gen_script.py \
197
+ --validate \
198
+ --input my-video.dsl.json
199
+ ```
200
+
201
+ ### Write to a file (debug only — the normal flow does not need this)
202
+
203
+ > ⚠️ In the normal agent flow, gen_script writes the DSL JSON to stdout and the agent reads it directly from the tool return value — **no `write_file` and no `--output` is needed**. Only use this when debugging locally:
204
+
205
+ ```bash
206
+ python3 <SkillDir>/scripts/gen_script.py \
207
+ --topic "How to code with AI" \
208
+ --output output.dsl.json
209
+ ```
210
+
211
+ 5. **Result handling**: pass the generated DSL to `template-bind` for template lookup, or directly to `prepare-video-assets` (which auto-invokes template binding when `template_id` is provided).
212
+
213
+ ## Common CLI flags
214
+
215
+ | Flag | Description | Default |
216
+ |------|-------------|---------|
217
+ | `--topic` | Video topic (required unless `--validate`). | — |
218
+ | `--platform` | Target platform: `douyin` / `xiaohongshu` / `bilibili` / `wechat` / `youtube` / `generic`. | `generic` |
219
+ | `--duration` | Target duration (seconds). | `30` |
220
+ | `--style` | Style tag. | — |
221
+ | `--ratio` | Aspect ratio. | `16:9` |
222
+ | `--scenes` | Scene count. | auto-planned |
223
+ | `--voice-id` | Narration voice id. | resolved from template + language fallback |
224
+ | `--allow-digital-human` | Whether to allow digital-human assets. | off |
225
+ | `--allow-ai-video` | Whether to allow AI-generated video assets. | off |
226
+ | `--validate` | Validate-only mode: only validate the input DSL. | — |
227
+ | `--input` | Input DSL file path (required in validate mode). | — |
228
+ | `-o` / `--output` | Output DSL file path. | stdout |
229
+ | `--stub-image-url` | Test mode: every image AssetRef is written as existing + generated + this URL, no prompt (env: `STUB_IMAGE_URL`). | — |
230
+ | `--stub-video-url` | Test mode: every video AssetRef is written as existing + generated + this URL, no prompt (env: `STUB_VIDEO_URL`). | — |
231
+
232
+ ## DSL generation principles
233
+
234
+ Apply the following principles when producing the DSL:
235
+
236
+ 1. **Narrative-first**: opening hook → point expansion → CTA close.
237
+ 2. **Assets are declared, not executed**: every asset starts as `AssetRef` with `status: planned`; no generation API call from this skill.
238
+ 3. **Narration drives duration**: each scene's duration should match its narration reading time (≈ 3–4 zh chars/sec, or ~2 words/sec for English).
239
+ 4. **Segment narration at subtitle granularity**: separate segments inside `audio.narration.text` with `\n`; each segment is 10–16 Chinese characters (or an equivalent number of English words). TTS returns per-line timestamps split on `\n`; the renderer uses them directly as subtitle cut points. Segments longer than 18 characters wrap awkwardly on screen; segments shorter than 6 flicker. Example:
240
+ ```
241
+ "text": "Alibaba's open-source AI video-editing project\nalready has 4.3k stars on GitHub"
242
+ ```
243
+ instead of one continuous paragraph.
244
+ 4. **Moderate scene count**: 30-second videos work well with 4–6 scenes, 60-second videos with 6–10.
245
+ 5. **Leave room for templates**: pick generic layouts; do not assume a specific template implementation.
246
+ 6. **Image model allowlist**: every `type: image` + `source: gen-image` `AssetRef`'s `payload.model` **must** be one of the values in the table below. **Never** use display names, short forms, or made-up ids (e.g. `seedream`, `gemini-flash`, etc.).
247
+
248
+ ### Allowlist `model` values aligned with gen-image
249
+
250
+ Mirrors the `gen-image` skill and `GEN_IMG_MODEL_PRESETS` in `gen_image.py`. **Only** the following four values are allowed (copy verbatim, including prefix and version):
251
+
252
+ | LiteLLM `model` | Display name | Provider |
253
+ |-----------------|--------------|----------|
254
+ | `doubao/doubao-seedream-4-5-251128` | Seedream 4.5 | Volcano |
255
+ | `doubao/doubao-seedream-5-0-260128` | Seedream 5.0 Lite | Volcano |
256
+ | `gemini-3-pro-image` | Gemini 3 Pro | Google |
257
+ | `gemini-3.1-flash-image-preview` | Gemini 3.1 Flash | Google |
258
+
259
+ **Agent behavior (avoid accidentally rewriting `model`)**:
260
+
261
+ - `gen_script.py` already writes a valid `payload.model` (currently `gemini-3.1-flash-image-preview` by default). When the user only asks to refine narration, change `payload.prompt`, add or remove scenes, etc. and does **not** ask to change the image model, the agent **must keep** each image asset's original `payload.model` — do not replace it under the guise of "polishing the script".
262
+ - **Only when the user explicitly asks to change the image model** (e.g. switches to Seedream or a different Gemini), update the corresponding image `AssetRef`'s `payload.model` to the matching row id from the table. Writing a display name into JSON is wrong.
263
+ - When creating a new image `AssetRef`, pick one of the values above for `payload.model`; default to `gemini-3.1-flash-image-preview` to match the script, or to whichever value the user specified.
264
+
265
+ ## Error handling
266
+
267
+ - **Schema validation failed**: check the DSL JSON shape and required fields against the schema.
268
+ - **Scene duration mismatch**: adjust the narration length or the scene duration.
269
+ - **Invalid platform**: look at the supported-platform list.
270
+
271
+ ## scripts/ contents
272
+
273
+ | File | Purpose |
274
+ |------|---------|
275
+ | `gen_script.py` | Core script — produces the Video DSL JSON from a topic. |
276
+ | `dsl.json` | DSL example produced from the generic template (debug reference). |
277
+ | `script.json` | Intermediate script-generation result (example). |
278
+ | `html_slide.json` | DSL example for the html-slide template. |
279
+ | `knowledge_card_dsl.json` | DSL example for the knowledge-card scene. |
280
+ | `knowledge_card_script.json` | Intermediate knowledge-card script result. |
281
+ | `script_knowledge_card.json` | Full knowledge-card script example. |
282
+
283
+ These JSON files are reference data for development / debugging; they do not participate in runtime logic. The authoritative DSL examples live under `template-bind/video_dsl/schema/examples/`.