@remixmate/cli 0.9.48 → 0.9.50

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.9.48",
4
- "generatedAt": "2026-09-24T03:37:24.431Z",
3
+ "version": "0.9.50",
4
+ "generatedAt": "2026-09-27T01:55:22.557Z",
5
5
  "skills": [
6
6
  {
7
7
  "id": "doc-parse",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remixmate/cli",
3
- "version": "0.9.48",
3
+ "version": "0.9.50",
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",
@@ -1873,6 +1873,11 @@ def _persist_plan_checkpoint(render_plan: dict, job_id: Optional[int], private_t
1873
1873
  LogPrint(f" ⚠️ RenderPlan checkpoint failed (jobId={job_id}): {exc}", file=sys.stderr)
1874
1874
 
1875
1875
 
1876
+
1877
+ def _builtin_dynamic_render_enabled() -> bool:
1878
+ """内置模板是否也走 /renderDraft(Phase 3b 路由翻转开关,默认关)。"""
1879
+ return os.environ.get("REMIXMATE_BUILTIN_DYNAMIC_RENDER", "").strip().lower() in {"1", "true", "yes", "on"}
1880
+
1876
1881
  def render_with_remote_api(
1877
1882
  render_plan: dict,
1878
1883
  output_path: str,
@@ -1931,19 +1936,23 @@ def render_with_remote_api(
1931
1936
  cover_composition_id = resolve_cover_composition_id(template_id)
1932
1937
 
1933
1938
  # ─── 私有模板路由 ────────────────────────────────────────────────────
1934
- # 仅【用户私有模板】(isBuiltin=false 且带 sourceOssKey) 源码在 OSS、不在
1935
- # ab-render 启动 bundle,需走动态渲染:presignSource 取临时 GET URL → /renderDraft。
1936
- # 内置模板即使带 sourceOssKey(builtin-template-registry 回填,仅服务
1937
- # derive_template 派生),渲染仍走 ab-render 预构建的 /render,绝不走 /renderDraft,
1938
- # 否则会用 OSS 上的旧快照 + DraftMainVideo 复刻渲染,与生产 MainVideo 漂移。
1939
- # 下面这套 payload 构造在"续跑既有任务"时其实用不上(见后面的 resuming 分支),
1940
- # 所以它的失败不该让续跑也跟着失败 —— 任务还在后端好好渲着。
1939
+ # 仅【用户私有模板】(isBuiltin=false 且 hasSource) 源码在 OSS、不在
1940
+ # ab-render 启动 bundle,需走动态渲染:/renderDraft {templateKey},ab-render 服务端取包。
1941
+ # 内置模板即使带 sourceOssKey(admin 调用时 registry 才会输出),渲染仍走 ab-render
1942
+ # 预构建的 /render,绝不走 /renderDraft,否则会用 OSS 上的旧快照 + DraftMainVideo
1943
+ # 复刻渲染,与生产 MainVideo 漂移。
1941
1944
  pending_resume = bool(str(render_plan.get("remoteTaskId") or "").strip())
1942
- # 先给默认值:presign 失败时下面的分支不会走到,续跑分支仍要读 status_path。
1943
1945
  render_path = "/render"
1944
1946
  status_path = "/renderStatus"
1945
1947
 
1946
1948
  source_oss_key = None
1949
+ # 内置模板是否也走动态渲染(Phase 3b 路由翻转,ab-platform/docs/
1950
+ # template-authoring-page-review.md §7.2)。默认关:翻转依赖 ab-render 以服务身份取
1951
+ # 内置源码(DRAFT_BUILTIN_SOURCE_TOKEN ↔ ab-api ab_render.service_token),服务端没配好
1952
+ # 就打开,普通用户渲染内置模板会全部失败。服务端就绪后设 REMIXMATE_BUILTIN_DYNAMIC_RENDER=1;
1953
+ # 回退 = 取消该变量,内置模板回到 /render。
1954
+ builtin_dynamic = _builtin_dynamic_render_enabled()
1955
+ is_builtin_dynamic = False
1947
1956
  template_id = render_plan.get("templateId", "")
1948
1957
  if template_id:
1949
1958
  try:
@@ -1953,35 +1962,21 @@ def render_with_remote_api(
1953
1962
  # 是另一个模板的画面。
1954
1963
  _meta = get_template(template_id, include_all_statuses=True)
1955
1964
  if _meta and not _meta.get("isBuiltin"):
1956
- source_oss_key = _meta.get("sourceOssKey")
1965
+ source_oss_key = _meta.get("hasSource")
1966
+ elif _meta and builtin_dynamic:
1967
+ # 内置模板:客户端拿不到也不需要 sourceOssKey(源码保护),只要知道
1968
+ # 它在 registry 里;ab-render 按 templateKey 以服务身份取包。
1969
+ source_oss_key = True
1970
+ is_builtin_dynamic = True
1957
1971
  except Exception:
1958
1972
  source_oss_key = None
1959
1973
 
1960
1974
  if source_oss_key:
1961
- import render_job_client # type: ignore
1962
- tarball_url = None
1963
- try:
1964
- src = render_job_client.presign_template_source(template_id, private_token)
1965
- tarball_url = src.get("tarballUrl")
1966
- if not tarball_url:
1967
- raise RuntimeError(f"presignSource 未返回 tarballUrl: {src}")
1968
- except Exception as exc:
1969
- if pending_resume:
1970
- LogPrint(
1971
- f"⚠️ presignSource failed ({exc}) — 但有待续跑的任务,忽略继续",
1972
- file=sys.stderr,
1973
- )
1974
- else:
1975
- LogPrint(f"❌ presignSource failed for private template {template_id}: {exc}", file=sys.stderr)
1976
- render_plan["status"] = "failed"
1977
- render_plan["errors"].append({
1978
- "phase": "render",
1979
- "message": f"presignSource failed: {exc}",
1980
- "timestamp": now_iso(),
1981
- })
1982
- return False
1975
+ # 只传 templateKey:由 ab-render 带本次的 X-Priv-Token 向 ab-api 换源码包 URL
1976
+ # 并自行下载(所有权校验在 ab-api)。源码包 URL 不经过客户端 ——
1977
+ # 见 ab-platform/docs/template-source-protection-design.md §4.3。
1983
1978
  payload = {
1984
- "tarballUrl": tarball_url,
1979
+ "templateKey": template_id,
1985
1980
  "inputProps": input_props,
1986
1981
  "upload": True,
1987
1982
  "uploadTitle": effective_title,
@@ -1991,6 +1986,10 @@ def render_with_remote_api(
1991
1986
  # 不传则 ab-render 退回截首帧 / 不渲。
1992
1987
  if cover_composition_id:
1993
1988
  payload["coverCompositionId"] = cover_composition_id
1989
+ if is_builtin_dynamic:
1990
+ # 与预构建 /render 的 MainVideo 语义对齐:不把 entry.props 摊平到顶层
1991
+ # (摊平会让同名键覆盖平台注入的 typography / variantId 等)。
1992
+ payload["spreadEntryProps"] = False
1994
1993
  render_path = "/renderDraft"
1995
1994
  status_path = "/renderDraftStatus"
1996
1995
  else:
@@ -2009,6 +2008,8 @@ def render_with_remote_api(
2009
2008
  if pending_resume:
2010
2009
  # 续跑:下面那堆"正在提交"的日志会误导人,跳过
2011
2010
  LogPrint(f"🎬 Remote render task already exists, will resume polling", file=sys.stderr)
2011
+ elif is_builtin_dynamic:
2012
+ LogPrint(f" Builtin template (dynamic bundle): {template_id}", file=sys.stderr)
2012
2013
  elif source_oss_key:
2013
2014
  LogPrint(f" Private template (OSS dynamic bundle): {template_id}", file=sys.stderr)
2014
2015
  else:
@@ -2,6 +2,6 @@
2
2
  "skillName": "render-video",
3
3
  "repoName": "agent-skill-media-maker",
4
4
  "skillId": "473",
5
- "version": "V28",
5
+ "version": "V30",
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
  }
@@ -186,18 +186,6 @@ def get_job(job_id: int, priv_token: str) -> dict:
186
186
  return _post("/renderJob/get", {"jobId": job_id}, priv_token)
187
187
 
188
188
 
189
- def presign_template_source(template_key: str, priv_token: str) -> dict:
190
- """
191
- 为已注册私有模板的源码包申请临时 GET 下载 URL(渲染取包用)。
192
-
193
- 调 ab-api /remotionTemplate/presignSource,返回 { tarballUrl, sourceOssKey, version }。
194
- ab-render 用 tarballUrl 走 /renderDraft 动态 bundle 渲染。
195
-
196
- 注意:presignSource 端点不在 /renderJob 下,路径以 / 开头直接拼到 _api_base。
197
- """
198
- return _post("/remotionTemplate/presignSource", {"templateKey": template_key}, priv_token)
199
-
200
-
201
189
  # ─── CLI self-test ────────────────────────────────────────────────────────────
202
190
 
203
191
  if __name__ == "__main__":
@@ -2,6 +2,6 @@
2
2
  "skillName": "template-registry",
3
3
  "repoName": "agent-skill-media-maker",
4
4
  "skillId": "475",
5
- "version": "V21",
5
+ "version": "V22",
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
  }