1实现原理 · 为什么它能做到
把「Figma → 合成」按能力拆成五个阶段:静态资产 / 品牌令牌 / 组件 / 运动 / 着色器;前三阶段走 REST + CLI,后两阶段没有 REST 对应物,只能靠连接器或原生导出。
Bring the user's Figma work into a composition. **Split by capability** (design spec §2):
REST 是默认通道(可批量、可无头),连接器只对运动/着色器是可选加分项;两条路都在导入期把资产冻结到本地,以保渲染确定性。
REST is used wherever it can be (usable at volume, headless). A compatible Figma connector is optional for motion and shader data; without one, ask for a native export. Every path freezes assets locally so renders stay deterministic.
第一步不是跑命令而是凭证预检:shell 环境或项目 .env 中须有 FIGMA_TOKEN 且只读即可;没有就先带用户做一次性设置再停下,禁止「先跑一下拿报错」。
**Preflight — before the first CLI call, check a token exists**: shell env (`[ -n "$FIGMA_TOKEN" ]`) **or** the project `.env` (the CLI auto-loads it — a `.env` entry counts as configured).
资产导入是幂等 + 冻结 + 留痕:按 fileKey:nodeId:format:scale:version 幂等,产物落 .media/images/,来源写进 manifest 并重建 media-use 的共享清单。
Idempotent per `fileKey:nodeId:format:scale:version`.
整帧取资产时把多个 node 合并为一次 /v1/images 调用以避开每分钟限流;storyboard 批量导出反而要分块(>~12 个 id 会 Render timeout,拆 ~4 个一组)。
All render in a single `/v1/images` call, which is figma's own answer to the per-minute rate limit
组件阶段把节点树重建成几何精确的可编辑 HTML,并做「按 ID、绝不按数值」的令牌绑定:绑到已导入令牌用 var(--slug, literal),绑到未知令牌保留字面量并打标记。
Bound to an **unknown** token → literal + `data-figma-unresolved` flag.
运动阶段是「机械解码 + 客观门禁」:连接器取回的 motion context 由纯 helper 解码(永不手抄关键帧、剥离 loop-wrap 尾帧),随后必须用 verify-motion.mjs 对比导出视频的运动能量,低于 15dB 判失败。
it compares motion-energy deltas (static import fidelity cancels out) and fails below 15dB min motion-PSNR
storyboard 段落按机械语法解码而非看图猜:场景单元按尺寸过滤、顺序按 x 坐标、相邻帧差分出元素链、每链只导一个资产;当逐帧其实是同一个产品界面时升级为「重建 UI + 每帧差当作一次交互」。
**The cardinal rule: storyboard frames are KEYFRAMES, not slides.**
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | hyperframes CLI 的 figma 子命令(asset / tokens / component)与 check 门禁 |
| api | Figma REST 批量渲染导出(host 未在 SKILL.md 出现,只写了路径) |
| api | Figma REST published-styles 回退(非 Enterprise 变量降级路径,需 library_content:read) |
| network | 用户粘贴的 figma.com 链接(解析 fileKey / nodeId 后走 REST);取 token 的引导页在 figma.com/settings |
| network | 可选的兼容 Figma 连接器(运动上下文与着色器数据;与本 skill 的 token 分开授权;未指名具体服务) |
| package | @hyperframes/core/figma 纯 helper(motionContextToDocs 解码、motionToGsap、emitTimelineScript) |
| cli | ffprobe / ffmpeg(仅 verify-motion.mjs 以数组参数子进程调用,抽帧与 PSNR) |
| network | GSAP + CustomEase CDN(注入合成 HTML 的 script 标签;产物期由浏览器拉取,按范式不判级) |
4风险提醒 风险提醒:橙色 · 评估后使用
- 凭证进项目:.env 会被 CLI 自动加载 — SKILL.md 明说项目 .env 里的 FIGMA_TOKEN 算已配置。这在多项目/共享目录下意味着 token 落在项目路径内即被读取;用户应确认项目目录的信任边界(该表述本身是便利设计,不是漏洞)。
- 不可信画布内容进入模型上下文 — 图层名、文本节点(尤其被当作运动意图的导演笔记)与原始 JSON 直接进上下文;来自他人 Figma 文件的指令式文本理论上可影响生成与时间线。
- 依赖可选连接器,且其来源未被指名 — 运动与着色器阶段完全依赖「a compatible Figma connector」,SKILL.md 未指名是哪一个、由谁发布,也要求它是独立授权——使用者需自行判断该连接器的可信度;缺它时这两阶段基本不可用。
- 平台与工具前提未在本 skill 内声明 — 资产导出/校验链路依赖 Node 22+ 与 FFmpeg(ffprobe/ffmpeg 直接以子进程调用),无这些环境时 verify-motion.mjs 会直接失败;SKILL.md 未给出前提清单。
- REST 细节不可回源 — Figma REST 的 host 与请求实现不在本目录内(由官方 CLI 承担),本报告只能对路径与语义取证,无法核对真实请求构造。
5第二遍独立确认
- [ok] FIGMA_TOKEN 是否真被读取并用于外发(橙档判定的关键证据) — SKILL.md 第 26 行给出预检(`[ -n "$FIGMA_TOKEN" ]` 或项目 .env),第 28–30 行给出取 token 的一次性设置与「never ask them to paste the token into the conversation」;第 36 行给出 401/403/429 的处置语义。读取与实际 REST 调用发生在官方 hyperframes CLI 侧,本 skill 的目录只声明并约束该行为——与 hyperframes-cli 同口径,故橙档依据记在 SKILL.md 的声明面,并注明执行主体。
- [unlocatable] Figma REST 的具体 host 能否在源码内定位 — SKILL.md 只写出路径(`/v1/images`、`/v1/files/:key/styles`),未出现 api.figma.com 或任何 host;连接器也未指名具体服务。故 external_deps.endpoint 按「仅路径」标注,不补写推测域名。
- [ok] verify-motion.mjs 的外部接触面(是否有隐藏网络/凭证/越界写入) — 全文 154 行只 import node:child_process / node:fs / node:os / node:path;调用为 execFileSync("ffprobe", …)、execFileSync("ffmpeg", …)、spawnSync("ffmpeg", …) 三处,全部数组参数无 shell;无 fetch、无 process.env、无凭证;写入仅限 mkdtempSync(join(tmpdir(), "verify-motion-")) 下的临时图,结束 rmSync 清理。阈值与标定写在文件头注释里(忠实 min 20.3dB / 发散 min 5.0dB,默认阈值 15dB)。
- [ok] 「连接器不执行 shader、会压平」这一关键警告是否自洽(会不会是夸大) — Phase 5 段与 Phase 4 步骤 4 的例外说明互相印证:两处都指向「请用户原生导出」,且 Phase 4 明确 shader 轨道烘焙会静默丢 shader。属同一声明的两处一致陈述,非矛盾。
- [ok] 「分镜帧是关键帧而非幻灯片」是否只是口号 — 同一段给出可机械执行的规则:场景单元按尺寸(如 >1400×900)过滤、顺序按 absoluteBoundingBox.x、相邻帧按 name 再按几何相似匹配成元素链、每链一资产、批量导出分块(~4/次,26 场景 ≈52 次单资产调用是反面教材),并给出升级判据(同一 UI 逐帧 → 重建 app、把帧差当作交互)。
6结论
22ae9717e5a19361…d2f0bc7f34