插件安装: 在执行 setup 或 freshness 命令前,若此技能位于 HyperFrames 插件内部,请遵循插件安装规则。独立安装则沿用下方更新指引。
首先,保持技能更新——运行前请与用户确认:
npx hyperframes skills update figma。若一切已是最新,则为快速无操作;否则将刷新此技能及其依赖的核心领域技能。
Figma → HyperFrames 是做什么的?
将用户的 Figma 作品导入合成场景。按能力拆分(设计规格 §2):
| 阶段 | 内容 | 传输方式 | 接口 |
|---|---|---|---|
| 1 | 静态资源 | REST | hyperframes figma asset |
| 2 | 品牌令牌/样式 | REST | hyperframes figma tokens |
| 3 | 组件 → HTML | REST | hyperframes figma component |
| 4 | 动效 → GSAP | 连接器(可用时) | 使用其动效上下文 |
| 5 | 着色器 | 连接器 / 手动导出 | 使用或原生导出 |
REST 在可用的地方都会使用(支持大规模、无头操作)。可兼容的 Figma 连接器用于动效和着色器数据为可选;若无连接器,请请求原生导出。每条路径都会在本地冻结资源,确保渲染确定性。故事板重建组合阶段 1 的资源导出(REST)与代理驱动的时间线组装——无需连接器。已有的冻结资源、清单记录和绑定不受路由变化影响——拆分仅改变下次导入使用的凭证。
认证——两种凭证,范围限定
预检——在首次 CLI 调用前,检查令牌是否存在:Shell 环境变量([ -n "$FIGMA_TOKEN" ])或项目 .env(CLI 自动加载——.env 条目视作已配置)。若两者均不存在,请不要运行命令以获取错误——先引导用户完成一次性设置,然后停止并等待:
- figma.com/settings → 安全 → 个人访问令牌 → 生成新令牌。
- 范围——本集成仅需只读权限(从不写入 Figma):文件内容:只读 + 文件元数据:只读。若你将在非 Enterprise 计划上运行
tokens,请添加库内容:只读——已发布样式的回退机制会访问/v1/files/:key/styles,若无此范围会返回 403(旧版设置文本遗漏了此范围)。可选:变量:只读用于品牌变量——仅限 Enterprise;无此范围时,tokens会自动降级为已发布样式(预期行为,非错误——请说明)。现在 403 会指明缺失的具体范围;429 会自动重试(按分钟限制,遵循Retry-After)。 - 让用户在 Shell 配置文件或项目
.env中设置FIGMA_TOKEN;切勿要求他们将令牌粘贴到对话中。
在 onboarding 过程中,同时设定预期:每次导入都会生成本地冻结文件,带有记录来源——渲染从不调用 Figma,重新运行命令仅重新导入 Figma 中更改的内容,一个令牌可用于所有用户 Figma 账户可查看文件中的资源、品牌令牌和组件。
- 阶段 4–5(动效/着色器): 需要一个兼容的 Figma 连接器,其授权与令牌分开。若连接器不可用或未认证,请用户连接它或提供原生导出,然后停止。
- 明确说明失败阶段所需的凭证——切勿将拆分描述为中断。
- 流程中出现
BAD_TOKEN(401)→ 令牌已过期/撤销;需重新生成。FORBIDDEN(403)→ 消息会指明缺失的具体范围(例如样式回退所需的library_content:read)——添加它,或文件对账户不可见。REQUIRES_ENTERPRISE(变量相关 403)→ 非失败:样式回退已运行。RATE_LIMITED(429)→ 客户端已使用退避重试(适用于每次读取——资源、令牌、样式、节点树、版本——重试逻辑位于共享请求路径;遵循Retry-After,上限 60 秒);若仍出现,请等待一分钟或减少每次调用的节点数。
速率限制感知(规格 §2.1): 连接器配额因 Figma 计划而异——批量处理父帧请求,跳过验证截图(除非要求),缓存原始响应以避免二次调用。REST 按分钟计算(10+/分钟,按端点桶划分)——大规模下表现良好,遇 429 则退避。
路由
使用 parseFigmaRef 解析用户的 Figma 链接(URL、fileKey:nodeId、裸 fileKey)。然后按意图路由:
- "使用这个图层/标志/图像" → 资源(CLI)
- "拉取我的品牌/颜色/令牌" → 令牌(CLI)
- "从此帧构建场景" → 组件(CLI)
- "导入此动画/动效" → 动效(连接器可用时,见下方)
- 故事板片段/场景帧序列 → 故事板(见下方)
- 着色器填充/效果 → 着色器(见下方)
为用户解说每一步——在每个命令前说明即将从 Figma 拉取什么;之后说明工件的落点(冻结路径/sidecar/组件目录)、合成场景的变化以及下一步操作(预览、添加打印变量、重新导入以链接绑定)。用户永远不需要问“它工作了吗?”或“现在怎么办?”。
资源(阶段 1 — CLI)
hyperframes figma asset '<url-or-fileKey:nodeId>' [更多引用…] [--format svg|png|jpg|pdf] [--scale 2] [--description "..."] [--entity "..."]
通过 REST 渲染,清理 SVG,冻结到 .media/images/ 下,追加带来源的清单,重新生成 .media/index.md(共享媒体使用清单),打印 <img> 片段。每个 fileKey:nodeId:format:scale:version 具有幂等性。矢量/标志优先使用 SVG(可缩放、可动画化),栅格保真度使用 PNG --scale 2。始终传递 --description "<what it is>"(它成为索引行 + <img alt>);为命名品牌标志添加 --entity "<name>",以便后续媒体使用 resolve --entity 可找到它们(实体命中可跨图像/图标匹配)。
在 一次请求中批量处理多个节点——传递同一文件的多个引用(空格分隔或逗号连接):hyperframes figma asset 'KEY:1-2' 'KEY:3-4' 'KEY:5-6'。所有内容通过一次 /v1/images 调用渲染,这是 Figma 自身应对分钟速率限制的方案——在拉取一整帧资源时优先使用,而非 N 个单独命令。--description/--entity 适用于批次中的每个节点,因此请将用途相同的节点分在一批。429 也会自动退避重试。
令牌(阶段 2 — CLI)
hyperframes figma tokens <fileKey>
将变量导入为合成品牌变量条目 + figma-tokens.json sidecar + 绑定索引记录(.media/figma-bindings.jsonl)。变量上游受 Enterprise 限制:其他计划下命令降级为已发布样式元数据(值在组件导入时解析)。将打印的条目添加到合成的 data-composition-variables。
如需同时导入令牌和组件,请先导入令牌——这样组件颜色可链接到品牌变量,而非产生重复值。
非 Enterprise 变量路径(经过实地测试): REST 变量受 Enterprise 限制,但兼容的连接器可能提供变量定义。当 tokens 报告 REQUIRES_ENTERPRISE 且连接器可用时,检索父场景的变量一次,将原始响应缓存到 .media/figma-cache/,并用其构建绑定索引。REST 节点树的 boundVariables 提供每个属性的 VariableID;按节点和属性连接它们,然后写入 .media/figma-bindings.jsonl 行({kind:"binding", figmaId, sourceFileKey, compositionVariableId: "figma:<name>", version})以及合成变量条目。所有下游功能(组件 var() 解析、刷新、运行时 CSS 变量)均使用现有机制。向用户说明:"通过 Figma 连接器获取令牌——Enterprise 计划可直接从 hyperframes figma tokens 获得。"
运行时将每个声明的合成变量定义为 CSS 自定义属性(文档根元素 + 子组合宿主),因此导入的 var(--slug, literal) 在变量默认值变化时可实现重新着色——更新 data-composition-variables 中的一个值即可重新品牌所有导入的组件,无需重新导入任何内容。hyperframes render --variables '<json>' 可在渲染时覆盖它们。
组件(阶段 3 — CLI)
hyperframes figma component '<url-or-fileKey:nodeId>'
节点树 → 精确 Figma 几何尺寸的可编辑 HTML,打包为 compositions/components/<name>/ 下的注册表项。矢量/布尔运算通过阶段 1 导出自动栅格化。绑定传递(规格 §7.1,仅精确 ID——绝不值匹配):
- 静态保真度自检(关键内容必做): 导入后,渲染片段并与 Figma 自身像素比较——
figma asset <same node> --format png作为基准。文本是已知偏差轴:Figma 文本框高度短于行高时,边界会被垂直修剪(映射器会为这些情况输出text-box-trim;未使用时的实测偏差约为 70px 字体上的 6px)。若比较显示映射器未覆盖的偏差,请报告——不要静默手动调整片段。 - 填充绑定到已导入令牌 →
var(--slug, #literal)——品牌刷新可传播。 - 绑定到未知令牌 → 原始值 +
data-figma-unresolved标志。命令会告知你;用户可选:对源文件(或库文件)运行tokens,然后重新导入组件以链接它们。对每个未知库只问一次是哪个文件——绝不猜测,绝不按十六进制值匹配。
动效(阶段 4 — 连接器辅助)
使用信标: 连接器辅助阶段没有 CLI 触点,因此在开始和结束时触发技能信标(匿名、征得同意、绝不失败):开始时运行 npx hyperframes events --skill=figma-motion,完成时运行 npx hyperframes events --skill=figma-motion --event=skill_completed --outcome=success|error。着色器(figma-shaders)和故事板(figma-storyboard)同理。
无 REST 等效实现。当兼容连接器可用时,使用它并将输出传递给 @hyperframes/core/figma 中的纯辅助函数;否则请求原生导出:
- 通过一次递归请求获取父帧的动效上下文,而非每个元素一次请求。将原始 JSON 保存到项目旁(
.media/figma-cache/)以便免费重新翻译。 - 使用
@hyperframes/core/figma中的motionContextToDocs(rawResponse, { selectorFor, repeat })标准化为MotionDocs——绝不手动转录关键帧编号。该辅助函数机械地编码了经过实地测试的解码规则:它解析 motion.dev 片段(可靠的编码——CSS 片段会拉伸持续时间且可能不一致;被忽略),剥离循环包裹尾部关键帧(时间约为 0.9999→1 的子毫秒段是循环的瞬时重置,非作者动效——包裹由repeat重启实现),并逐字保留贝塞尔缓动。selectorFor必须返回阶段 3 组件导入中的 ID——不要从节点名称派生选择器。 2b. 在完成前必须对照基准验证:通过可用连接器导出群组的根帧,并运行node skills/figma/scripts/verify-motion.mjs --reference <export.mp4> --render <render.mp4> --crop WxH+X+Y——它比较动效能差(静态导入保真度抵消),低于 15dB 最小动效 PSNR 则失败(校准:忠实 ≈ 20+,偏离 ≈ 5)。从渲染的实际卡片边缘测量--crop,不要猜测。FAIL 意味着重新检查翻译,而非阈值。 motionToGsap(doc)→emitTimelineScript(spec)→ 在 GSAP + CustomEase CDN 标签后注入为<script>。暂停、有限、使用字面量键注册在window.__timelines上。- 无法翻译的轨道(着色器驱动、不支持的属性、复杂遮罩)→ 通过连接器导出,冻结 MP4,然后嵌入为
<video class="clip">。例外:着色器驱动轨道——Figma 的导出路径将着色器扁平化为基色(见下方着色器),因此在那里烘焙会静默丢失着色器;请用户改为原生 Figma 导出。始终说明你使用了哪条路径及原因。映射集之外的命名缓动回退为线性——映射表位于motionEase.ts;回退发生时向用户标记。 - 完成前运行
npx hyperframes check。
着色器(阶段 5 — 主要手动)
Figma 的连接器渲染路径不执行着色器(它们会扁平化为基色),并且着色器源代码仅对库发布样式(付费 Full 席位)可访问。默认路径:请用户在 Figma 中原生导出着色器帧(PNG 或动效 MP4),然后作为阶段 1 资源/剪辑导入。不要尝试通过连接器像素捕获着色器——它会静默产生错误结果。
故事板(场景帧片段 → 动画)
首要规则:故事板帧是关键帧,而非幻灯片。 包含同一元素的两帧描述该元素随时间变化的状态——在状态之间对元素进行动画处理;绝不要将帧作为静止序列播放。一个标志在四个连续帧中 y 坐标递减,是一个元素通过四个关键帧上升。逐帧播放故事板是失败模式;重建它们隐含的元素时间线才是任务。
故事板文件遵循可机械解析的语法——不要用肉眼判断,而是解码:
- 场景单元: 在 SECTION 内部,每个帧大小的节点都是一个场景——既包括命名的 FRAME,也包括松散的满帧 RECTANGLE(设计师直接将静态图片粘贴到片段中)。按大小过滤(≈ 合成宽高比,例如 >1400×900),而非按节点类型或名称。
- 顺序 = x 位置(如果条带换行,则按行优先)。按
absoluteBoundingBox.x对场景排序。 - 对相邻场景进行差异比较: 从场景 1 到 2,从 2 到 3,以此类推。对每对场景,
diff(FrameA, FrameB)产生:(a)保持不变的节点 → 无动画;(b)仅 x/y 变化 → 平移过渡;(c)比例/旋转变化 → 变换;(d)透明度变化 → 淡入淡出;(e)新节点 → 从属性(例如opacity:0或transform起始)入场;(f)消失节点 → 出场。差异比较器必须考虑资源 vs. 实例:同一组件实例的两个变体应视为变化,而非替换。 - 为每对场景构造时间线: 对每个变化使用
fromTo(),持续时间 = 场景持续时间(从absoluteBoundingBox.x之间的可配置毫秒值导出,或由用户指定)。缓动:Figma 不存储帧间缓动,因此使用"power2.out"除非另有指定(且应作为可覆盖默认值告知用户)。默认持续时间为 500ms。 - 将时间线缝合到主 GSAP 时间线: 每个场景批次的
previousSceneDuration延迟,因此序列流畅播放。 - 包含阶段 1 资源引用: 场景内引用的图像应作为
<img>元素存在,其src指向冻结路径。 - 验证与迭代: 运行
npx hyperframes check,然后npx hyperframes preview。如果场景之间的转换不连贯,调整默认持续时间或缓动。
简单语法示例(供参考——实际使用机械解码): 一个包含两个圆圈的故事板:Frame1 中圆圈在 (0,0),Frame2 中在 (100,0)。差异比较器检测到 cx 从 0 变为 100 → 生成 fromTo({ cx:0 }, { cx:100 }) → 缝合到主时间线。
错误诊断(快速参考)
| 错误 | 原因 | 响应 |
|---|---|---|
401 BAD_TOKEN | 令牌过期或已撤销 | 重新生成令牌。 |
403 FORBIDDEN | 缺失范围 | 消息提及缺失的范围(例如 library_content:read)——添加它。 |
403 REQUIRES_ENTERPRISE | 变量仅限 Enterprise | 非失败;令牌已自动降级为已发布样式(如果使用连接器则使用连接器回退)。 |
429 RATE_LIMITED | 超出速率限制 | 已使用退避重试;若持续出现,请稍后再试或减少节点。 |
| 连接器不可用 | 阶段 4–5 无 REST 等效 | 请用户安装/认证 Figma 连接器,或提供原生导出。 |
| 着色器静默错误 | 连接器扁平化着色器 | 请用户提供原生 Figma 导出。 |
| 故事板不连贯 | 差异比较器输出不正确 | 检查 diff() 是否考虑资源等效性和组件实例;验证 fromTo() 轨迹。 |
Figma → HyperFrames 技能 – 版本 1.0.0