设计文件与组件库的区别在于标识。设计文件有形状。组件库有具名、可复用、带稳定标识符的部件。components/inventory.json 是 figmascope 对以下问题的回答:"这个设计中哪些部分是组件,实例如何链接回其定义?"
数据结构
components/inventory.json 是一个对象数组:
[
{
"id": "789:012",
"name": "PrimaryButton",
"type": "COMPONENT"
},
{
"id": "789:013",
"name": "SecondaryButton",
"type": "COMPONENT"
},
{
"id": "890:100",
"name": "Button",
"type": "COMPONENT_SET"
},
{
"id": "890:101",
"name": "Button/Primary/Default",
"type": "COMPONENT"
},
{
"id": "890:102",
"name": "Button/Primary/Pressed",
"type": "COMPONENT"
}
]
每个条目有三个字段:
id:Figma 节点 ID,在同一文件的不同会话中保持稳定。name:来自 Figma 的组件名称。对于 COMPONENT_SET 中的变体,Figma 使用斜杠表示法:Button/Primary/Default。type:"COMPONENT"(单个组件定义)或"COMPONENT_SET"(变体组)。
这是完整的数据结构。它有意保持最小化。
实例如何链接回来
从实例到清单的链接在逐屏 IR 中。作为组件 INSTANCE 的任何节点都携带 componentId 和 componentName:
// screens/home.json
{
"kind": "stack",
"id": "555:201",
"componentId": "789:012",
"componentName": "PrimaryButton",
"axis": "horizontal",
...
}
componentId 与 inventory.json 中的 id 匹配,componentName 与 name 匹配。两个字段都存在,因此 Agent 无需加载 inventory.json 就能获取名称——但如果需要知道该组件是否属于 COMPONENT_SET,则通过交叉引用清单获取。
这就是编程 Agent 知道屏幕上的按钮节点不是需要详细重现的自定义布局——它是 PrimaryButton 的一个实例,应该调用现有的 PrimaryButton() 可组合函数,而不是根据 IR 的结构细节生成新代码。
没有组件标识,Agent 在每个屏幕上从头生成相同的按钮。有了组件标识,Agent 调用现有的可组合函数,完全跳过结构性代码生成。区别在于:你得到的是 40 个
Row { Text(...) Surface { ... } }块,还是 40 个PrimaryButton(...)调用。
为什么这对重构安全性很重要
设计系统会被重构。按钮可能获得新的形状、新的内边距、不同的颜色。如果所有生成的代码都是字面上的结构代码,重构意味着要修改每个有按钮的屏幕。如果生成的代码使用了 PrimaryButton 可组合函数引用,重构只需修改一个文件。
清单使这成为可能,它在生成时建立了契约:"这个节点不是自定义布局,它是已知组件的实例。"遵守这一契约的 Agent 生成的代码已经为组件级重构做好了结构准备。
这是相对于基于截图的交付方式的主要结构优势。截图中的按钮是像素,没有标识。从截图工作的 Agent 会在每个屏幕上为按钮生成结构代码,总是如此。从带有清单链接的 IR 工作的 Agent 可以识别实例并使用组件引用。
COMPONENT 与 COMPONENT_SET 的区别
Figma 的组件系统有两个层次。COMPONENT 是单个定义。COMPONENT_SET 是变体的容器——Figma 称之为"变体"(例如,具有 Primary/Secondary/Destructive 和 Default/Hovered/Pressed 状态的按钮)。
实际上,屏幕中的实例总是引用一个 COMPONENT(特定变体),而不是 COMPONENT_SET。COMPONENT_SET 的存在是为了让 Agent 在需要实现组件状态机时了解完整的变体集合。
// 按钮集的清单条目
{ "id": "890:100", "name": "Button", "type": "COMPONENT_SET" }
{ "id": "890:101", "name": "Button/Primary/Default", "type": "COMPONENT" }
{ "id": "890:102", "name": "Button/Primary/Pressed", "type": "COMPONENT" }
{ "id": "890:103", "name": "Button/Secondary/Default", "type": "COMPONENT" }
// 屏幕 IR 中的实例引用特定变体
{ "componentId": "890:101", "componentName": "Button/Primary/Default" }
为此生成 Compose 代码的 Agent 知道:该组件是具有 Primary 样式和 Default 状态的 Button。它可以推断函数签名可能涉及 style: ButtonStyle 和 state: ButtonState 参数,或者至少将 Button/Primary/Default 用作处于默认状态的主按钮的语义引用。
300 条目上限
figmascope 将 inventory.json 限制在 300 条目以内。规模较大的 Figma 文件——尤其是拥有详尽组件库的设计系统——可能有数千个组件。将所有组件都包含在发送给 LLM 的上下文包中,会用实现所需屏幕时不会用到的定义填充上下文窗口。
当达到上限时,清单中会出现一个 _truncated 字段:
[
{ "id": "...", "name": "...", "type": "COMPONENT" },
...
{ "_truncated": true, "totalCount": 847, "included": 300 }
]
totalCount 告诉你文件中有多少组件,included 告诉你有多少进入了清单。排序按照 Figma 节点树中首次遇到的顺序,因此文档早期引用的组件(通常是主屏幕)更可能被包含。
如果你正在处理使用文档后期定义的组件的屏幕,而这些组件不在清单中,IR 中这些实例的节点仍然携带 componentId 和 componentName——即使组件未列在清单中,标识信息也会保留。Agent 从 IR 中知道组件的名称,即使没有清单条目。
清单不包含的内容
清单是标识列表,不是实现规范。它告诉你存在一个 ID 为 789:012、名为 PrimaryButton 的组件。它不告诉你:
- 组件接受什么属性
- 它有什么状态
- 组件的内部结构(那在作为 INSTANCE 的 IR 节点中)
- 组件的源 Figma 文件是什么(如果来自链接库)
这些缺口在 v0.4 中是有意为之的。从 IR 结构推断完整的组件属性是可能的,但对于具有复杂变体逻辑的组件会产生不可靠的结果。清单提供稳定的标识,实现细节来自你的现有代码库,Agent 也可以访问这些代码库。
正确的工作流是:Agent 看到 componentId: "789:012",在清单中将其查找为 PrimaryButton,然后在你的 Kotlin 代码库中搜索 PrimaryButton 以了解实际的函数签名。清单是设计与代码之间的桥梁,不是代码的替代品。你可以在 figmascope.dev 上从任何 Figma 文件导出清单。
IR 中的组件标识是"从这个设计生成代码"与"生成适配现有代码库的代码"之间的分水岭。前者是玩具,后者才是真正的工作。
与纯截图交付方式的对比
从同一屏幕的 PNG 工作的 Agent 没有组件标识。它看到一个带有居中文字的蓝色圆角矩形,生成:
Box(
modifier = Modifier
.background(Color(0xFF7F5CFE), RoundedCornerShape(24.dp))
.padding(horizontal = 32.dp, vertical = 16.dp)
) {
Text("Start", color = Color.White, fontWeight = FontWeight.SemiBold)
}
从带有清单的 IR 工作的 Agent 看到 componentId: "789:012",查找 PrimaryButton,在代码库中找到现有的可组合函数,生成:
PrimaryButton(
label = stringResource(R.string.start),
onClick = { /* TODO */ }
)
第二个输出与你的设计系统集成。第一个制造了分歧。清单使第二个输出成为可能。关于截图为何不适合作为交付物,请参阅为什么截图会失败。
包含 componentId 引用的逐屏 IR 在逐屏 IR — Stack、Overlay、Absolute、Leaf 中有详细介绍。包含这两个产物的完整上下文包结构通过CONTEXT.md 解析介绍。要获取你自己的组件清单,请在 figmascope 上运行你的 Figma 文件。