A diferença entre um arquivo de design e uma biblioteca de componentes é identidade. Um arquivo de design tem formas. Uma biblioteca de componentes tem partes nomeadas e reutilizáveis com identificadores estáveis. O components/inventory.json é a resposta do figmascope para a pergunta: "quais partes neste design são componentes, e como as instâncias se conectam de volta a eles?"
O schema
O components/inventory.json é um array de objetos:
[
{
"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"
}
]
Cada entrada tem três campos:
id: O ID do nó no Figma, estável entre sessões para o mesmo arquivo.name: O nome do componente no Figma. Para variantes dentro de um COMPONENT_SET, o Figma usa notação de barra:Button/Primary/Default.type: Ou"COMPONENT"(uma única definição de componente) ou"COMPONENT_SET"(um grupo de variantes).
Esse é o schema completo. É intencionalmente mínimo.
Como as instâncias se vinculam de volta
O vínculo de instâncias ao inventário está na IR por tela. Qualquer nó que seja uma INSTANCE de um componente carrega componentId e componentName:
// screens/home.json
{
"kind": "stack",
"id": "555:201",
"componentId": "789:012",
"componentName": "PrimaryButton",
"axis": "horizontal",
...
}
O componentId corresponde a um id em inventory.json. O componentName corresponde ao name. Ambos os campos estão presentes para que o agente não precise carregar o inventory.json para obter o nome — mas se precisar saber que este componente faz parte de um COMPONENT_SET, ele cruza a referência com o inventário.
É assim que um agente de código sabe que o nó de botão na tela não é um layout personalizado que deve reproduzir em detalhes — é uma instância de PrimaryButton, e ele deve chamar o composable PrimaryButton() existente em vez de gerar um novo a partir dos detalhes estruturais da IR.
Sem identidade de componente, um agente gera o mesmo botão do zero em cada tela. Com ela, o agente chama o composable existente e pula completamente a geração de código estrutural. A diferença é se você obtém 40 blocos
Row { Text(...) Surface { ... } }ou 40 chamadasPrimaryButton(...).
Por que isso importa para a segurança de refatoração
Design systems são refatorados. Um botão recebe uma nova forma, novo padding, uma cor diferente. Se todo o código gerado fosse literalmente estrutural, a refatoração significaria tocar em cada tela que tem um botão. Se o código gerado usasse a referência ao composable PrimaryButton, a refatoração é um único arquivo.
O inventário torna isso possível ao estabelecer o contrato no momento da geração: "este nó não é um layout personalizado, é uma instância de um componente conhecido." O agente que respeita esse contrato gera código que já está estruturado para refatoração em nível de componente.
Esta é a vantagem estrutural primária em relação a handoffs baseados em screenshots. Um screenshot de um botão são pixels. Ele não tem identidade. Um agente trabalhando a partir de um screenshot sempre gerará código estrutural para o botão em cada tela. Um agente trabalhando a partir da IR com vinculação de inventário pode reconhecer a instância e usar a referência ao componente.
COMPONENT vs. COMPONENT_SET
O sistema de componentes do Figma tem dois níveis. Um COMPONENT é uma definição única. Um COMPONENT_SET é um contêiner para variantes — o que o Figma chama de "variants" (por exemplo, um botão com estados Primary/Secondary/Destructive e Default/Hovered/Pressed).
Na prática, uma instância em uma tela sempre referenciará um COMPONENT (uma variante específica), não o COMPONENT_SET. O COMPONENT_SET está lá para que o agente conheça a superfície completa de variantes ao precisar implementar a máquina de estados do componente.
// Entradas do inventário para um conjunto de Button
{ "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" }
// Instância na IR da tela referencia uma variante específica
{ "componentId": "890:101", "componentName": "Button/Primary/Default" }
Um agente gerando código Compose para isso sabe: o componente é um Button com estilo Primary e estado Default. Ele pode inferir que a assinatura da função provavelmente envolve parâmetros style: ButtonStyle e state: ButtonState, ou no mínimo usar Button/Primary/Default como referência semântica para um botão primário em seu estado padrão.
O limite de 300 entradas
O figmascope limita o inventory.json a 300 entradas. Arquivos do Figma em escala — especialmente design systems com bibliotecas de componentes exaustivas — podem ter milhares de componentes. Incluir todos eles em um bundle de contexto destinado a ser enviado a um LLM encheria a janela de contexto com definições que o agente não usará para as telas sendo implementadas.
Quando o limite é atingido, um campo _truncated aparece no inventário:
[
{ "id": "...", "name": "...", "type": "COMPONENT" },
...
{ "_truncated": true, "totalCount": 847, "included": 300 }
]
O totalCount informa quantos componentes existem no arquivo. O included informa quantos entraram no inventário. A ordenação é por primeira ocorrência na árvore de nós do Figma, então os componentes referenciados no início do documento (tipicamente as telas primárias) têm maior probabilidade de serem incluídos.
Se você estiver trabalhando em telas que usam componentes definidos no final do documento e eles não estão no inventário, os nós da IR para essas instâncias ainda têm componentId e componentName — as informações de identidade são preservadas mesmo quando o componente não está listado no inventário. O agente conhece o nome do componente pela IR, mesmo sem a entrada do inventário.
O que o inventário não inclui
O inventário é uma lista de identidade, não uma spec de implementação. Ele informa que existe um componente chamado PrimaryButton com ID 789:012. Ele não informa:
- Quais props o componente aceita
- Quais estados ele tem
- Como o componente é estruturado internamente (isso está nos nós da IR que são INSTANCEs)
- Qual é o arquivo fonte do Figma do componente (se for de uma biblioteca vinculada)
Essas lacunas são intencionais na v0.4. A inferência completa de props de componentes a partir da estrutura da IR é possível, mas produziria resultados não confiáveis para componentes com lógica de variantes complexa. O inventário fornece identidade estável. Os detalhes de implementação vêm da sua base de código existente, à qual o agente também tem acesso.
O fluxo de trabalho correto: o agente vê um componentId: "789:012", consulta o inventário como PrimaryButton, então pesquisa na sua base de código Kotlin por PrimaryButton para entender a assinatura real da função. O inventário é a ponte entre o design e o código, não uma substituição do código. Você pode exportar um inventário de qualquer arquivo do Figma no figmascope.dev.
A identidade de componentes na IR é o que separa "gerar código a partir deste design" de "gerar código que se encaixa em uma base de código existente." O primeiro é um brinquedo. O segundo é o trabalho.
Comparação com handoff somente por screenshot
Um agente trabalhando a partir de um PNG da mesma tela não tem identidade de componente. Ele vê um retângulo azul arredondado com texto centralizado e gera:
Box(
modifier = Modifier
.background(Color(0xFF7F5CFE), RoundedCornerShape(24.dp))
.padding(horizontal = 32.dp, vertical = 16.dp)
) {
Text("Start", color = Color.White, fontWeight = FontWeight.SemiBold)
}
Um agente trabalhando a partir da IR com inventário vê componentId: "789:012", consulta PrimaryButton, encontra o composable existente na base de código e gera:
PrimaryButton(
label = stringResource(R.string.start),
onClick = { /* TODO */ }
)
O segundo output se integra ao seu design system. O primeiro cria divergência. O inventário é o que torna o segundo output possível. Para mais informações sobre por que screenshots falham como artefatos de handoff, veja Por que Screenshots Falham.
A IR por tela que contém referências de componentId é coberta em detalhes em IR por Tela — Stack, Overlay, Absolute, Leaf. A estrutura completa do bundle de contexto que contém ambos os artefatos é introduzida via Anatomia do CONTEXT.md. Para obter seu próprio inventário de componentes, rode o figmascope no seu arquivo do Figma.