Różnica między plikiem projektowym a biblioteką komponentów to tożsamość. Plik projektowy ma kształty. Biblioteka komponentów ma nazwane, wielokrotnego użytku części ze stabilnymi identyfikatorami. components/inventory.json to odpowiedź figmascope na pytanie: "które części w tym projekcie mają być komponentami i jak instancje łączą się z powrotem z nimi?"

Schemat

components/inventory.json to tablica obiektów:

[
  {
    "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"
  }
]

Każdy wpis ma trzy pola:

To pełny schemat. Jest celowo minimalny.

Jak instancje się łączą

Połączenie z instancji do inwentarza jest w IR per-ekran. Każdy węzeł będący INSTANCE komponentu nosi componentId i componentName:

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

componentId pasuje do id w inventory.json. componentName pasuje do name. Oba pola są obecne, aby agent nie musiał ładować inventory.json, by uzyskać nazwę — ale jeśli musi wiedzieć, czy ten komponent jest częścią COMPONENT_SET, odsyła do inwentarza.

W ten sposób agent kodujący wie, że węzeł przycisku na ekranie nie jest niestandardowym układem, który powinien szczegółowo reprodukować — to instancja PrimaryButton i powinien wywołać istniejący composable PrimaryButton() zamiast generować nowy ze strukturalnych szczegółów IR.

Bez tożsamości komponentów, agent generuje ten sam przycisk od zera na każdym ekranie. Z nią agent wywołuje istniejący composable i całkowicie pomija strukturalne generowanie kodu. Różnica polega na tym, czy dostaniesz 40 bloków Row { Text(...) Surface { ... } } czy 40 wywołań PrimaryButton(...).

Dlaczego ma to znaczenie dla bezpieczeństwa refaktoryzacji

Systemy projektowania są refaktoryzowane. Przycisk dostaje nowy kształt, nowy padding, inny kolor. Jeśli cały wygenerowany kod był strukturalnie dosłowny, refaktoryzacja oznacza dotknięcie każdego ekranu, który ma przycisk. Jeśli wygenerowany kod używał referencji do composable PrimaryButton, refaktoryzacja to jeden plik.

Inwentarz umożliwia to poprzez ustanowienie kontraktu w czasie generowania: "ten węzeł nie jest niestandardowym układem, to instancja znanego komponentu." Agent, który respektuje ten kontrakt, generuje kod, który jest już ustrukturyzowany dla refaktoryzacji na poziomie komponentów.

COMPONENT vs. COMPONENT_SET

System komponentów Figma ma dwa poziomy. COMPONENT to jedna definicja. COMPONENT_SET to kontener dla wariantów — to, co Figma nazywa "wariantami" (np. przycisk z Primary/Secondary/Destructive i Default/Hovered/Pressed stanami).

W praktyce instancja na ekranie zawsze będzie odwoływała się do COMPONENT (konkretnego wariantu), nie do COMPONENT_SET. COMPONENT_SET jest tam, aby agent znał pełną powierzchnię wariantów, gdy musi zaimplementować maszynę stanów komponentu.

// Wpisy inwentarza dla zestawu 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" }

// Instancja w IR ekranu odwołuje się do konkretnego wariantu
{ "componentId": "890:101", "componentName": "Button/Primary/Default" }

Limit 300 wpisów

figmascope ogranicza inventory.json do 300 wpisów. Pliki Figma na dużą skalę — zwłaszcza pliki systemów projektowania z wyczerpującymi bibliotekami komponentów — mogą mieć tysiące komponentów. Uwzględnienie wszystkich w pakiecie kontekstu przeznaczonym do wysłania do LLM wypełniłoby okno kontekstu definicjami, których agent nie użyje dla implementowanych ekranów.

Gdy limit zostanie osiągnięty, w inwentarzu pojawia się pole _truncated:

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

Czego inwentarz nie zawiera

Inwentarz to lista tożsamości, nie specyfikacja implementacji. Mówi Ci, że komponent o nazwie PrimaryButton z ID 789:012 istnieje. Nie mówi Ci:

Właściwy przepływ pracy: agent widzi componentId: "789:012", wyszukuje w inwentarzu jako PrimaryButton, następnie przeszukuje bazę kodu Kotlin w poszukiwaniu PrimaryButton, aby zrozumieć rzeczywistą sygnaturę funkcji. Inwentarz jest mostem między projektem a kodem, nie zastąpieniem kodu. Możesz wyeksportować inwentarz z dowolnego pliku Figma na figmascope.dev.

Tożsamość komponentów w IR to to, co oddziela "generuj kod z tego projektu" od "generuj kod, który pasuje do istniejącej bazy kodu." To pierwsze to zabawka. To drugie to praca.

IR per-ekran zawierający odwołania componentId jest szczegółowo omówiony w IR Per-Ekran — Stack, Overlay, Absolute, Leaf. Pełna struktura pakietu kontekstu zawierająca oba artefakty jest wprowadzona przez Anatomię CONTEXT.md. Aby uzyskać własny inwentarz komponentów, uruchom figmascope na swoim pliku Figma.