La diferencia entre un archivo de diseño y una biblioteca de componentes es la identidad. Un archivo de diseño tiene formas. Una biblioteca de componentes tiene partes nombradas y reutilizables con identificadores estables. components/inventory.json es la respuesta de figmascope a: "¿qué partes de este diseño están pensadas para ser componentes y cómo se conectan las instancias de vuelta a ellas?"

El esquema

components/inventory.json es un 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 tiene tres campos:

Ese es el esquema completo. Es intencionalmente mínimo.

Cómo las instancias se vinculan de vuelta

El vínculo de las instancias al inventario está en el IR por pantalla. Cualquier nodo que sea una INSTANCE de un componente lleva componentId y componentName:

// screens/home.json
{
  "kind": "stack",
  "id": "555:201",
  "componentId": "789:012",
  "componentName": "PrimaryButton",
  "axis": "horizontal",
  ...
}

El componentId coincide con un id en inventory.json. El componentName coincide con el name. Ambos campos están presentes para que el agente no tenga que cargar inventory.json para obtener el nombre — pero si necesita saber que este componente es parte de un COMPONENT_SET, hace una referencia cruzada con el inventario.

Así es como un agente de codificación sabe que el nodo de botón en pantalla no es un layout a medida que debería reproducir en detalle — es una instancia de PrimaryButton, y debería llamar al composable PrimaryButton() existente en lugar de generar uno nuevo a partir de los detalles estructurales del IR.

Sin identidad de componentes, un agente genera el mismo botón desde cero en cada pantalla. Con ella, el agente llama al composable existente y omite completamente el codegen estructural. La diferencia es si obtienes 40 bloques Row { Text(...) Surface { ... } } o 40 llamadas a PrimaryButton(...).

Por qué esto importa para la seguridad en refactorización

Los sistemas de diseño se refactorizan. Un botón obtiene una nueva forma, nuevo relleno, un color diferente. Si todo tu código generado era estructuralmente literal, la refactorización significa tocar cada pantalla que tiene un botón. Si el código generado usó la referencia al composable PrimaryButton, la refactorización es un solo archivo.

El inventario lo hace posible al establecer el contrato en tiempo de generación: "este nodo no es un layout personalizado, es una instancia de un componente conocido." El agente que respeta este contrato genera código que ya está estructurado para la refactorización a nivel de componente.

Esta es la ventaja estructural principal sobre los handoffs basados en capturas de pantalla. Una captura de pantalla de un botón son píxeles. No tiene identidad. Un agente trabajando desde una captura de pantalla generará código estructural para el botón en cada pantalla, siempre. Un agente trabajando desde el IR con vinculación de inventario puede reconocer la instancia y usar la referencia al componente en su lugar.

COMPONENT vs. COMPONENT_SET

El sistema de componentes de Figma tiene dos niveles. Un COMPONENT es una única definición. Un COMPONENT_SET es un contenedor para variantes — lo que Figma llama "variants" (por ejemplo, un botón con estados Primary/Secondary/Destructive y Default/Hovered/Pressed).

En la práctica, una instancia en una pantalla siempre referenciará un COMPONENT (una variante específica), no el COMPONENT_SET. El COMPONENT_SET está ahí para que el agente conozca la superficie completa de variantes cuando necesite implementar la máquina de estados del componente.

// Inventory entries for a Button set
{ "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" }

// Instance in screen IR references a specific variant
{ "componentId": "890:101", "componentName": "Button/Primary/Default" }

Un agente generando código Compose para esto sabe: el componente es un Button con estilo Primary y estado Default. Puede inferir que la firma de la función probablemente implica parámetros style: ButtonStyle y state: ButtonState, o como mínimo usar Button/Primary/Default como referencia semántica para un botón primario en su estado por defecto.

El límite de 300 entradas

figmascope limita inventory.json a 300 entradas. Los archivos Figma a escala — especialmente los sistemas de diseño con bibliotecas de componentes exhaustivas — pueden tener miles de componentes. Incluirlos todos en un bundle de contexto destinado a enviarse a un LLM rellenaría la ventana de contexto con definiciones que el agente no usará para las pantallas que se están implementando.

Cuando se alcanza el límite, un campo _truncated aparece en el inventario:

[
  { "id": "...", "name": "...", "type": "COMPONENT" },
  ...
  { "_truncated": true, "totalCount": 847, "included": 300 }
]

El totalCount te dice cuántos componentes existen en el archivo. El included te dice cuántos llegaron al inventario. El orden es por primer encuentro en el árbol de nodos de Figma, por lo que los componentes referenciados temprano en el documento (típicamente las pantallas principales) tienen más probabilidades de incluirse.

Si estás trabajando en pantallas que usan componentes definidos tarde en el documento y no están en el inventario, los nodos del IR para esas instancias aún tienen componentId y componentName — la información de identidad se preserva incluso cuando el componente no aparece en el inventario. El agente conoce el nombre del componente por el IR, incluso sin la entrada en el inventario.

Qué no incluye el inventario

El inventario es una lista de identidades, no una especificación de implementación. Te dice que existe un componente llamado PrimaryButton con ID 789:012. No te dice:

Estas brechas son intencionales en v0.4. La inferencia completa de props de componentes desde la estructura del IR es posible pero produciría resultados poco fiables para componentes con lógica de variantes compleja. El inventario proporciona identidad estable. Los detalles de implementación provienen de tu base de código existente, a la que el agente también tiene acceso.

El flujo de trabajo correcto: el agente ve un componentId: "789:012", lo busca en el inventario como PrimaryButton, luego busca en tu base de código Kotlin PrimaryButton para entender la firma real de la función. El inventario es el puente entre el diseño y el código, no un reemplazo del código. Puedes exportar un inventario desde cualquier archivo Figma en figmascope.dev.

La identidad de componentes en el IR es lo que separa "generar código desde este diseño" de "generar código que encaja en una base de código existente." Lo primero es un juguete. Lo segundo es el trabajo.

Comparación con el handoff solo con capturas de pantalla

Un agente trabajando desde un PNG de la misma pantalla no tiene identidad de componentes. Ve un rectángulo azul redondeado con texto centrado y genera:

Box(
    modifier = Modifier
        .background(Color(0xFF7F5CFE), RoundedCornerShape(24.dp))
        .padding(horizontal = 32.dp, vertical = 16.dp)
) {
    Text("Start", color = Color.White, fontWeight = FontWeight.SemiBold)
}

Un agente trabajando desde el IR con inventario ve componentId: "789:012", busca PrimaryButton, encuentra el composable existente en la base de código y genera:

PrimaryButton(
    label = stringResource(R.string.start),
    onClick = { /* TODO */ }
)

La segunda salida se integra con tu sistema de diseño. La primera crea divergencia. El inventario es lo que hace posible la segunda salida. Para más información sobre por qué las capturas de pantalla fallan como artefactos de handoff, ver Por Qué las Capturas de Pantalla Fallan.

El IR por pantalla que contiene referencias componentId se cubre en detalle en IR por Pantalla — Stack, Overlay, Absolute, Leaf. La estructura completa del bundle de contexto que contiene ambos artefactos se introduce en Anatomía de CONTEXT.md. Para obtener tu propio inventario de componentes, ejecuta figmascope en tu archivo Figma.