From a5363f8c93a24a104d4ed5a2a4eb1cef7f812197 Mon Sep 17 00:00:00 2001 From: AIwork4me Date: Wed, 2 Sep 2026 07:15:14 +0800 Subject: [PATCH 1/3] feat(zcode-remotion): add reliable Remotion video workflow --- marketplace.json | 30 +++ .../zcode-remotion/.zcode-plugin/plugin.json | 28 +++ plugins/zcode-remotion/LICENSE | 21 ++ plugins/zcode-remotion/NOTICE.md | 16 ++ plugins/zcode-remotion/README.md | 111 +++++++++++ plugins/zcode-remotion/README_CN.md | 111 +++++++++++ plugins/zcode-remotion/UPSTREAM.md | 22 ++ .../commands/remotion-doctor.md | 51 +++++ .../zcode-remotion/commands/remotion-setup.md | 96 +++++++++ .../commands/remotion-update.md | 101 ++++++++++ .../compatibility/remotion.json | 29 +++ .../zcode-remotion/scripts/skill-names.mjs | 16 ++ .../zcode-remotion/scripts/skill-paths.mjs | 148 ++++++++++++++ .../zcode-remotion/skills/remotion/SKILL.md | 188 ++++++++++++++++++ 14 files changed, 968 insertions(+) create mode 100644 plugins/zcode-remotion/.zcode-plugin/plugin.json create mode 100644 plugins/zcode-remotion/LICENSE create mode 100644 plugins/zcode-remotion/NOTICE.md create mode 100644 plugins/zcode-remotion/README.md create mode 100644 plugins/zcode-remotion/README_CN.md create mode 100644 plugins/zcode-remotion/UPSTREAM.md create mode 100644 plugins/zcode-remotion/commands/remotion-doctor.md create mode 100644 plugins/zcode-remotion/commands/remotion-setup.md create mode 100644 plugins/zcode-remotion/commands/remotion-update.md create mode 100644 plugins/zcode-remotion/compatibility/remotion.json create mode 100644 plugins/zcode-remotion/scripts/skill-names.mjs create mode 100644 plugins/zcode-remotion/scripts/skill-paths.mjs create mode 100644 plugins/zcode-remotion/skills/remotion/SKILL.md diff --git a/marketplace.json b/marketplace.json index 415f7eb..000085b 100644 --- a/marketplace.json +++ b/marketplace.json @@ -152,6 +152,36 @@ "motion" ] }, + { + "name": "zcode-remotion", + "source": "./plugins/zcode-remotion", + "displayName": "Remotion for ZCode", + "displayName_i18n": { + "en": "Remotion for ZCode", + "zh-CN": "Remotion for ZCode" + }, + "description": "Create and verify Remotion videos in ZCode with official Agent Skills, environment preflight, autonomous visual QA, verified MP4 output, and compatibility-aware setup.", + "description_i18n": { + "en": "Create and verify Remotion videos in ZCode with official Agent Skills, environment preflight, autonomous visual QA, verified MP4 output, and compatibility-aware setup.", + "zh-CN": "在 ZCode 中可靠创建并校验 Remotion 视频:使用官方 Agent Skills,提供环境预检、自主静帧视觉 QA、MP4 产物校验和兼容性感知的安装流程。" + }, + "version": "0.2.5", + "author": { + "name": "AIwork4me", + "url": "https://github.com/AIwork4me" + }, + "category": "productivity", + "keywords": [ + "remotion", + "zcode", + "video-generation", + "programmatic-video", + "animation", + "visual-qa", + "render", + "mp4" + ] + }, { "name": "accounting-and-reporting", "source": "./plugins/accounting-and-reporting", diff --git a/plugins/zcode-remotion/.zcode-plugin/plugin.json b/plugins/zcode-remotion/.zcode-plugin/plugin.json new file mode 100644 index 0000000..5b11d3d --- /dev/null +++ b/plugins/zcode-remotion/.zcode-plugin/plugin.json @@ -0,0 +1,28 @@ +{ + "name": "zcode-remotion", + "description": "Create and verify Remotion videos in ZCode with official Agent Skills, environment preflight, autonomous visual QA, verified MP4 output, and compatibility-aware setup.", + "description_i18n": { + "en": "Create and verify Remotion videos in ZCode with official Agent Skills, environment preflight, autonomous visual QA, verified MP4 output, and compatibility-aware setup.", + "zh-CN": "在 ZCode 中可靠创建并校验 Remotion 视频:使用官方 Agent Skills,提供环境预检、自主静帧视觉 QA、MP4 产物校验和兼容性感知的安装流程。" + }, + "version": "0.2.5", + "author": { + "name": "AIwork4me", + "url": "https://github.com/AIwork4me" + }, + "homepage": "https://github.com/AIwork4me/zcode-remotion", + "repository": "https://github.com/AIwork4me/zcode-remotion", + "license": "MIT", + "keywords": [ + "remotion", + "zcode", + "video-generation", + "programmatic-video", + "animation", + "visual-qa", + "render", + "mp4" + ], + "skills": "skills", + "commands": "commands" +} diff --git a/plugins/zcode-remotion/LICENSE b/plugins/zcode-remotion/LICENSE new file mode 100644 index 0000000..83494f9 --- /dev/null +++ b/plugins/zcode-remotion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 ZCode Remotion Plugin Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/zcode-remotion/NOTICE.md b/plugins/zcode-remotion/NOTICE.md new file mode 100644 index 0000000..099ae07 --- /dev/null +++ b/plugins/zcode-remotion/NOTICE.md @@ -0,0 +1,16 @@ +# NOTICE + +This plugin contains original ZCode integration-layer content (routing, environment checks, workflow guidance, helper scripts), licensed under the MIT License in `LICENSE`. + +The Remotion Agent Skills that this plugin bootstraps are **not redistributed** by this Marketplace package. They are fetched by the user's own machine from the official source with the official installer, for example: + +```text +npx -y skills add remotion-dev/skills -s '*' -y --copy -g +``` + +The upstream Remotion Agent Skills and Remotion software are Copyright Remotion and remain subject to Remotion's own license terms. Review: + +- https://github.com/remotion-dev/remotion/blob/main/LICENSE.md +- https://www.remotion.pro + +Eligibility for free use depends on the upstream license terms and the user's entity type. This integration does not alter or bypass those terms. diff --git a/plugins/zcode-remotion/README.md b/plugins/zcode-remotion/README.md new file mode 100644 index 0000000..cf5fa57 --- /dev/null +++ b/plugins/zcode-remotion/README.md @@ -0,0 +1,111 @@ +# zcode-remotion + +[中文文档](./README_CN.md) + +Create and verify programmatic videos with Remotion directly from ZCode. The plugin keeps Remotion's official Agent Skills as the source of domain knowledge and adds the reliability layer around them: skill bootstrap, environment preflight, routing, autonomous representative-frame visual QA, final MP4 verification, and a recorded compatibility baseline. + +**One prompt → official Remotion skills → visual QA → verified MP4.** + +Source project: https://github.com/AIwork4me/zcode-remotion + +## Install + +In ZCode, open **Settings → Plugins**, search the official marketplace for **zcode-remotion** (display name: **Remotion for ZCode**), then install and enable it. + +Requirements: + +- Node.js 18 or newer (20/22/24 recommended) +- Network access for first-time package / skill / browser downloads +- A writable project directory for generated Remotion projects and outputs + +The plugin itself has no API key, account, MCP server, hook, or background-service requirement. + +## Quick start + +Just ask for a video, for example: + +```text +Create a 10-second product promo video for an AI coding agent. 16:9, modern technical style, and deliver the final MP4. +``` + +The bundled `remotion` skill will: + +1. verify that the official Remotion Agent Skills are present and complete; +2. bootstrap or repair them with the official installer when needed; +3. check Node and the project package manager; +4. route the task to the relevant official Remotion skill; +5. render a representative still and inspect it for objective visual defects; +6. fix obvious issues before the expensive full render; and +7. render and verify the final MP4 before reporting success. + +The bundled command picker also exposes workflows for **remotion-setup**, **remotion-doctor**, and **remotion-update**. + +## What this plugin adds + +| Capability | Behavior | +| --- | --- | +| Official skill bootstrap | Installs / repairs the official `remotion-dev/skills` set instead of vendoring a copy | +| Skill integrity | Verifies the expected skill set on disk; a partial install is repaired in the same scope | +| Environment preflight | Checks Node, package-manager context, Remotion project state, and render prerequisites | +| Routing | Maps creation, markup, captions, maps, Studio, render, multimedia, upgrade, docs, SaaS and interactivity requests to the corresponding official skills | +| Autonomous visual QA | Renders and visually inspects a representative still before a full render; asks the user only for subjective or low-confidence decisions | +| Output verification | Confirms the MP4 exists and is non-empty; uses `ffprobe` for duration / dimensions when available | +| Compatibility awareness | Ships a machine-readable tested baseline for Remotion, official skills and Mediabunny | + +## Current tested baseline + +The Marketplace package records the compatibility state in `compatibility/remotion.json`: + +- Remotion `4.0.520` +- official Remotion Agent Skills `4.0.520` — 12 skills +- Mediabunny `1.55.5` + +This is a **last verified baseline**, not a claim that newer releases are incompatible. The doctor / update workflows distinguish installed versions, latest upstream versions, and the recorded baseline. + +## Network access and side effects + +Enabling the plugin itself only registers its Markdown skill and commands. When you use its workflows, the Agent may execute local commands and access the network on your behalf. + +### Network access + +Depending on the task, it may contact: + +- npm registry, through `npm` / `npx` or the detected package manager; +- GitHub, primarily `remotion-dev/skills` for the official Agent Skills; +- Remotion documentation / release pages for version and upgrade guidance; and +- Remotion's browser download endpoints when Chrome Headless Shell is required for rendering. + +### Local commands + +Typical commands include: + +- `node` / `npx`; +- the detected package manager (`npm`, `pnpm`, `yarn`, or `bun`); +- official Remotion CLI commands such as `remotion studio`, `remotion still`, `remotion render`, `remotion versions`, `remotion upgrade`, and `remotion browser ensure`; +- the official `skills` installer; and +- optional `ffprobe` for final media metadata verification. + +### File writes + +The workflows can write: + +- Remotion project files and dependencies in the user's chosen project directory; +- rendered stills and MP4 outputs in the project; +- official Remotion skills into user scope (`~/.zcode/skills/` / `~/.agents/skills/`) or project scope (`.zcode/skills/`) according to the requested scope. + +The plugin does **not** install hooks, register MCP servers, request credentials, or silently write long-term data outside these documented paths. + +## Official Remotion Skills and licensing + +This plugin does **not** redistribute Remotion's official Agent Skills. It invokes the official installer so the user's machine fetches them from the official source. + +- This integration layer is MIT licensed; see `LICENSE`. +- The upstream Remotion Agent Skills and Remotion software remain under Remotion's own licensing terms; see `NOTICE.md` and https://www.remotion.pro. + +## Skill discovery after bootstrap + +The plugin's own skill and commands are registered when the plugin is enabled. The Remotion skills installed by the external official installer are separate skill files. After creating or updating them, open **Settings → Skills**, click **Refresh**, and confirm they are listed and enabled. Start a new conversation only if Refresh does not surface them. + +## Provenance + +This Marketplace package is derived from `AIwork4me/zcode-remotion` v0.2.5. Repository-only CI, demos, verification reports, tests, release tooling and drift automation are intentionally not included in the installable Marketplace artifact. See `UPSTREAM.md` for the packaging notes. diff --git a/plugins/zcode-remotion/README_CN.md b/plugins/zcode-remotion/README_CN.md new file mode 100644 index 0000000..e6d13c4 --- /dev/null +++ b/plugins/zcode-remotion/README_CN.md @@ -0,0 +1,111 @@ +# zcode-remotion + +[English](./README.md) + +在 ZCode 中直接创建并校验 Remotion 程序化视频。插件继续以 Remotion 官方 Agent Skills 作为领域知识来源,只补上可靠性层:官方技能引导安装、环境预检、任务路由、自主代表性静帧视觉 QA、最终 MP4 校验,以及可追溯的兼容性基线。 + +**一句提示 → Remotion 官方技能 → 视觉 QA → 校验过的 MP4。** + +源项目:https://github.com/AIwork4me/zcode-remotion + +## 安装 + +在 ZCode 中打开 **设置 → 插件**,在官方插件市场搜索 **zcode-remotion**(显示名:**Remotion for ZCode**),安装并启用即可。 + +要求: + +- Node.js 18 或更高版本(推荐 20/22/24) +- 首次下载包、技能和浏览器组件时需要网络访问 +- 用于创建 Remotion 项目和输出文件的可写目录 + +插件本身不需要 API Key、账号、MCP Server、Hook 或后台服务。 + +## 快速开始 + +直接描述你要的视频,例如: + +```text +帮我做一个 10 秒的 AI 编程助手产品宣传视频,16:9,现代科技感,并交付最终 MP4。 +``` + +插件自带的 `remotion` 技能会: + +1. 检查 Remotion 官方 Agent Skills 是否已完整安装; +2. 如缺失或不完整,调用官方安装器在原作用域内安装 / 修复; +3. 检查 Node 和当前项目的包管理器环境; +4. 把任务路由到对应的 Remotion 官方技能; +5. 先渲染代表性静帧,并自主检查客观视觉问题; +6. 在全量渲染前先修复明显问题; +7. 完成渲染后校验 MP4,再向用户报告成功。 + +插件的 Commands 列表还提供 **remotion-setup**、**remotion-doctor** 和 **remotion-update** 三条维护工作流。 + +## 插件补上的可靠性能力 + +| 能力 | 行为 | +| --- | --- | +| 官方技能引导安装 | 调用官方 `remotion-dev/skills` 安装器,不在插件中复制官方技能 | +| 技能完整性检查 | 按预期技能集合检查磁盘;局部安装会在同一作用域内修复 | +| 环境预检 | 检查 Node、包管理器、Remotion 项目状态和渲染前提 | +| 任务路由 | 将创建、组件编写、字幕、地图、Studio、渲染、多媒体、升级、文档、SaaS、交互等请求路由到对应官方技能 | +| 自主视觉 QA | 全量渲染前先生成代表性静帧并由 Agent 检查;仅在主观选择、品牌歧义或低置信度时询问用户 | +| 产物校验 | 确认 MP4 存在且非空;若有 `ffprobe`,进一步检查时长和分辨率 | +| 兼容性感知 | 随插件携带 Remotion、官方技能和 Mediabunny 的机器可读验证基线 | + +## 当前验证基线 + +Marketplace 包中的 `compatibility/remotion.json` 记录: + +- Remotion `4.0.520` +- Remotion 官方 Agent Skills `4.0.520` — 共 12 个 +- Mediabunny `1.55.5` + +这是**最近一次真实验证通过的基线**,并不意味着更新版本不兼容。doctor / update 工作流会明确区分:当前安装版本、上游最新版本、以及插件记录的验证基线。 + +## 网络访问与副作用 + +启用插件本身只会注册 Markdown 技能和命令。真正执行工作流时,Agent 会根据任务在本机运行命令,并可能访问网络。 + +### 网络访问 + +根据任务不同,可能访问: + +- npm registry,通过 `npm` / `npx` 或当前项目的包管理器; +- GitHub,主要用于从 `remotion-dev/skills` 获取 Remotion 官方 Agent Skills; +- Remotion 官方文档 / Release 页面,用于版本与升级信息; +- Remotion 的浏览器下载地址,在渲染需要 Chrome Headless Shell 时下载组件。 + +### 本地命令 + +典型命令包括: + +- `node` / `npx`; +- 当前项目使用的包管理器(`npm`、`pnpm`、`yarn` 或 `bun`); +- Remotion 官方 CLI,例如 `remotion studio`、`remotion still`、`remotion render`、`remotion versions`、`remotion upgrade`、`remotion browser ensure`; +- 官方 `skills` 安装器; +- 可选的 `ffprobe`,用于最终媒体元数据校验。 + +### 文件写入 + +工作流可能写入: + +- 用户指定项目目录里的 Remotion 源码和依赖; +- 项目中的静帧与 MP4 输出; +- 用户作用域的官方 Remotion 技能(`~/.zcode/skills/` / `~/.agents/skills/`),或按用户明确要求写入项目作用域 `.zcode/skills/`。 + +插件**不会**安装 Hook、注册 MCP Server、索要凭据,也不会在上述已说明路径之外静默写入长期数据。 + +## Remotion 官方技能与许可证 + +本插件**不重新分发** Remotion 官方 Agent Skills,而是调用官方安装器,让用户机器直接从官方来源获取。 + +- 本集成层使用 MIT License,见 `LICENSE`。 +- Remotion 官方 Agent Skills 与 Remotion 软件继续遵循 Remotion 自己的许可证条款,见 `NOTICE.md` 和 https://www.remotion.pro。 + +## 引导安装后的技能发现 + +插件自带的 skill 和 commands 在启用插件时自动注册。通过官方安装器外部安装的 Remotion Skills 属于独立技能文件;新建或更新后,请打开 **设置 → 技能**,点击 **刷新**,确认技能已列出并启用。只有刷新后仍未出现时,再新建会话。 + +## 来源与打包说明 + +本 Marketplace 包基于 `AIwork4me/zcode-remotion` v0.2.5。源仓中的 CI、demo、验证报告、测试、Release 工具和上游漂移自动化属于维护侧资产,不进入用户安装包。具体差异见 `UPSTREAM.md`。 diff --git a/plugins/zcode-remotion/UPSTREAM.md b/plugins/zcode-remotion/UPSTREAM.md new file mode 100644 index 0000000..6cc8fbf --- /dev/null +++ b/plugins/zcode-remotion/UPSTREAM.md @@ -0,0 +1,22 @@ +# Upstream and provenance + +This Marketplace package is derived from: + +- Source repository: https://github.com/AIwork4me/zcode-remotion +- Source version: `0.2.5` +- Source main commit used for this submission: `2a9903c2cfc167f11cbec3009a2d7b2161b03492` + +## Marketplace packaging adaptations + +The official Marketplace package keeps the user-facing runtime layer and intentionally excludes repository-maintenance assets such as CI workflows, demos, verification reports, unit tests, release checks, and upstream-drift automation. + +The following distribution-specific adjustments are applied without changing the product boundary: + +1. Add the bilingual `description_i18n` metadata required by the official Marketplace validator. +2. Provide Marketplace-specific English and Chinese READMEs that document network access, local command execution, file writes, dependencies, side effects, and licensing. +3. Resolve bundled helper scripts from the installed plugin root instead of assuming the user's current workspace is the source repository. Workflows first resolve `ZCODE_PLUGIN_ROOT` and then invoke the packaged scripts by absolute path. +4. Remove two duplicated prose fragments from the source skill/setup text while preserving the same behavior. + +## Third-party material + +No Remotion Agent Skill is vendored in this package. The plugin asks the user's machine to fetch official skills from `remotion-dev/skills` using the official installer. See `NOTICE.md` for licensing details. diff --git a/plugins/zcode-remotion/commands/remotion-doctor.md b/plugins/zcode-remotion/commands/remotion-doctor.md new file mode 100644 index 0000000..11d5d58 --- /dev/null +++ b/plugins/zcode-remotion/commands/remotion-doctor.md @@ -0,0 +1,51 @@ +--- +description: Diagnose the Remotion + ZCode environment: Node, package manager, official skills, versions, browser and license awareness +--- + +Run the checks first, collect evidence, then print one compact pass/fail table with fixes. Do not change the environment until the report is complete unless the user explicitly asks you to repair it. + +## 0. Resolve the packaged helper path + +Do not assume the current workspace is the plugin repository. Resolve the installed plugin root from ZCode's environment: + +```text +node -p "process.env.ZCODE_PLUGIN_ROOT || ''" +``` + +Use the resulting absolute path as ``. + +Machine-readable version sources must stay separate: + +- latest Remotion stable: `npm view remotion version` +- latest official skill release: the `version` field from `https://raw.githubusercontent.com/remotion-dev/skills/main/package.json` +- in-project Remotion truth: `npx remotion versions` when available +- last verified plugin baseline: `/compatibility/remotion.json` + +Never infer the skills version from the Remotion package version or vice versa. + +## Checks + +1. **Node** — `node -v`; PASS when >=18. Fix: install from https://nodejs.org. +2. **npx** — `npx -v`; PASS when it prints a version. +3. **Package manager** — detect by lockfile: `bun.lock` / `bun.lockb` → bun, `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `package-lock.json` → npm, otherwise npm as the default recommendation. +4. **Official Remotion skills installed and complete?** Run: + + ```text + node "/scripts/skill-paths.mjs" + ``` + + This checks project scope first, then user scope, never unions scopes. Report `N/M present`, missing names, extra `remotion-*` folders and COMPLETE / INCOMPLETE / absent. Incomplete or absent → recommend the `remotion-setup` workflow. +5. **Official skills current?** Read the installed `remotion-best-practices/SKILL.md` version from the detected scope and compare it with the official skills package metadata using SemVer. Installed < latest → outdated; equal → current; installed > latest → ahead/informational; source unreachable → unknown, not failure by guesswork. +6. **Remotion project state** — only when the project declares `remotion` or `@remotion/*` dependencies. Use the detected package manager plus `npx remotion versions` / dependency inspection. All installed Remotion packages must resolve to one consistent version. Compare installed vs latest separately from the plugin's last verified baseline. If installed is newer than the recorded baseline, report: `Installed Remotion is newer than this plugin's verified baseline — check current compatibility evidence before relying on the baseline.` Do not call it incompatible without evidence. +7. **Chrome Headless Shell** — in a Remotion project run `npx remotion browser ensure`. If there is no Remotion project, mark N/A. On failure, report the network/proxy error and point to https://www.remotion.dev/docs/chrome-headless-shell. +8. **License awareness** — informational PASS. Remotion's upstream license terms apply; point to https://www.remotion.pro and this plugin's `NOTICE.md`. Do not attempt to bypass licensing behavior. + +## Output + +End with: + +- one table: Check | Result | Evidence | Fix; +- summary count `X/8 checks passed` (N/A clearly identified); +- compact version block: Remotion installed / latest / verified baseline; official skills installed / latest / expected count; Mediabunny recorded pairing; +- the **single highest-priority next action**; and +- a note that Remotion API-specific questions should use the official `remotion-docs` skill. diff --git a/plugins/zcode-remotion/commands/remotion-setup.md b/plugins/zcode-remotion/commands/remotion-setup.md new file mode 100644 index 0000000..2623559 --- /dev/null +++ b/plugins/zcode-remotion/commands/remotion-setup.md @@ -0,0 +1,96 @@ +--- +description: Install or repair the official Remotion Agent Skills and verify the requested ZCode scope +argument-hint: "[--project]" +--- + +Install or repair the official Remotion Agent Skills, then verify the same requested scope on disk. This workflow is idempotent. + +## 0. Resolve the packaged helper path + +Do **not** assume the user's current workspace is the plugin source repository. +Resolve the installed plugin root from ZCode's `ZCODE_PLUGIN_ROOT`. A cross-platform way to print it is: + +```text +node -p "process.env.ZCODE_PLUGIN_ROOT || ''" +``` + +Use the resolved absolute path for `scripts/skill-paths.mjs` below. + +## 1. Preflight + +Run `node -v`. Require Node >=18. If Node is missing or older, stop and point the user to https://nodejs.org. + +## 2. Choose the requested scope + +- Default: **global/user scope** — official skills are available across projects. +- If `$ARGUMENTS` contains `--project`: **project scope** — pin the skills to the current project. + +Never silently switch scope after a failure. + +## 3. Inspect the requested scope + +Using the resolved plugin root, run: + +```text +node "/scripts/skill-paths.mjs" --global +``` + +or for project scope: + +```text +node "/scripts/skill-paths.mjs" --project . +``` + +Expected skill names come only from `/compatibility/remotion.json`. + +Interpret the report: + +- **COMPLETE** — every expected skill has `SKILL.md`; report success and stop. +- **INCOMPLETE** — one or more expected skills exist but the set is incomplete; repair this exact scope. +- **absent** — none of the expected skills exists in this scope; bootstrap this scope. + +A single router skill is never enough to prove a healthy installation. + +## 4. Install / repair with the official installer + +Global/user scope: + +```text +npx -y skills add remotion-dev/skills -s '*' -y --copy -g +``` + +Project scope: + +```text +npx -y skills add remotion-dev/skills -s '*' -y --copy +``` + +`--copy` avoids Windows symlink privilege problems and is safe on the other supported platforms. + +If the official installer fails: + +1. report the actual error; +2. keep the requested scope; +3. if GitHub is still reachable, fetch the official skill folders directly from `https://github.com/remotion-dev/skills` into the same requested scope; +4. if truly offline, use an already-installed/cached copy in that scope if one exists; otherwise state that the official skills cannot be installed now. + +Do not invent success from an installer exit code alone. + +## 5. Verify on disk + +Re-run the **same** `skill-paths.mjs` command used in step 3. +Only a `COMPLETE` report counts as success. + +Report: + +- scope used; +- `Official Remotion skills: N/M present`; +- missing skills, if any; +- extra `remotion-*` folders, if any; and +- whether repair is still required. + +## 6. Finish with discovery and licensing guidance + +The plugin's own skill and commands register when the plugin is enabled. The official Remotion skills installed above are external skill files. After creating or updating them, open **Settings → Skills**, click **Refresh**, and confirm they are listed and enabled. Start a new conversation only if Refresh does not surface them. + +Tell the user that the official skills were fetched from Remotion's official source and are **not redistributed by this plugin**. Their licensing remains governed by Remotion; see this plugin's `NOTICE.md` and https://www.remotion.pro. diff --git a/plugins/zcode-remotion/commands/remotion-update.md b/plugins/zcode-remotion/commands/remotion-update.md new file mode 100644 index 0000000..b6418c8 --- /dev/null +++ b/plugins/zcode-remotion/commands/remotion-update.md @@ -0,0 +1,101 @@ +--- +description: Upgrade Remotion through the official CLI path and refresh the official Remotion Agent Skills +--- + +Bring the current project's Remotion packages and the installed official Remotion Agent Skills up to the latest stable versions using official-first flows. Treat package upgrades and skill refresh as two independent parts and report both. + +## 0. Resolve the packaged helper path + +Do not assume the user's current workspace is the plugin source repository. Resolve the installed plugin root: + +```text +node -p "process.env.ZCODE_PLUGIN_ROOT || ''" +``` + +Use the resulting absolute path as ``. + +## Part A — Upgrade Remotion packages + +Record the current Remotion version before changing anything. + +### A1. `@remotion/cli` is installed + +Use the official upgrader: + +```text +npx remotion upgrade +``` + +If an older local CLI on Windows fails while spawning the package manager, retry with a current CLI rather than hand-writing a parallel upgrade algorithm: + +```text +npx --yes --package=@remotion/cli@latest -- remotion upgrade +``` + +Then run: + +```text +npx remotion versions +``` + +All Remotion packages should resolve to one version. + +### A2. `@remotion/cli` is not installed + +Follow the official `remotion-upgrade` skill's manual path: + +1. Get the target stable version with `npm view remotion version`. +2. Find every `remotion` and `@remotion/*` dependency in every dependency section / workspace / catalog used by the project. +3. Upgrade all of them to the same target version with the project's detected package manager, preserving its existing version-pin style. +4. If `mediabunny` or `@mediabunny/*` is installed, use the official compatibility page https://www.remotion.dev/docs/mediabunny/version and align it with the target Remotion release. +5. Run the package manager install so the lockfile is updated. +6. Verify resolution with `npx remotion versions` or the matching dependency inspection. + +Do not infer a Mediabunny pairing from `npm view mediabunny version`; the relevant value is the pairing documented for the target Remotion version. + +## Part B — Refresh official Remotion Agent Skills + +Get the canonical recorded skill-name list from the packaged compatibility manifest: + +```text +node "/scripts/skill-names.mjs" +``` + +Pass the returned names explicitly to the official updater. Do not use shell-specific command substitution and do not rely on a memorized list. + +- Project-scope skills: add `-p`. +- User/global-scope skills: add `-g`. + +Conceptually: + +```text +npx skills update --yes +``` + +If upstream says a recorded skill name is unknown, stop guessing and report the topology change for maintainer review. + +After updating, verify the same scope on disk with: + +```text +node "/scripts/skill-paths.mjs" --global +``` + +or: + +```text +node "/scripts/skill-paths.mjs" --project . +``` + +Only a COMPLETE report counts as success. + +## Report + +Return: + +- previous Remotion version → new version; +- upgrade path used (official CLI or official manual fallback); +- package consistency PASS / FAIL; +- Mediabunny compatibility result when applicable; +- skills refresh result, scope, resulting `N/M`, and installed skill version; +- relevant breaking-change notes from https://github.com/remotion-dev/remotion/releases and https://www.remotion.dev/docs/upgrading for the crossed version range; and +- after external skills change, remind the user to open **Settings → Skills → Refresh** and confirm they are enabled. diff --git a/plugins/zcode-remotion/compatibility/remotion.json b/plugins/zcode-remotion/compatibility/remotion.json new file mode 100644 index 0000000..8d4b8bd --- /dev/null +++ b/plugins/zcode-remotion/compatibility/remotion.json @@ -0,0 +1,29 @@ +{ + "remotion": { + "tested": "4.0.520" + }, + "skills": { + "tested": "4.0.520", + "count": 12, + "names": [ + "remotion-best-practices", + "remotion-captions", + "remotion-create", + "remotion-docs", + "remotion-interactivity", + "remotion-maps", + "remotion-markup", + "remotion-multimedia", + "remotion-render", + "remotion-saas", + "remotion-studio", + "remotion-upgrade" + ] + }, + "mediabunny": { + "tested": "1.55.5", + "source": "https://www.remotion.dev/docs/mediabunny/version" + }, + "verifiedAt": "2026-09-01", + "source": "https://github.com/remotion-dev/skills" +} diff --git a/plugins/zcode-remotion/scripts/skill-names.mjs b/plugins/zcode-remotion/scripts/skill-names.mjs new file mode 100644 index 0000000..b4c1905 --- /dev/null +++ b/plugins/zcode-remotion/scripts/skill-names.mjs @@ -0,0 +1,16 @@ +#!/usr/bin/env node +// Prints the official Remotion skill names recorded in +// compatibility/remotion.json — the one canonical list. + +import { readFileSync } from 'node:fs'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); +const { skills } = JSON.parse(readFileSync(join(ROOT, 'compatibility', 'remotion.json'), 'utf8')); + +if (process.argv.includes('--count')) { + console.log(skills.count); +} else { + console.log(skills.names.join(' ')); +} diff --git a/plugins/zcode-remotion/scripts/skill-paths.mjs b/plugins/zcode-remotion/scripts/skill-paths.mjs new file mode 100644 index 0000000..cf149b8 --- /dev/null +++ b/plugins/zcode-remotion/scripts/skill-paths.mjs @@ -0,0 +1,148 @@ +#!/usr/bin/env node +// Canonical official-skill discovery + installation integrity for zcode-remotion. +// Pure logic over paths — expected skill names come exclusively from +// compatibility/remotion.json → skills.names. + +import { existsSync, readdirSync, readFileSync } from 'node:fs'; +import { homedir } from 'node:os'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +export const ROUTER_SKILL = 'remotion-best-practices'; + +export const userSkillDirs = (home = homedir()) => + [join(home, '.zcode', 'skills'), join(home, '.agents', 'skills')]; + +export const projectSkillDir = (projectRoot) => join(projectRoot, '.zcode', 'skills'); + +export const loadExpectedSkillNames = () => + JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'compatibility', 'remotion.json'), 'utf8')).skills.names; + +const listInstalled = (dir) => { + if (!existsSync(dir)) return []; + try { + return readdirSync(dir) + .filter((name) => name.startsWith('remotion-') && existsSync(join(dir, name, 'SKILL.md'))); + } catch { + return []; + } +}; + +function inspectCandidate(dir, expected) { + const installed = new Set(listInstalled(dir)); + const presentExpected = expected.filter((n) => installed.has(n)); + const missing = expected.filter((n) => !installed.has(n)); + return { + dir, + expected: expected.length, + found: presentExpected.length, + missing, + extra: [...installed].filter((n) => !expected.includes(n)), + complete: presentExpected.length === expected.length, + hasInstall: presentExpected.length > 0, + }; +} + +// mode: +// auto — project → user scope, strict priority; first scope with any +// expected skill is the detected installation. +// project — inspect only /.zcode/skills. +// global — inspect ~/.zcode/skills and ~/.agents/skills as two +// representations of one logical user scope; never union them. +export function inspectSkillInstall({ mode = 'auto', projectRoot = null, home = homedir(), expectedSkillNames } = {}) { + if (!['auto', 'project', 'global'].includes(mode)) { + throw new Error(`unknown mode: ${mode}`); + } + if (mode === 'project' && !projectRoot) { + throw new Error('projectRoot is required in project mode'); + } + + const expected = expectedSkillNames ?? loadExpectedSkillNames(); + let candidates; + + if (mode === 'project') { + candidates = [{ scope: 'project', dir: projectSkillDir(projectRoot) }]; + } else if (mode === 'global') { + candidates = userSkillDirs(home).map((dir) => ({ scope: 'user', dir })); + } else { + candidates = [ + { scope: 'project', dir: projectSkillDir(projectRoot) }, + ...userSkillDirs(home).map((dir) => ({ scope: 'user', dir })), + ]; + } + + if (mode === 'global') { + const inspected = candidates.map((c) => ({ ...c, ...inspectCandidate(c.dir, expected) })); + const withInstall = inspected.filter((r) => r.hasInstall); + if (withInstall.length === 0) return absent('global', expected); + const complete = withInstall.find((r) => r.complete); + const best = complete ?? withInstall.reduce((a, b) => (b.found > a.found ? b : a)); + return { mode, scope: 'user', ...pick(best) }; + } + + for (const c of candidates) { + const r = inspectCandidate(c.dir, expected); + if (r.hasInstall) return { mode, scope: c.scope, ...pick(r) }; + } + return absent(mode, expected); + + function pick(r) { + return { dir: r.dir, expected: r.expected, found: r.found, missing: r.missing, extra: r.extra, complete: r.complete }; + } + function absent(m, exp) { + return { mode: m, scope: 'none', dir: null, expected: exp.length, found: 0, missing: [], extra: [], complete: false }; + } +} + +// CLI: node skill-paths.mjs [--global | --project ] [--home ] +// Exit codes: 0 complete · 1 incomplete · 2 absent · 64 usage error. +if (process.argv[1] && process.argv[1].endsWith('skill-paths.mjs')) { + const args = process.argv.slice(2); + const KNOWN = new Set(['--global', '--project', '--home']); + const badFlag = args.find((a) => a.startsWith('--') && !KNOWN.has(a)); + const projectIdx = args.indexOf('--project'); + const wantsGlobal = args.includes('--global'); + const projectArg = projectIdx !== -1 ? args[projectIdx + 1] : undefined; + + if (badFlag) { + console.error(`skill-paths: unknown option ${badFlag}\nusage: node skill-paths.mjs [--global | --project ] [--home ]`); + process.exit(64); + } + if (wantsGlobal && projectIdx !== -1) { + console.error('skill-paths: --global and --project are mutually exclusive\nusage: node skill-paths.mjs [--global | --project ] [--home ]'); + process.exit(64); + } + if (projectIdx !== -1 && (projectArg === undefined || projectArg.startsWith('--'))) { + console.error('skill-paths: --project requires a directory argument'); + process.exit(64); + } + const homeIdx = args.indexOf('--home'); + if (homeIdx !== -1 && (args[homeIdx + 1] === undefined || args[homeIdx + 1].startsWith('--'))) { + console.error('skill-paths: --home requires a directory argument'); + process.exit(64); + } + + const mode = wantsGlobal ? 'global' : projectIdx !== -1 ? 'project' : 'auto'; + const result = inspectSkillInstall({ + mode, + projectRoot: mode === 'global' ? null : projectArg ?? process.cwd(), + home: homeIdx !== -1 ? args[homeIdx + 1] : homedir(), + }); + + console.log(`mode: ${result.mode}`); + console.log(`scope: ${result.scope}`); + if (result.scope === 'none') { + console.log('Official Remotion skills: not installed'); + console.log(`Repair: remotion-setup${mode === 'project' ? ' --project' : ''}`); + } else { + console.log(`dir: ${result.dir}`); + console.log(`Official Remotion skills: ${result.found}/${result.expected} present`); + console.log(`status: ${result.complete ? 'COMPLETE' : 'INCOMPLETE'}`); + if (result.missing.length) console.log(`Missing:\n${result.missing.map((n) => `- ${n}`).join('\n')}`); + if (result.extra.length) console.log(`Extra (upstream topology may have changed):\n${result.extra.map((n) => `- ${n}`).join('\n')}`); + console.log(result.complete + ? 'Repair: none needed (use remotion-update to keep them current)' + : `Repair: remotion-setup${result.scope === 'project' ? ' --project' : ''} (repairs the detected scope — never a different one)`); + } + process.exit(result.scope === 'none' ? 2 : result.complete ? 0 : 1); +} diff --git a/plugins/zcode-remotion/skills/remotion/SKILL.md b/plugins/zcode-remotion/skills/remotion/SKILL.md new file mode 100644 index 0000000..7ee9dac --- /dev/null +++ b/plugins/zcode-remotion/skills/remotion/SKILL.md @@ -0,0 +1,188 @@ +--- +name: remotion +description: "Reliable Remotion video workflow for ZCode. Use when the user wants to create, edit, preview, animate, caption, render, export or troubleshoot a programmatic video; mentions Remotion; or says 视频/动画/宣传片/字幕/渲染/出片. Bootstraps Remotion's official Agent Skills, preflights the environment, routes to the right official skill, runs autonomous still-frame visual QA, and verifies the final MP4." +license: MIT +metadata: + author: AIwork4me + version: "0.2.5" +--- + +# Remotion Workflow — ZCode reliability layer + +Remotion's official Agent Skills contain the domain knowledge. This plugin does **not** replace or redistribute them. It makes the workflow reliable inside ZCode: bootstrap → preflight → official-skill routing → representative still → Agent visual QA → final render → output verification. + +## 0. Resolve packaged resources first + +Never assume the user's current working directory is the plugin repository. + +When a bundled helper is needed, resolve the installed plugin root from ZCode: + +```text +node -p "process.env.ZCODE_PLUGIN_ROOT || ''" +``` + +Call the printed absolute path `` and use: + +```text +node "/scripts/skill-paths.mjs" ... +node "/scripts/skill-names.mjs" +``` + +The expected official skill list comes only from `/compatibility/remotion.json`. + +## 1. Bootstrap gate — always check official skills before Remotion work + +Inspect skill integrity with: + +```text +node "/scripts/skill-paths.mjs" +``` + +Automatic discovery uses strict scope priority: + +1. project: `/.zcode/skills/` +2. user: `~/.zcode/skills/` +3. installer mirror: `~/.agents/skills/` + +The first scope containing **any** expected official skill is the detected installation. Scopes are never merged to manufacture a complete result. + +Interpret the result: + +- **COMPLETE** — every recorded official skill has `SKILL.md`; continue. +- **INCOMPLETE** — repair the detected scope; do not silently fill it from another scope. +- **absent** — bootstrap official skills, defaulting to user/global scope unless the user explicitly asks for project scope. + +Official installer — global/user scope: + +```text +npx -y skills add remotion-dev/skills -s '*' -y --copy -g +``` + +Project scope: + +```text +npx -y skills add remotion-dev/skills -s '*' -y --copy +``` + +`--copy` avoids Windows symlink privilege problems. + +If installation fails, preserve the requested scope and report the actual error. When GitHub is reachable, a direct fetch from the official `remotion-dev/skills` repository into that same scope is an acceptable recovery path. If truly offline and no cached copy exists, say the official skills cannot be installed now. Never report success without checking the files on disk. + +After install / repair, re-run the same scope check and require `COMPLETE`. + +The plugin's own skill and commands register with the plugin. Official Remotion skills installed externally are separate files; after creating or updating them, tell the user to open **Settings → Skills → Refresh** and confirm they are listed and enabled. Start a new conversation only if Refresh still does not surface them. + +## 2. Environment preflight + +Before creating or rendering: + +1. Run `node -v`; require Node >=18 (20/22/24 recommended). +2. Detect the project package manager by lockfile: `bun.lock` / `bun.lockb` → bun; `pnpm-lock.yaml` → pnpm; `yarn.lock` → yarn; `package-lock.json` → npm; otherwise npm by default. +3. For a new project, prefer the official Remotion scaffold (`npm create video@latest`, or the matching package-manager equivalent). +4. If an existing project is involved, inspect its Remotion versions before editing and keep all `remotion` / `@remotion/*` packages aligned. +5. Do not treat the plugin's recorded compatibility baseline as a ban on newer versions. It is the last verified state, not an incompatibility assertion. + +## 3. Route to Remotion's official skills + +Read the installed official `SKILL.md` files as needed and follow them rather than inventing a parallel Remotion API guide. + +| User intent | Official skill | +| --- | --- | +| Unsure / best-practices router | `remotion-best-practices` | +| Captions / subtitles / transcription presentation | `remotion-captions` | +| Create a new Remotion video project / composition | `remotion-create` | +| Look up Remotion APIs or documentation | `remotion-docs` | +| Studio editing / selectable or interactive elements | `remotion-interactivity` | +| Map animations | `remotion-maps` | +| Write / change React video markup, animation, typography, audio, fonts | `remotion-markup` | +| Media metadata, decoding, conversion, Mediabunny workflows | `remotion-multimedia` | +| Still / MP4 export | `remotion-render` | +| Product / SaaS rendering architecture and licensing context | `remotion-saas` | +| Preview in Remotion Studio | `remotion-studio` | +| Upgrade Remotion dependencies | `remotion-upgrade` | + +If upstream skill topology changes, inspect the installed `remotion-*` skills and current official source rather than guessing renamed skills. + +## 4. Mandatory no-rework render loop + +For requests that should produce a rendered deliverable, do not jump straight from generated code to a final MP4. + +### Step 1 — render a representative still + +Use the official render guidance to choose a frame that meaningfully represents the composition, for example: + +```text +npx remotion still out/frame.png --frame= +``` + +### Step 2 — Agent visual QA + +Actually inspect the generated image with the available image / vision capability. Check at least: + +- blank or failed render; +- missing image / font / asset; +- clipped or overflowing text; +- obvious overlap or broken layout; +- poor framing; +- unreadable typography or contrast; +- unexpected transparent / black areas; and +- obvious rendering artifacts. + +If an objective defect exists: fix the composition → rerender the still → inspect again. Iterate here before the full render. + +### Step 3 — decide without unnecessary user interruption + +If the representative still objectively passes, continue to the final render automatically. + +Ask the user only when: + +- the user explicitly requested approval; +- the remaining choice is genuinely subjective; +- brand / aesthetic intent is ambiguous; or +- visual confidence is low. + +Do not add a routine “is this frame OK?” checkpoint to an otherwise straightforward render. + +### Step 4 — full render + +Follow the official `remotion-render` guidance and use the project's package manager / CLI setup. Preserve the requested format, duration, dimensions and frame rate. + +### Step 5 — verify the delivered file + +Before saying the video is finished: + +1. confirm the render command succeeded; +2. confirm the expected MP4 exists; +3. confirm it is non-empty; +4. when `ffprobe` is available, verify a video stream exists and check duration / dimensions against the composition; and +5. report the output path and exactly what was verified. + +If `ffprobe` is unavailable, say so. Do not claim metadata verification that was not performed. + +## 5. Common failure triage + +| Symptom | Likely cause | Next action | +| --- | --- | --- | +| Official skills absent / incomplete | first install, partial install, wrong scope | run the `remotion-setup` workflow; verify the same scope on disk | +| `npx skills add` fails | Node / npm / network / GitHub access | preserve the scope, report the real error, then use the documented recovery ladder | +| Chrome Headless Shell download fails | blocked browser download / proxy | `npx remotion browser ensure`; inspect network/proxy; see https://www.remotion.dev/docs/chrome-headless-shell | +| Composition ID not found | composition not registered or wrong CLI ID | inspect `registerRoot` and `` | +| `delayRender()` timeout | unresolved render handle / async resource | make every `delayRender` reach `continueRender`; inspect async metadata/assets | +| Module not found | dependencies not installed / lockfile mismatch | run the detected package manager install and verify dependency resolution | +| Remotion packages disagree on versions | partial upgrade / workspace mismatch | use the `remotion-update` workflow and `npx remotion versions` | +| Licensing message | upstream license condition | explain Remotion's current terms and point to https://www.remotion.pro; never work around licensing checks | + +For unknown Remotion-specific errors, use the official `remotion-docs` and `remotion-best-practices` skills before inventing a workaround. + +## 6. Reporting standard + +A successful video task should end with concise evidence: + +- composition / output produced; +- representative still QA: PASS (and fixes made, if any); +- final render: PASS; +- MP4 path and file existence / size check; +- duration / dimensions verification when `ffprobe` was available; and +- any remaining limitation stated explicitly. + +Reliability means the claim must match the evidence that actually happened. From bc2cb39dcb9910b0fd526eee893eef565cd248ab Mon Sep 17 00:00:00 2001 From: AIwork4me Date: Wed, 2 Sep 2026 07:17:20 +0800 Subject: [PATCH 2/3] test(zcode-remotion): lock marketplace runtime contract --- tests/test_zcode_remotion_plugin.py | 97 +++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/test_zcode_remotion_plugin.py diff --git a/tests/test_zcode_remotion_plugin.py b/tests/test_zcode_remotion_plugin.py new file mode 100644 index 0000000..5d1294e --- /dev/null +++ b/tests/test_zcode_remotion_plugin.py @@ -0,0 +1,97 @@ +from __future__ import annotations + +import json +import re +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +PLUGIN = ROOT / "plugins" / "zcode-remotion" + + +def load_json(path: Path) -> dict: + return json.loads(path.read_text(encoding="utf-8")) + + +class ZCodeRemotionPluginTest(unittest.TestCase): + def setUp(self) -> None: + self.manifest = load_json(PLUGIN / ".zcode-plugin" / "plugin.json") + self.marketplace = load_json(ROOT / "marketplace.json") + self.entry = next( + p for p in self.marketplace["plugins"] if p["name"] == "zcode-remotion" + ) + self.compat = load_json(PLUGIN / "compatibility" / "remotion.json") + + def test_manifest_and_marketplace_contract_match(self) -> None: + self.assertEqual(PLUGIN.name, "zcode-remotion") + self.assertEqual(self.manifest["name"], "zcode-remotion") + self.assertEqual(self.entry["source"], "./plugins/zcode-remotion") + self.assertEqual(self.entry["version"], self.manifest["version"]) + self.assertEqual( + self.entry["description_i18n"], self.manifest["description_i18n"] + ) + self.assertEqual(self.entry["category"], "productivity") + + def test_official_skill_topology_is_canonical_and_not_vendored(self) -> None: + names = self.compat["skills"]["names"] + self.assertEqual(self.compat["skills"]["count"], 12) + self.assertEqual(len(names), 12) + self.assertEqual(len(names), len(set(names))) + self.assertTrue(all(name.startswith("remotion-") for name in names)) + + bundled_skill_dirs = { + path.name for path in (PLUGIN / "skills").iterdir() if path.is_dir() + } + self.assertEqual(bundled_skill_dirs, {"remotion"}) + self.assertTrue(set(names).isdisjoint(bundled_skill_dirs)) + + def test_router_mentions_every_recorded_official_skill(self) -> None: + router = (PLUGIN / "skills" / "remotion" / "SKILL.md").read_text( + encoding="utf-8" + ) + for name in self.compat["skills"]["names"]: + self.assertIn(name, router, f"missing routing coverage for {name}") + + version_match = re.search(r'^\s+version:\s*["\']?([^"\'\s]+)', router, re.M) + self.assertIsNotNone(version_match) + self.assertEqual(version_match.group(1), self.manifest["version"]) + + def test_packaged_helper_references_do_not_assume_workspace_is_plugin_root(self) -> None: + files = [ + PLUGIN / "skills" / "remotion" / "SKILL.md", + PLUGIN / "commands" / "remotion-setup.md", + PLUGIN / "commands" / "remotion-doctor.md", + PLUGIN / "commands" / "remotion-update.md", + ] + for path in files: + text = path.read_text(encoding="utf-8") + self.assertIn("ZCODE_PLUGIN_ROOT", text, path.name) + self.assertNotIn("node scripts/", text, path.name) + + def test_commands_have_descriptions(self) -> None: + for path in sorted((PLUGIN / "commands").glob("*.md")): + text = path.read_text(encoding="utf-8") + self.assertTrue(text.startswith("---\n"), path.name) + frontmatter = text.split("---\n", 2)[1] + self.assertRegex(frontmatter, r"(?m)^description:\s*\S") + + def test_bilingual_docs_disclose_execution_network_writes_and_licensing(self) -> None: + for filename in ("README.md", "README_CN.md"): + text = (PLUGIN / filename).read_text(encoding="utf-8").lower() + for required in ( + "node", + "npx", + "github", + "remotion-dev/skills", + "ffprobe", + "license", + ): + self.assertIn(required, text, f"{filename}: missing {required}") + + notice = (PLUGIN / "NOTICE.md").read_text(encoding="utf-8").lower() + self.assertIn("not redistributed", notice) + self.assertIn("remotion-dev/skills", notice) + + +if __name__ == "__main__": + unittest.main() From 9c7b9c0eabdcaf15cf78e54ceccc547506961659 Mon Sep 17 00:00:00 2001 From: AIwork4me Date: Wed, 2 Sep 2026 07:18:25 +0800 Subject: [PATCH 3/3] docs(zcode-remotion): clarify Marketplace provenance --- plugins/zcode-remotion/UPSTREAM.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/plugins/zcode-remotion/UPSTREAM.md b/plugins/zcode-remotion/UPSTREAM.md index 6cc8fbf..68e7ab4 100644 --- a/plugins/zcode-remotion/UPSTREAM.md +++ b/plugins/zcode-remotion/UPSTREAM.md @@ -1,21 +1,26 @@ # Upstream and provenance -This Marketplace package is derived from: +This Marketplace package is a **curated distribution adaptation**, not a byte-for-byte mirror, of: - Source repository: https://github.com/AIwork4me/zcode-remotion - Source version: `0.2.5` -- Source main commit used for this submission: `2a9903c2cfc167f11cbec3009a2d7b2161b03492` +- Source main commit used as the functional baseline: `2a9903c2cfc167f11cbec3009a2d7b2161b03492` -## Marketplace packaging adaptations +The product boundary is unchanged: Remotion's official Agent Skills provide Remotion domain knowledge; zcode-remotion adds ZCode-specific bootstrap, environment checks, routing, autonomous representative-frame visual QA, output verification, and compatibility awareness. -The official Marketplace package keeps the user-facing runtime layer and intentionally excludes repository-maintenance assets such as CI workflows, demos, verification reports, unit tests, release checks, and upstream-drift automation. +## Marketplace-specific adaptations -The following distribution-specific adjustments are applied without changing the product boundary: +The official Marketplace package intentionally excludes repository-maintenance assets such as CI workflows, demos, verification reports, source-project unit tests, release checks, and upstream-drift automation. -1. Add the bilingual `description_i18n` metadata required by the official Marketplace validator. -2. Provide Marketplace-specific English and Chinese READMEs that document network access, local command execution, file writes, dependencies, side effects, and licensing. -3. Resolve bundled helper scripts from the installed plugin root instead of assuming the user's current workspace is the source repository. Workflows first resolve `ZCODE_PLUGIN_ROOT` and then invoke the packaged scripts by absolute path. -4. Remove two duplicated prose fragments from the source skill/setup text while preserving the same behavior. +The installable layer is adapted for Marketplace distribution in these ways: + +1. Add the bilingual `description_i18n` metadata required by this Marketplace. +2. Provide Marketplace-specific English and Chinese READMEs that disclose network access, local command execution, file writes, dependencies, side effects, and licensing. +3. Refactor helper-script instructions so they resolve the installed plugin root through `ZCODE_PLUGIN_ROOT` instead of assuming the user's current workspace is the source repository. +4. Tighten and de-duplicate the Agent-facing skill / command instructions while preserving the same official-first workflow and reliability gates. +5. Use the Marketplace plugin ID `zcode-remotion` rather than the bare upstream product name `remotion`; the bundled auto-trigger skill remains named `remotion`. + +Because this is not byte-identical to the source repository release, source-project E2E / CI evidence is background evidence only. The official Marketplace artifact must pass this repository's own validation/build/tests and a live ZCode install check before the submission is considered verified. ## Third-party material