1实现原理 · 为什么它能做到
先做静态 lint 判定「能不能翻译」:脚本用规则扫 Remotion 源码,把发现分成 blocker(拒译并改荐运行时互操作)/ warning(丢掉该构造后照译,但要在 TRANSLATION_NOTES.md 记缺口)/ info(翻译并注明)三级。
Blockers (skill should refuse to translate): - r2hf/use-state React state machine drives animation - r2hf/use-effect-deps useEffect/useLayoutEffect with non-empty deps (side effects) - r2hf/use-reducer useReducer drives animation - r2hf/async-metadata calculateMetadata returns a Promise - r2hf/third-party-react-ui Imports a React UI library (shadcn, mui, antd, mantine, chakra)
翻译是机械映射 + 按需加载专题参考:api-map.md 是索引,按源码里出现的 API 只加载对应专题(parameters/sequencing/timing/media/transitions/lottie/fonts),不一次全读。
Translate Remotion (React-based) video compositions into HyperFrames (HTML + GSAP) compositions. Most Remotion idioms have direct HyperFrames equivalents — the translation is mechanical for ~80% of typical compositions. This skill encodes the mapping and guards against the lossy 20% by refusing to translate patterns that don't fit HF's seek-driven model
产出形态固定:一个 <div id="stage"> 携带 composition-id/start/duration/fps/尺寸与每个标量 prop 的 data-*,场景 div 平铺带 data-start/data-duration/data-track-index,底部一个 paused GSAP 时间线并注册到 window.__timelines。
A single `<script>` tag at the bottom containing one paused `gsap.timeline({paused: true})`. Every Remotion `useCurrentFrame()` derivation becomes a tween on this timeline at the right offset. - `window.__timelines["<composition-id>"] = tl;` registers the timeline with HF's runtime.
验收不是「看起来对」而是可量化的 SSIM:随包四级测试语料 T1–T4 给出各家平均 SSIM 与阈值基线,并要求两侧渲染使用相同像素格式否则量到的是编码器差异。
Threshold: ~0.02 below `p05` of the source's complexity tier (see `eval.md`'s validated thresholds table). If the diff fails, run [`scripts/frame_strip.sh`](scripts/frame_strip.sh) to see _which_ frames diverged, then re-read the relevant timing/sequencing/media reference.
差异调试有专用工具:frame_strip.sh 生成「基准帧 | 翻译帧」并排条带图定位是哪几帧跑偏;render_diff.sh 输出逐帧 SSIM 并落 summary.json(mean/min/p05/p95/frame_count/pass)。
# render_diff.sh — compute per-frame SSIM between two video files. # # The eval primitive for the remotion-to-hyperframes skill: given a Remotion # render and a HyperFrames render of the same composition, report whether the # translation is visually equivalent.
缺口必须留痕:任何没干净翻译的东西(音量斜坡、自定义 presentation、字体替换)都要写成 HF 输出旁的 TRANSLATION_NOTES.md;并明确列出本 skill 不做什么(反向导出、非 Remotion 来源、React 状态机、与 Remotion 并行运行渲染管线)。
Anything that didn't translate cleanly (volume ramps dropped, custom presentations approximated, fonts substituted) gets a `TRANSLATION_NOTES.md` written next to the HF output.
2核心能力
3外部依赖
| Kind | Dependency / Endpoint |
|---|---|
| cli | hyperframes CLI(渲染翻译产物:npx hyperframes render --skill=remotion-to-hyperframes) |
| cli | Remotion CLI(生成基准渲染:npx remotion render <CompositionId> out/baseline.mp4) |
| cli | ffmpeg / ffprobe(SSIM 比较、帧抽取、条带拼图;脚本缺它即 exit 2) |
| cli | python3(lint_source.py 与 frame_strip.sh 内嵌的 python 片段) |
| package | HF 侧可选包(shader-transitions / lottie 适配器等,由 api-map 引用;HF 侧的 blocks 目录) |
| network | 文档外链(仅参考;fonts.md 里的 Google Fonts 预连接示例属于产出 HTML 的写法,非本 skill 调用) |
| cli | hyperframes skills update(自刷新,需网络) |
4管控建议与判定依据
- scripts/: 执行本地脚本或命令: python3 scripts/lint_source.py <remotion-src> [--json](静态文本分析被扫描目录;不执行被扫描代码
- 本地工作目录: 文件读写与工件输出: 翻译产物:hf-src/index.html(HF 合成)与 TRANSLATION_NOTES.md
5第二遍独立确认
- [ok] 是否真的零网络 / 零凭证(蓝档判定的关键) — 脚本层 fetch/curl/wget/http.request 0 命中;process.env 命中仅 3 处且在 tier-4 的 validate.sh 里读路径变量;无 API_KEY/TOKEN/SECRET/.env/Bearer 命中。27 处 URL 全部可解释为文档链接、示例 HTML 资源或测试夹具端点。
- [ok] 测试夹具里的 fetch / example.com 是否会被执行(是否构成隐藏外发) — 逐文件确认:tier-4 的 8 个 .tsx 与 scripts/tests/fixtures/*.tsx 只被 lint_source.py 以文本方式扫描(脚本无 subprocess/无 import 被扫描模块),run.sh 的 T4 分支只跑 lint 校验('It runs T1, T2, T3 (render + diff) and T4 (lint validation)')。不会被渲染或执行,因此不构成外发。
- [ok] 『外部资源』逐条回查调用点 — npx remotion render 与 npx hyperframes render 在 SKILL.md Step 4 原文;ffmpeg/ffprobe 的存在性检查与调用在 render_diff.sh/frame_strip.sh 原文;python3 调用在 frame_strip.sh 原文;shader-transitions 与 lottie 适配器链接在 api-map.md/lottie.md 原文。无推测项。
- [ok] lint 规则是否真能拦住它宣称拦的东西(blocker 是否只是文档口号) — lint_source.py 的 docstring 与 THIRD_PARTY_UI_PACKAGES 集合、rule id(r2hf/use-state、r2hf/use-effect-deps、r2hf/use-reducer、r2hf/async-metadata、r2hf/third-party-react-ui 等)在源码中真实存在,并配有 8 个 tier-4 用例与 validate.sh 断言('8/8 pass' 基线)。规则实现与文档口径一致。
- [unlocatable] 验证:SSIM 阈值基线表是否可在源码内复算 — SKILL.md 的基线表(T1 0.974、T2 0.985、T3 0.953、T4 8/8,日期 2026-04-27)是历史测量值;复算需要执行 Remotion 与 HF 两条渲染管线(本任务禁止构建/渲染,且环境未验证具备 Remotion)。故该表按『文档声明』记录,不在结论中当作已验证事实。
- [ok] meta.official_desc 与 SKILL.md 原文的逐字比对(体检工具的 ⚠ 项) — 本 skill 的 frontmatter 用 YAML 单引号风格书写:`description: 'Port an existing Remotion (React) composition''s source to …'`——文件里的两个连续单引号是 YAML 的转义语法,解析后的字符串值是带**一个**撇号的 `composition's`。本 JSON 的 meta.official_desc 记录的是解析后的真实描述文本(与 YAML 解析结果一致),因此对**原始文件字节**做朴素逐字比对时会出现一处不可避免的差异(源码里的 `composition''s` vs 记录值的 `composition's`)。这不是改写,也不影响展示层:如实记录为报告口径差异,而非内容出入。
6结论
7dc73746cff19b96…