figma
Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.
1How It Works & Mechanism
Breaks down 'Figma → Composition' into five capability-based phases: Static Assets / Brand Tokens / Components / Motion / Shaders. The first three phases operate via REST + CLI, while the latter two lack REST counterparts and rely strictly on connectors or native exports.
Bring the user's Figma work into a composition. **Split by capability** (design spec §2):
REST serves as the default channel (batchable, headless), whereas connectors are optional enhancements solely for motion/shaders; both paths freeze assets locally during import to guarantee rendering determinism.
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.
Step one performs credential pre-checks rather than immediately running commands: FIGMA_TOKEN must exist in the shell environment or project .env with read-only permissions; if absent, guide the user through a one-time setup and halt, strictly forbidding 'running blindly to catch errors'.
**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).
Asset import follows idempotency + freezing + provenance tracking: deduplicated by fileKey:nodeId:format:scale:version, stored in .media/images/, logged to the manifest, and used to rebuild the shared media-use catalog.
Idempotent per `fileKey:nodeId:format:scale:version`.
Combines multiple nodes into a single /v1/images call when fetching assets for an entire frame to bypass per-minute rate limits; conversely, chunks storyboard batch exports (>~12 IDs trigger render timeouts, split into ~4 per chunk).
All render in a single `/v1/images` call, which is figma's own answer to the per-minute rate limit
The component phase reconstructs the node tree into geometrically precise, editable HTML and performs token binding strictly 'by ID, never by raw value': bound to imported tokens using var(--slug, literal), while retaining literals and flagging unknown tokens.
Bound to an **unknown** token → literal + `data-figma-unresolved` flag.
The motion phase enforces 'mechanical decoding + objective gating': connector-retrieved motion context is decoded via pure helpers (never manually transcribing keyframes, stripping loop-wrap trailing frames), then strictly verified using verify-motion.mjs against reference video motion energy, failing below 15dB.
it compares motion-energy deltas (static import fidelity cancels out) and fails below 15dB min motion-PSNR
Decodes storyboard sections via mechanical syntax rather than visual guesswork: filters scene units by size, sorts sequence by x-coordinate, derives element chains from adjacent-frame diffing, and exports only one asset per chain; upgrades to 'reconstructing UI + treating frame diffs as interactions' when frames depict the same interface.
**The cardinal rule: storyboard frames are KEYFRAMES, not slides.**
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| 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 标签;产物期由浏览器拉取,按范式不判级) |
4Recommended Governance & Evidence
- scripts/: Local script and command execution: node skills/figma/scripts/verify-motion.mjs --reference <export.mp4> --rend
- 网络端点: Declared external network access: Figma REST read-only endpoints (/v1/images batch export, /v1/files/:key/styles fallback, node tree, variable
- 本地工作目录: File I/O and artifact output: .media/images/ (frozen Figma rendered assets), .media/manifest.jsonl (provenance ledger), .media/index.md (
5Second-Pass Verification
- [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、把帧差当作交互)。
6Verdict & Scenarios
22ae9717e5a19361…