@remixmate/cli 0.1.0 → 0.1.1

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 (122) hide show
  1. package/README.md +100 -83
  2. package/README.zh-CN.md +183 -0
  3. package/dist/handlers/gen-digital-human.d.ts +12 -0
  4. package/dist/handlers/gen-digital-human.js +157 -0
  5. package/dist/handlers/gen-image.js +5 -41
  6. package/dist/handlers/gen-video.d.ts +18 -0
  7. package/dist/handlers/gen-video.js +153 -0
  8. package/dist/handlers/gen-voice.js +2 -12
  9. package/dist/handlers/index.js +4 -2
  10. package/dist/handlers/shared.d.ts +26 -0
  11. package/dist/handlers/shared.js +66 -0
  12. package/dist/http.d.ts +4 -2
  13. package/dist/http.js +5 -3
  14. package/dist/manifest.json +27 -24
  15. package/dist/registry.d.ts +5 -16
  16. package/dist/registry.js +11 -17
  17. package/dist/skill-schema.d.ts +47 -0
  18. package/dist/skill-schema.js +49 -0
  19. package/package.json +5 -4
  20. package/skills/export-jianying/scripts/gen_jianying_draft.py +4 -4
  21. package/skills/gen-digital-human/SKILL.md +23 -46
  22. package/skills/gen-digital-human/skill.json +3 -2
  23. package/skills/gen-digital-human/version.json +1 -1
  24. package/skills/gen-image/SKILL.md +2 -2
  25. package/skills/gen-image/skill.json +2 -1
  26. package/skills/gen-image/version.json +1 -1
  27. package/skills/gen-script/SKILL.md +13 -13
  28. package/skills/gen-script/scripts/gen_script.py +11 -12
  29. package/skills/gen-video/SKILL.md +22 -33
  30. package/skills/gen-video/skill.json +3 -2
  31. package/skills/gen-video/version.json +1 -1
  32. package/skills/gen-voice/SKILL.md +1 -1
  33. package/skills/gen-voice/version.json +1 -1
  34. package/skills/prepare-video-assets/SKILL.md +2 -2
  35. package/skills/prepare-video-assets/skill.json +1 -1
  36. package/skills/render-video/scripts/render_video.py +8 -8
  37. package/skills/{template-bind → template-registry}/README.md +4 -4
  38. package/skills/{template-bind → template-registry}/SKILL.md +14 -12
  39. package/skills/template-registry/scripts/list_templates.py +129 -0
  40. package/skills/{template-bind → template-registry}/scripts/match_template.py +4 -3
  41. package/skills/{template-bind → template-registry}/scripts/registry_loader.py +1 -1
  42. package/skills/{template-bind → template-registry}/scripts/template_paths.py +7 -7
  43. package/skills/{template-bind → template-registry}/skill.json +6 -5
  44. package/skills/template-registry/version.json +7 -0
  45. package/skills/{template-bind → template-registry}/video_dsl/README.md +2 -2
  46. package/skills/{template-bind → template-registry}/video_dsl/runtime/__init__.py +1 -1
  47. package/skills/video-parser/SKILL.md +47 -160
  48. package/skills/video-parser/skill.json +3 -4
  49. package/skills/video-parser/version.json +1 -1
  50. package/skills/web-capture/SKILL.md +407 -116
  51. package/skills/web-capture/scripts/_media_screenshot/__init__.py +21 -0
  52. package/skills/web-capture/scripts/_media_screenshot/bootstrap.py +34 -0
  53. package/skills/web-capture/scripts/_media_screenshot/browser.py +86 -0
  54. package/skills/web-capture/scripts/_media_screenshot/cli_args.py +111 -0
  55. package/skills/web-capture/scripts/_media_screenshot/js/arrow.js +86 -0
  56. package/skills/web-capture/scripts/_media_screenshot/js/caption.js +27 -0
  57. package/skills/web-capture/scripts/_media_screenshot/js/clear_overlay.js +5 -0
  58. package/skills/web-capture/scripts/_media_screenshot/js/cursor_bootstrap.js +26 -0
  59. package/skills/web-capture/scripts/_media_screenshot/js/cursor_hide.js +6 -0
  60. package/skills/web-capture/scripts/_media_screenshot/js/cursor_move.js +12 -0
  61. package/skills/web-capture/scripts/_media_screenshot/js/cursor_ripple.js +25 -0
  62. package/skills/web-capture/scripts/_media_screenshot/js/element_zoom.js +72 -0
  63. package/skills/web-capture/scripts/_media_screenshot/js/element_zoom_restore.js +21 -0
  64. package/skills/web-capture/scripts/_media_screenshot/js/fade_out_overlays.js +10 -0
  65. package/skills/web-capture/scripts/_media_screenshot/js/focus.js +38 -0
  66. package/skills/web-capture/scripts/_media_screenshot/js/highlight.js +97 -0
  67. package/skills/web-capture/scripts/_media_screenshot/js/overlay_bootstrap.js +19 -0
  68. package/skills/web-capture/scripts/_media_screenshot/js/page_zoom_in.js +54 -0
  69. package/skills/web-capture/scripts/_media_screenshot/js/page_zoom_out.js +11 -0
  70. package/skills/web-capture/scripts/_media_screenshot/js/page_zoom_restore.js +13 -0
  71. package/skills/web-capture/scripts/_media_screenshot/js/redact.js +33 -0
  72. package/skills/web-capture/scripts/_media_screenshot/js/scroll.js +26 -0
  73. package/skills/web-capture/scripts/_media_screenshot/js/scroll_through.js +18 -0
  74. package/skills/web-capture/scripts/_media_screenshot/js/sequence.js +76 -0
  75. package/skills/web-capture/scripts/_media_screenshot/js/settled_check.js +15 -0
  76. package/skills/web-capture/scripts/_media_screenshot/js/title_card.js +71 -0
  77. package/skills/web-capture/scripts/_media_screenshot/js_loader.py +14 -0
  78. package/skills/web-capture/scripts/_media_screenshot/overlay.py +17 -0
  79. package/skills/web-capture/scripts/_media_screenshot/recording.py +100 -0
  80. package/skills/web-capture/scripts/_media_screenshot/scenes/__init__.py +39 -0
  81. package/skills/web-capture/scripts/_media_screenshot/scenes/arrow.py +50 -0
  82. package/skills/web-capture/scripts/_media_screenshot/scenes/caption.py +20 -0
  83. package/skills/web-capture/scripts/_media_screenshot/scenes/click.py +35 -0
  84. package/skills/web-capture/scripts/_media_screenshot/scenes/code_lines.py +54 -0
  85. package/skills/web-capture/scripts/_media_screenshot/scenes/focus.py +24 -0
  86. package/skills/web-capture/scripts/_media_screenshot/scenes/highlight.py +54 -0
  87. package/skills/web-capture/scripts/_media_screenshot/scenes/hover.py +28 -0
  88. package/skills/web-capture/scripts/_media_screenshot/scenes/redact.py +32 -0
  89. package/skills/web-capture/scripts/_media_screenshot/scenes/scroll.py +32 -0
  90. package/skills/web-capture/scripts/_media_screenshot/scenes/sequence.py +43 -0
  91. package/skills/web-capture/scripts/_media_screenshot/scenes/title_card.py +20 -0
  92. package/skills/web-capture/scripts/_media_screenshot/scenes/type.py +42 -0
  93. package/skills/web-capture/scripts/_media_screenshot/scenes/wait.py +9 -0
  94. package/skills/web-capture/scripts/_media_screenshot/scenes/zoom.py +72 -0
  95. package/skills/web-capture/scripts/_media_screenshot/screenshot.py +166 -0
  96. package/skills/web-capture/scripts/_media_screenshot/storyboard.py +88 -0
  97. package/skills/web-capture/scripts/_media_screenshot/template.py +119 -0
  98. package/skills/web-capture/scripts/_media_screenshot/trim.py +82 -0
  99. package/skills/web-capture/scripts/record.py +186 -0
  100. package/skills/web-capture/scripts/screenshot.py +94 -0
  101. package/skills/web-capture/skill.json +14 -14
  102. package/skills/web-capture/templates/github-code-tour.json +59 -0
  103. package/skills/web-capture/templates/github-readme-tour.json +77 -0
  104. package/skills/web-capture/templates/github-repo-intro.json +74 -0
  105. package/skills/web-capture/version.json +2 -2
  106. package/dist/handlers/template-bind.d.ts +0 -15
  107. package/dist/handlers/template-bind.js +0 -149
  108. package/skills/gen-digital-human/scripts/gen_digital_human_video.py +0 -574
  109. package/skills/gen-video/scripts/gen_video.py +0 -591
  110. package/skills/template-bind/version.json +0 -7
  111. package/skills/web-capture/scripts/web_capture.py +0 -461
  112. /package/skills/{template-bind → template-registry}/scripts/check_contracts.py +0 -0
  113. /package/skills/{template-bind → template-registry}/scripts/render_job_client.py +0 -0
  114. /package/skills/{template-bind → template-registry}/scripts/sync_registry.py +0 -0
  115. /package/skills/{template-bind → template-registry}/video_dsl/runtime/dsl_validator.py +0 -0
  116. /package/skills/{template-bind → template-registry}/video_dsl/runtime/prompt_enhancer.py +0 -0
  117. /package/skills/{template-bind → template-registry}/video_dsl/runtime/template_binder.py +0 -0
  118. /package/skills/{template-bind → template-registry}/video_dsl/runtime/timeline_compiler.py +0 -0
  119. /package/skills/{template-bind → template-registry}/video_dsl/schema/render-plan-v1alpha1.json +0 -0
  120. /package/skills/{template-bind → template-registry}/video_dsl/schema/template-binding-v1alpha1.json +0 -0
  121. /package/skills/{template-bind → template-registry}/video_dsl/schema/template-definition-v1alpha1.json +0 -0
  122. /package/skills/{template-bind → template-registry}/video_dsl/schema/video-dsl-v1alpha1.json +0 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Single source of truth for skill.json shape + validation.
3
+ *
4
+ * Imported directly by `registry.ts` (runtime loader) and — via the compiled
5
+ * `dist/skill-schema.js` — by `scripts/build-manifest.mjs` and `scripts/smoke.mjs`.
6
+ * Previously each of those reimplemented `normalizeEntry` and its own subset of
7
+ * field checks, so "valid at build" ≠ "loadable at runtime". Centralizing here
8
+ * means one definition of a well-formed skill.
9
+ *
10
+ * Error policy is the caller's choice: `validateSkillJson` returns a list of
11
+ * human-readable problems (empty = OK). The runtime loader skips + warns;
12
+ * the build treats them as fatal.
13
+ */
14
+ export type SkillEntry = {
15
+ type: 'python';
16
+ scriptPath: string;
17
+ } | {
18
+ type: 'http';
19
+ handler: string;
20
+ } | {
21
+ type: 'builtin';
22
+ handler: string;
23
+ };
24
+ export interface RawSkillJson {
25
+ name: string;
26
+ toolName: string;
27
+ description: string;
28
+ title?: string;
29
+ tier?: string;
30
+ parameters?: Record<string, unknown>;
31
+ scriptPath?: string;
32
+ entry?: SkillEntry;
33
+ envVars?: string[];
34
+ }
35
+ export declare const TIER_VALUES: readonly ["atomic", "orchestration", "tool"];
36
+ export declare const REQUIRED_SKILL_JSON_FIELDS: readonly ["name", "tier", "title", "description"];
37
+ /**
38
+ * Resolve the dispatcher entry. A missing `entry` falls back to the legacy
39
+ * top-level `scriptPath`, treated as `{ type: 'python', scriptPath }` so older
40
+ * skills keep working untouched. Returns null when neither is present.
41
+ */
42
+ export declare function normalizeEntry(raw: Pick<RawSkillJson, 'entry' | 'scriptPath'>): SkillEntry | null;
43
+ /**
44
+ * Validate a parsed skill.json against the directory it lives in. Returns an
45
+ * array of problem strings; an empty array means the record is well-formed.
46
+ */
47
+ export declare function validateSkillJson(raw: RawSkillJson, skillId: string): string[];
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Single source of truth for skill.json shape + validation.
3
+ *
4
+ * Imported directly by `registry.ts` (runtime loader) and — via the compiled
5
+ * `dist/skill-schema.js` — by `scripts/build-manifest.mjs` and `scripts/smoke.mjs`.
6
+ * Previously each of those reimplemented `normalizeEntry` and its own subset of
7
+ * field checks, so "valid at build" ≠ "loadable at runtime". Centralizing here
8
+ * means one definition of a well-formed skill.
9
+ *
10
+ * Error policy is the caller's choice: `validateSkillJson` returns a list of
11
+ * human-readable problems (empty = OK). The runtime loader skips + warns;
12
+ * the build treats them as fatal.
13
+ */
14
+ export const TIER_VALUES = ['atomic', 'orchestration', 'tool'];
15
+ export const REQUIRED_SKILL_JSON_FIELDS = ['name', 'tier', 'title', 'description'];
16
+ /**
17
+ * Resolve the dispatcher entry. A missing `entry` falls back to the legacy
18
+ * top-level `scriptPath`, treated as `{ type: 'python', scriptPath }` so older
19
+ * skills keep working untouched. Returns null when neither is present.
20
+ */
21
+ export function normalizeEntry(raw) {
22
+ if (raw.entry)
23
+ return raw.entry;
24
+ if (raw.scriptPath)
25
+ return { type: 'python', scriptPath: raw.scriptPath };
26
+ return null;
27
+ }
28
+ /**
29
+ * Validate a parsed skill.json against the directory it lives in. Returns an
30
+ * array of problem strings; an empty array means the record is well-formed.
31
+ */
32
+ export function validateSkillJson(raw, skillId) {
33
+ const errors = [];
34
+ for (const field of REQUIRED_SKILL_JSON_FIELDS) {
35
+ const value = raw[field];
36
+ if (value == null || value === '')
37
+ errors.push(`skill.json missing required field '${field}'`);
38
+ }
39
+ if (raw.tier != null && !TIER_VALUES.includes(raw.tier)) {
40
+ errors.push(`skill.json.tier must be one of ${TIER_VALUES.join(' | ')}, got '${raw.tier}'`);
41
+ }
42
+ if (raw.name && raw.name !== skillId) {
43
+ errors.push(`skill.json.name='${raw.name}' does not match directory name '${skillId}'`);
44
+ }
45
+ if (!normalizeEntry(raw)) {
46
+ errors.push("skill.json missing 'entry' (or legacy 'scriptPath')");
47
+ }
48
+ return errors;
49
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@remixmate/cli",
3
- "version": "0.1.0",
4
- "description": "AI media generation skills for Claude Code / Codex — 9 skills covering image, video, voice, digital human, script, template binding, rendering, Jianying export, and video deconstruction.",
3
+ "version": "0.1.1",
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.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -15,13 +15,14 @@
15
15
  "LICENSE"
16
16
  ],
17
17
  "scripts": {
18
- "build": "tsc && node scripts/build-manifest.mjs",
18
+ "build": "node scripts/clean-dist.mjs && tsc && node scripts/build-manifest.mjs",
19
19
  "prepare": "npm run build",
20
20
  "list": "node dist/cli.js --list",
21
21
  "smoke": "node scripts/smoke.mjs",
22
+ "test:cli": "npm run build && node --test test/*.test.mjs",
22
23
  "test:validators": "PYTHONDONTWRITEBYTECODE=1 python3 scripts/test-validators.py",
23
24
  "test:template-pipeline": "PYTHONDONTWRITEBYTECODE=1 python3 scripts/test-template-pipeline.py",
24
- "test:contracts": "PYTHONDONTWRITEBYTECODE=1 python3 skills/template-bind/scripts/check_contracts.py",
25
+ "test:contracts": "PYTHONDONTWRITEBYTECODE=1 python3 skills/template-registry/scripts/check_contracts.py",
25
26
  "clean": "node scripts/clean.mjs"
26
27
  },
27
28
  "keywords": [
@@ -986,13 +986,13 @@ Scene fields:
986
986
  if not PRIVATE_TOKEN:
987
987
  print("❌ --from-job-id mode requires PRIV_TOKEN", file=sys.stderr)
988
988
  sys.exit(1)
989
- # render_job_client lives in skills/template-bind/scripts/ — the
989
+ # render_job_client lives in skills/template-registry/scripts/ — the
990
990
  # shared location for cross-skill Python helpers (matches the pattern
991
991
  # render-video uses for the same import).
992
- _template_bind_scripts = os.path.join(
993
- os.path.dirname(__file__), "..", "..", "template-bind", "scripts"
992
+ _template_registry_scripts = os.path.join(
993
+ os.path.dirname(__file__), "..", "..", "template-registry", "scripts"
994
994
  )
995
- sys.path.insert(0, _template_bind_scripts)
995
+ sys.path.insert(0, _template_registry_scripts)
996
996
  from render_job_client import get_plan as rjc_get_plan
997
997
  try:
998
998
  render_plan_str = rjc_get_plan(args.from_job_id, PRIVATE_TOKEN)
@@ -19,7 +19,9 @@ triggers:
19
19
 
20
20
  # Digital-Human Skill
21
21
 
22
- Wraps ab-api's digital-human endpoints (the same ones the web studio uses), authenticated with the **Tianyan privateToken**. Two providers: **Jimeng** (image-driven) and **HiFly** (video-driven).
22
+ Wraps ab-api's digital-human endpoints (the same ones the web studio uses), authenticated with the **Tianyan privateToken**. Two providers: **Jimeng** (image-driven) and **HiFly** (video-driven). Generation is async — the handler submits the task and polls `/digital-human/video/status` until completion.
23
+
24
+ > 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_digital_human`, same params as in `skill.json`); local repro goes through `ab-skill gen-digital-human ...`.
23
25
 
24
26
  ## Capabilities
25
27
 
@@ -34,54 +36,52 @@ Wraps ab-api's digital-human endpoints (the same ones the web studio uses), auth
34
36
 
35
37
  ## Auth & environment
36
38
 
37
- No skill-local env file — the executing process inherits the system environment. Examples below say `python`; on macOS you may need `python3`.
39
+ No skill-local env file — the executing process inherits the system environment.
38
40
 
39
41
  - **Enterprise OpenClaw**: auth is already injected, **no need** for `PRIV_TOKEN` / `--priv-token`.
40
- - **Other environments**: configure the token. Without a token, non-interactive runs fail; interactive ones may prompt.
42
+ - **Other environments**: configure the token. Without a token, non-interactive runs fail.
41
43
 
42
44
  | Env var | Description | Default |
43
45
  |---------|-------------|---------|
44
46
  | `PRIV_TOKEN` | Tianyan token; `--priv-token` overrides | none |
45
- | `MM_API_BASE_URL` | API root | see `gen_digital_human_video.py` default |
47
+ | `MM_API_BASE_URL` | API root; `--api-base-url` overrides | `http://localhost:2999/api` |
46
48
  | `AGENT_NAME` | Optional `x-invoke-agent` header | none |
47
49
 
48
50
  ## Operations
49
51
 
50
- **Script path**: read the system-injected `Base directory for this skill: <path>` as `<SkillDir>`. Always use `<SkillDir>/scripts/gen_digital_human_video.py`. Do not hardcode paths.
52
+ By default only the URL is printed; generation is async and the handler polls until done (typically 1–5 minutes), emitting `__progress__` lines. The resulting video URL is cloud-persisted — show it directly, no download needed.
51
53
 
52
54
  ### 1. List avatars
53
55
 
54
56
  ```bash
55
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars
57
+ ab-skill gen-digital-human --list-avatars
56
58
  ```
57
59
 
58
60
  Optional filters:
59
61
 
60
62
  ```bash
61
63
  # Filter by source (jimeng = image-driven, hifly = video-driven)
62
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars --source jimeng
63
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars --source hifly
64
+ ab-skill gen-digital-human --list-avatars --source jimeng
65
+ ab-skill gen-digital-human --list-avatars --source hifly
64
66
 
65
67
  # Filter by gender
66
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars --gender female
68
+ ab-skill gen-digital-human --list-avatars --gender female
67
69
 
68
70
  # Show your custom avatars
69
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars --mine
71
+ ab-skill gen-digital-human --list-avatars --mine
70
72
 
71
73
  # Filter by name
72
- python3 <SkillDir>/scripts/gen_digital_human_video.py --list-avatars --name "alice"
74
+ ab-skill gen-digital-human --list-avatars --name "alice"
73
75
  ```
74
76
 
75
- > Custom avatars require `--mine`. When generating a video the script auto-falls back from the public list to `mine: true` if needed.
77
+ > Custom avatars require `--mine`. When generating a video the handler auto-falls back from the public list to `mine: true` if needed.
76
78
 
77
79
  ### 2. Generate a digital-human video
78
80
 
79
- By default only the URL is printed; pass `--download` (and optional `--output`) to save locally. Generation is async; the script polls until done (typically 1–5 minutes).
80
-
81
81
  #### TTS mode
82
82
 
83
83
  ```bash
84
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
84
+ ab-skill gen-digital-human \
85
85
  --avatar-id 7 \
86
86
  --text "Hi everyone, welcome to the live stream — today I'll introduce a new product." \
87
87
  --voice-id "male-qn-qingse"
@@ -90,7 +90,7 @@ python3 <SkillDir>/scripts/gen_digital_human_video.py \
90
90
  #### TTS + custom voice + aspect ratio
91
91
 
92
92
  ```bash
93
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
93
+ ab-skill gen-digital-human \
94
94
  --avatar-id 7 \
95
95
  --text "Hi class, here's our brand-new course." \
96
96
  --voice-id "female-shaonv" \
@@ -100,37 +100,19 @@ python3 <SkillDir>/scripts/gen_digital_human_video.py \
100
100
  #### Audio-driven mode
101
101
 
102
102
  ```bash
103
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
103
+ ab-skill gen-digital-human \
104
104
  --avatar-id 39 \
105
105
  --source hifly \
106
106
  --audio-url "https://example.com/voice.mp3" \
107
107
  --aspect-ratio "16:9"
108
108
  ```
109
109
 
110
- #### Download to disk
111
-
112
- ```bash
113
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
114
- --avatar-id 7 \
115
- --text "Hello world" \
116
- --download \
117
- --output "digital_human_output.mp4"
118
- ```
119
-
120
110
  ### 3. Check job status
121
111
 
122
112
  ```bash
123
- # Status only
124
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
125
- --check-status --generation-id 123
126
-
127
- # Download once it's done
128
- python3 <SkillDir>/scripts/gen_digital_human_video.py \
129
- --check-status --generation-id 123 --download --output result.mp4
113
+ ab-skill gen-digital-human --check-status --generation-id 123
130
114
  ```
131
115
 
132
- For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py --help`.
133
-
134
116
  ## Common CLI flags
135
117
 
136
118
  ### List avatars
@@ -155,11 +137,8 @@ For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py -
155
137
  | `--source` | `jimeng` / `hifly` (inferable from avatar) | auto |
156
138
  | `--aspect-ratio` | `9:16` / `16:9` / `3:4` / `1:1` | avatar's default |
157
139
  | `--prompt` | Action prompt (e.g. "more hand gestures") | none |
158
- | `--download` | Download the video locally | off |
159
- | `-o` / `--output` | Download path (only with `--download`) | `digital_human_video.mp4` |
160
- | `--poll-interval` | Polling interval (seconds) | `5` |
161
- | `--max-wait` | Max wait time (seconds) | `600` |
162
- | `--private-token` | Override token | see env vars |
140
+ | `--api-base-url` | Override API root | see env vars |
141
+ | `--priv-token` | Override token | see env vars |
163
142
 
164
143
  ### Check status
165
144
 
@@ -167,8 +146,6 @@ For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py -
167
146
  |------|-------------|---------|
168
147
  | `--check-status` | Enter status-check mode | — |
169
148
  | `--generation-id` | Job id (required) | — |
170
- | `--download` | Download when finished | off |
171
- | `-o` / `--output` | Download path | `digital_human_video.mp4` |
172
149
 
173
150
  ## Typical flows
174
151
 
@@ -180,7 +157,7 @@ For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py -
180
157
  3. Confirm or polish the speech text
181
158
  4. (Optional) pick a voice → use gen-voice --list-voices
182
159
  5. Generate → --avatar-id <id> --text "..." --voice-id "female-shaonv"
183
- 6. Show URL or local path
160
+ 6. Show URL
184
161
  ```
185
162
 
186
163
  ### Flow B — Audio-driven
@@ -189,7 +166,7 @@ For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py -
189
166
  1. List avatars → --list-avatars [--mine]
190
167
  2. Prepare an audio URL (gen-voice can produce one)
191
168
  3. Generate → --avatar-id <id> --audio-url "https://..." [--source hifly]
192
- 4. Show URL or local path
169
+ 4. Show URL
193
170
  ```
194
171
 
195
172
  ## Text guidance (TTS)
@@ -203,7 +180,7 @@ For the full flag list: `python3 <SkillDir>/scripts/gen_digital_human_video.py -
203
180
  - **401** / **token missing** (non-OpenClaw): set `PRIV_TOKEN`.
204
181
  - **Business `code != 0`**: read `msg` on stderr.
205
182
  - **429**: rate-limited; retry later.
206
- - **Generation timeout**: increase `--max-wait`, or use `--check-status` later.
183
+ - **Generation timeout**: the handler caps polling at ~10 minutes; use `--check-status --generation-id <id>` later.
207
184
  - **Empty TTS text**: provide non-empty `--text` or use `--audio-url`.
208
185
  - **Invalid voice id**: re-check via `gen-voice --list-voices`.
209
186
  - **Avatar id not found**: re-check via `--list-avatars` (or `--list-avatars --mine`).
@@ -5,7 +5,7 @@
5
5
  "title": "Digital-Human Talking-Head",
6
6
  "description": "Digital-human video: list available avatars; produce a talking-head video from text via TTS, or drive an avatar from an existing audio URL.",
7
7
  "envVars": ["PRIV_TOKEN", "MM_API_BASE_URL", "AGENT_NAME"],
8
- "scriptPath": "scripts/gen_digital_human_video.py",
8
+ "entry": { "type": "http", "handler": "gen-digital-human" },
9
9
  "parameters": {
10
10
  "type": "object",
11
11
  "properties": {
@@ -16,7 +16,8 @@
16
16
  "text": { "type": "string", "description": "Narration text (TTS mode)" },
17
17
  "audio_url": { "type": "string", "description": "Audio URL (audio-driven mode)" },
18
18
  "voice_id": { "type": "string", "description": "Voice id" },
19
- "aspect_ratio": { "type": "string", "description": "Aspect ratio" }
19
+ "aspect_ratio": { "type": "string", "description": "Aspect ratio" },
20
+ "json_output": { "type": "boolean", "description": "Emit a JSON result (generate: { url, generationId }; list: { avatars }; check-status: { status, url }) instead of human-readable output" }
20
21
  },
21
22
  "required": []
22
23
  }
@@ -2,6 +2,6 @@
2
2
  "skillName": "gen-digital-human",
3
3
  "repoName": "agent-skill-media-maker",
4
4
  "skillId": "336",
5
- "version": "V5",
5
+ "version": "V7",
6
6
  "skillDescription": "数字人口播视频技能,支持查询形象、TTS 口播、音频驱动口播和查询生成状态(调用 ab-api 数字人接口,即梦 / 飞影)。\n\n当用户提到以下任何需求时,立即使用本 skill:\n- 数字人、数字人视频、数字人口播、生成数字人视频\n- 用户提供已有音频 URL(MP3 等)、用外链音频驱动数字人口型\n- AI 主播、虚拟主播、虚拟人物视频、口播视频\n- 让数字人说话、让虚拟人说一段话、让 AI 人物播报\n- 查看/列出数字人形象、有哪些数字人可以用\n- 使用即梦/飞影数字人\n\n即使用户没有明确说「使用 AI」,只要他们想要让一个虚拟人物朗读/播报一段文字并生成视频,也要使用本 skill。"
7
7
  }
@@ -23,7 +23,7 @@ Wraps ab-api's `POST /model/genImg` (the same endpoint the web studio uses), aut
23
23
 
24
24
  ## Models and sizes
25
25
 
26
- Aligned with `gen_image.py`'s `GEN_IMG_MODEL_PRESETS` and the backend `ModelGenImgDTO`:
26
+ Aligned with the gen-image handler's model presets and the backend `ModelGenImgDTO`:
27
27
 
28
28
  | LiteLLM `model` | Display name | Provider |
29
29
  |-----------------|--------------|----------|
@@ -46,7 +46,7 @@ No skill-local env file — the executing process inherits the system environmen
46
46
  |---------|-------------|---------|
47
47
  | `PRIV_TOKEN` | Tianyan token; `--priv-token` overrides | none |
48
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 |
49
+ | `MM_API_BASE_URL` | API root; `--api-base-url` overrides | `http://localhost:2999/api` |
50
50
  | `AGENT_NAME` | Optional `x-invoke-agent` header | none |
51
51
 
52
52
  ## Operations
@@ -15,7 +15,8 @@
15
15
  "resolution": { "type": "string", "enum": ["1K", "2K", "4K"], "description": "Output resolution (Gemini only)" },
16
16
  "n": { "type": "number", "description": "Number of images, 1-4" },
17
17
  "reference": { "type": "string", "description": "Reference image path or URL" },
18
- "negative_prompt": { "type": "string", "description": "Negative prompt — content to avoid" }
18
+ "negative_prompt": { "type": "string", "description": "Negative prompt — content to avoid" },
19
+ "json_output": { "type": "boolean", "description": "Emit a JSON result ({ urls: [...] }) instead of human-readable output" }
19
20
  },
20
21
  "required": ["prompt"]
21
22
  }
@@ -2,6 +2,6 @@
2
2
  "skillName": "gen-image",
3
3
  "repoName": "agent-skill-media-maker",
4
4
  "skillId": "337",
5
- "version": "V6",
5
+ "version": "V8",
6
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
7
  }
@@ -28,11 +28,11 @@ Turns a user-supplied **topic** into a **Video DSL v1alpha1** JSON describing wh
28
28
 
29
29
  ## DSL schema
30
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`).
31
+ The full schema is `template-registry` skill's `video_dsl/schema/video-dsl-v1alpha1.json`; examples live in `video_dsl/schema/examples/` (locate them through `template-registry`'s `Base directory for this skill`).
32
32
 
33
33
  ## Agent behavior: DSL generation when a template is selected
34
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.**
35
+ **When the user explicitly specifies a template id, the agent must first read the existing `*.dsl.json` and `*.binding.json` examples in `template-registry`'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-registry` to force-match the template later.**
36
36
 
37
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
38
 
@@ -41,7 +41,7 @@ The intent is to reuse the validated example shapes already in the repo and to a
41
41
 
42
42
  ### Mandatory steps
43
43
 
44
- 1. Visit `template-bind/video_dsl/schema/examples/` and locate the closest existing `*.dsl.json` and `*.binding.json` for the requested template.
44
+ 1. Visit `template-registry/video_dsl/schema/examples/` and locate the closest existing `*.dsl.json` and `*.binding.json` for the requested template.
45
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
46
  3. Read the template's `template.json`.
47
47
  4. Combine the examples and `template.json` to understand the template's `slotMapping`, `requiredProps`, `optionalProps`, `propExtractors`, `assetRequirements`, `supportedAspectRatios`, and `scenePatterns`.
@@ -51,15 +51,15 @@ The intent is to reuse the validated example shapes already in the repo and to a
51
51
 
52
52
  ### Hard constraints
53
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/`.
54
+ - **Forbidden**: the user specified a template, but the agent generated the DSL without reading any of the existing examples under `template-registry/video_dsl/schema/examples/`.
55
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.
56
+ - **Forbidden**: the user specified a template, but the agent first generated a generic DSL and then passed `--template-id` to `template-registry` to force-bind it.
57
57
  - **Forbidden**: continuing into binding / rendering despite knowing that template-specific fields, scene shapes, or binding details are missing.
58
58
  - **Forbidden**: silently degrading to a generic DSL because the current script cannot support a template, leaving the failure to the downstream stage.
59
59
 
60
60
  ### When a template is not yet supported
61
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:
62
+ If `template-registry/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
63
 
64
64
  1. Ask the user to switch to a template that has an example and is already supported.
65
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.
@@ -67,7 +67,7 @@ If `template-bind/video_dsl/schema/examples/` has no matching example for the re
67
67
 
68
68
  ### Design principle
69
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`".
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-registry`".
71
71
 
72
72
  ## Authentication & environment
73
73
 
@@ -75,16 +75,16 @@ This skill does not hit any external API; no token required. The script only doe
75
75
 
76
76
  | Env var | Description | Default |
77
77
  |---------|-------------|---------|
78
- | `VIDEO_DSL_SCHEMA_PATH` | DSL schema file path. | Reads `template-bind` skill's `video_dsl/schema/video-dsl-v1alpha1.json` by default. |
78
+ | `VIDEO_DSL_SCHEMA_PATH` | DSL schema file path. | Reads `template-registry` skill's `video_dsl/schema/video-dsl-v1alpha1.json` by default. |
79
79
 
80
80
  ## Agent behavior: script confirmation
81
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.
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-registry / prepare-video-assets / render-video).** This lets the user review and adjust the scene structure, narration text, etc. before any asset is produced.
83
83
 
84
84
  ### Confirmation flow
85
85
 
86
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).
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).
88
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
89
 
90
90
  ### Summary content
@@ -174,7 +174,7 @@ Env vars `STUB_IMAGE_URL` / `STUB_VIDEO_URL` also work — their priority is low
174
174
 
175
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
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.
177
+ 3. **If the user specifies a template, read it first**: load the matching `template.json` via `template-registry` and confirm its template-specific fields and asset requirements. Do not skip this step.
178
178
  4. **Generate the DSL**: pick the right command or DSL shape for the target template (see the per-template commands below).
179
179
  5. **Schema validation**: make sure the output DSL conforms to v1alpha1.
180
180
  6. **User confirmation**: show the script summary and wait for confirmation, per the rules above.
@@ -208,7 +208,7 @@ python3 <SkillDir>/scripts/gen_script.py \
208
208
  --output output.dsl.json
209
209
  ```
210
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).
211
+ 5. **Result handling**: pass the generated DSL to `template-registry` for template lookup, or directly to `prepare-video-assets` (which auto-invokes template binding when `template_id` is provided).
212
212
 
213
213
  ## Common CLI flags
214
214
 
@@ -280,4 +280,4 @@ Mirrors the `gen-image` skill and `GEN_IMG_MODEL_PRESETS` in `gen_image.py`. **O
280
280
  | `knowledge_card_script.json` | Intermediate knowledge-card script result. |
281
281
  | `script_knowledge_card.json` | Full knowledge-card script example. |
282
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/`.
283
+ These JSON files are reference data for development / debugging; they do not participate in runtime logic. The authoritative DSL examples live under `template-registry/video_dsl/schema/examples/`.
@@ -12,7 +12,7 @@ Usage:
12
12
 
13
13
  Environment variables:
14
14
  VIDEO_DSL_SCHEMA_PATH - DSL schema file path
15
- (default: skills/template-bind/video_dsl/schema/video-dsl-v1alpha1.json)
15
+ (default: skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json)
16
16
  """
17
17
 
18
18
  import argparse
@@ -24,20 +24,19 @@ import uuid
24
24
 
25
25
  SCHEMA_PATH = os.environ.get(
26
26
  "VIDEO_DSL_SCHEMA_PATH",
27
- "skills/template-bind/video_dsl/schema/video-dsl-v1alpha1.json",
27
+ "skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json",
28
28
  )
29
29
 
30
30
  # prompt_enhancer 路径动态添加
31
- _TEMPLATE_DSL_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "template-bind", "video_dsl")
31
+ _TEMPLATE_DSL_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "template-registry", "video_dsl")
32
32
  if os.path.isdir(_TEMPLATE_DSL_DIR):
33
33
  sys.path.insert(0, os.path.abspath(os.path.join(_TEMPLATE_DSL_DIR, "..")))
34
34
 
35
- # Shared Python lib lives under skills/template-bind/scripts/ — the de-facto
36
- # cross-skill module location (registry_loader, template_paths, etc.). Named
37
- # generically here so its host skill could be renamed without touching every
38
- # caller. See AGENTS.md for the convention.
35
+ # Shared Python lib lives under skills/template-registry/scripts/ — the de-facto
36
+ # cross-skill module location (registry_loader, template_paths, etc.). See
37
+ # AGENTS.md for the convention.
39
38
  _SHARED_SCRIPTS_DIR = os.path.join(
40
- os.path.dirname(__file__), "..", "..", "template-bind", "scripts"
39
+ os.path.dirname(__file__), "..", "..", "template-registry", "scripts"
41
40
  )
42
41
  if os.path.isdir(_SHARED_SCRIPTS_DIR):
43
42
  sys.path.insert(0, os.path.abspath(_SHARED_SCRIPTS_DIR))
@@ -58,7 +57,7 @@ except ImportError:
58
57
  _HAS_REGISTRY_LOADER = False
59
58
 
60
59
  try:
61
- # Centralized monorepo-path resolver living in template-bind/scripts/;
60
+ # Centralized monorepo-path resolver living in template-registry/scripts/;
62
61
  # the import works because the same sys.path.insert above pointed at it.
63
62
  from template_paths import monorepo_template_src_dir as _monorepo_template_src_dir
64
63
  except ImportError:
@@ -326,7 +325,7 @@ def _load_template_config(template_id: str) -> dict | None:
326
325
  解析顺序(与 match_template / template_binder 保持一致):
327
326
  1. 通过 registry_loader 从 monorepo template-library/packages/metadata/registry.json
328
327
  (或 VIDEO_TEMPLATE_REGISTRY[_URL] 环境变量)加载,并按 templateId 匹配。
329
- 2. 兜底:旧路径 apps/ab-skill/skills/template-bind/video_dsl/templates/<id>/template.json
328
+ 2. 兜底:旧路径 template-registry/video_dsl/templates/<id>/template.json
330
329
  (仅在仓库还残留旧目录时使用)。
331
330
  返回完整 template dict(含 supportedAspectRatios / assetRequirements / slotMapping 等),
332
331
  找不到时返回 None。
@@ -343,7 +342,7 @@ def _load_template_config(template_id: str) -> dict | None:
343
342
 
344
343
  # 兜底:旧的本地目录布局
345
344
  legacy_dir = os.path.join(
346
- os.path.dirname(__file__), "..", "..", "template-bind", "video_dsl", "templates"
345
+ os.path.dirname(__file__), "..", "..", "template-registry", "video_dsl", "templates"
347
346
  )
348
347
  legacy_file = os.path.join(legacy_dir, template_id, "template.json")
349
348
  if os.path.isfile(legacy_file):
@@ -408,7 +407,7 @@ def _locate_template_dir(template_id: str) -> str | None:
408
407
  """定位模板源码目录(template-library/packages/templates/src/<id>/)。
409
408
 
410
409
  路径解析已集中到 ``template_paths.monorepo_template_src_dir``;
411
- 当 helper 不可用(template-bind/scripts/ 不在 sys.path)时回退到 None,
410
+ 当 helper 不可用(template-registry/scripts/ 不在 sys.path)时回退到 None,
412
411
  与原始函数"找不到就返回 None"的语义一致。
413
412
  """
414
413
  if _monorepo_template_src_dir is None: