@remixmate/cli 0.9.53 → 0.9.54
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.
- package/dist/manifest.json +2 -2
- package/package.json +1 -1
- package/skills/prepare-video-assets/version.json +1 -1
- package/skills/render-video/scripts/render_video.py +26 -0
- package/skills/render-video/version.json +1 -1
- package/skills/template-registry/SKILL.md +1 -0
- package/skills/template-registry/version.json +1 -1
- package/skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json +3 -0
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remixmate/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.54",
|
|
4
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",
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"skillName": "prepare-video-assets",
|
|
3
3
|
"repoName": "agent-skill-media-maker",
|
|
4
4
|
"skillId": "476",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "V5",
|
|
6
6
|
"skillDescription": "Asset-preparation skill: resolves and generates every asset (image / audio / video) referenced by a Video DSL, persists a RenderPlan to the database, and returns a `job_id` for the subsequent `render_video` call.\n\nUse this skill as soon as the user mentions any of these intents:\n- Generate / prepare video assets, resolve assets, render-ready\n- \"Make me a video about X\" (the agent calls gen_script → prepare_video_assets → render_video)\n- Regenerate one asset (image / audio) for a specific scene\n\nNext step: after the user confirms the resolved assets, call `render_video` with the `job_id` returned by this skill.\n\n⚠️ 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."
|
|
7
7
|
}
|
|
@@ -196,6 +196,23 @@ def _narration_language_boost(narration: dict) -> Optional[str]:
|
|
|
196
196
|
return raw.strip()
|
|
197
197
|
|
|
198
198
|
|
|
199
|
+
def _narration_voice(narration: dict) -> Optional[str]:
|
|
200
|
+
"""Read a narration block's voice id, or None when unset.
|
|
201
|
+
|
|
202
|
+
Same tolerance as _narration_speed. Exists because the voice used to be read
|
|
203
|
+
only from the audio asset's payload.voiceId — which gen_script bakes once
|
|
204
|
+
when it drafts the skeleton — so changing global.narration.voiceId (or a
|
|
205
|
+
scene's voice) after that never reached TTS: the video kept the original
|
|
206
|
+
voice while every other layer reported the new one (2026-09-28).
|
|
207
|
+
"""
|
|
208
|
+
if not isinstance(narration, dict):
|
|
209
|
+
return None
|
|
210
|
+
raw = narration.get("voiceId")
|
|
211
|
+
if not isinstance(raw, str) or not raw.strip():
|
|
212
|
+
return None
|
|
213
|
+
return raw.strip()
|
|
214
|
+
|
|
215
|
+
|
|
199
216
|
def extract_narration_lines(narration: dict) -> Optional[tuple[list[str], int, list[Optional[float]]]]:
|
|
200
217
|
"""If narration uses the structured {intro, items, outro} form, return
|
|
201
218
|
(lines, intro_line_count, at_sec_list). `at_sec_list` is parallel to
|
|
@@ -783,6 +800,7 @@ def build_render_plan(dsl: dict, binding: dict) -> dict:
|
|
|
783
800
|
global_narration = (dsl.get("global") or {}).get("narration") or {}
|
|
784
801
|
global_speed = _narration_speed(global_narration)
|
|
785
802
|
global_language_boost = _narration_language_boost(global_narration)
|
|
803
|
+
global_voice = _narration_voice(global_narration)
|
|
786
804
|
for scene in dsl.get("scenes", []):
|
|
787
805
|
narration = (scene.get("audio") or {}).get("narration") or {}
|
|
788
806
|
ref = narration.get("assetRef")
|
|
@@ -790,6 +808,14 @@ def build_render_plan(dsl: dict, binding: dict) -> dict:
|
|
|
790
808
|
if not asset:
|
|
791
809
|
continue
|
|
792
810
|
payload = asset.setdefault("payload", {})
|
|
811
|
+
# Voice follows the same precedence as speed: scene narration.voiceId >
|
|
812
|
+
# global.narration.voiceId. The asset's own payload.voiceId (written once
|
|
813
|
+
# by gen_script) is only the last resort for DSLs that declare neither —
|
|
814
|
+
# letting it win meant a voice change made after the script was drafted
|
|
815
|
+
# never reached TTS.
|
|
816
|
+
voice = _narration_voice(narration) or global_voice
|
|
817
|
+
if voice:
|
|
818
|
+
payload["voiceId"] = voice
|
|
793
819
|
# Speech rate follows the same route as the narration text: single source
|
|
794
820
|
# of truth on the DSL, copied down here because resolve_asset_audio only
|
|
795
821
|
# ever sees the asset. Scene-level overrides global (mirrors the narration
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"skillName": "render-video",
|
|
3
3
|
"repoName": "agent-skill-media-maker",
|
|
4
4
|
"skillId": "473",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "V32",
|
|
6
6
|
"skillDescription": "Final-render skill: loads a persisted RenderPlan by `job_id` and drives the Remotion engine to produce the final video.\n\nUse this skill as soon as the user mentions any of these intents (after assets are already prepared):\n- Render the video, composite the video, export the video\n- Turn the prepared assets into the final clip\n- Render with Remotion\n\nPrerequisite: 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.\n\n⚠️ 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."
|
|
7
7
|
}
|
|
@@ -169,6 +169,7 @@ Rules:
|
|
|
169
169
|
- If the author explicitly provides a `highlightMap`, the system keeps it as-is.
|
|
170
170
|
- The legacy flat `narration.text` form still works but the author then has to keep `highlightMap` in sync with the subtitle segmentation (error-prone, not recommended).
|
|
171
171
|
- `narration.languageBoost` (optional, also accepted at `global.narration`) pins the TTS language hint (`auto` / `Chinese` / `English` / …). Leave it unset unless auto-detection gets it wrong — the service applies its own default, and a scene-level value overrides the global one, exactly like `speed`.
|
|
172
|
+
- Voice: to change the narration voice, set `global.narration.voiceId` (whole video) or `narration.voiceId` on a scene (that scene only). Precedence when synthesizing is scene > global > the audio asset's `payload.voiceId`, which is only a fallback — editing the asset payload alone is not how you change a voice.
|
|
172
173
|
|
|
173
174
|
## Image sources
|
|
174
175
|
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"skillName": "template-registry",
|
|
3
3
|
"repoName": "agent-skill-media-maker",
|
|
4
4
|
"skillId": "475",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "V25",
|
|
6
6
|
"skillDescription": "Video-template registry skill. Stores every video-template definition and lists the available templates (templateId / name / aspect ratio / style tags).\n\nUse this skill as soon as the user mentions any of these intents:\n- View available templates / list every template\n\nNote: DSL→TemplateBinding is no longer a separate exposed step — once prepare_video_assets receives a template_id it builds the binding internally."
|
|
7
7
|
}
|
|
@@ -247,6 +247,9 @@
|
|
|
247
247
|
},
|
|
248
248
|
"outro": { "type": "string", "description": "可选:收尾句(此期间无卡片高亮)" },
|
|
249
249
|
"assetRef": { "type": "string", "description": "旁白音频 assetId" },
|
|
250
|
+
"voiceId": { "type": "string", "description": "该场旁白音色,覆盖 global.narration.voiceId;留空跟随全局。合成时优先级:场景 > 全局 > 音频资产 payload.voiceId(仅作兜底)。" },
|
|
251
|
+
"voiceName": { "type": "string", "description": "voiceId 的展示名(仅展示用,不参与合成)" },
|
|
252
|
+
"speed": { "type": "number", "description": "该场旁白语速,覆盖 global.narration.speed;留空跟随全局。" },
|
|
250
253
|
"languageBoost": { "type": "string", "description": "TTS 语种提示(auto / Chinese / English …)。中英混排的旁白不给提示时,英文词容易被按中文音系读出来;覆盖 global.narration 的同名字段;留空则跟随全局/服务端默认。" }
|
|
251
254
|
}
|
|
252
255
|
},
|