हर figmascope export में tokens.json शामिल है। यह Figma की visual values और आपके code को चाहिए typed constants के बीच bridge है। यह post schema, keys कैसे named हैं, Figma file में Variables न होने पर क्या होता है, और token system honestly कहाँ कम पड़ती है — यह सब cover करता है।

Schema

Top-level structure में चार sections हैं:

{
  "spacing": {
    "spacing.4":  { "$value": 4,  "$type": "dimension" },
    "spacing.8":  { "$value": 8,  "$type": "dimension" },
    "spacing.12": { "$value": 12, "$type": "dimension" },
    "spacing.16": { "$value": 16, "$type": "dimension" },
    "spacing.24": { "$value": 24, "$type": "dimension" }
  },
  "radius": {
    "radius.4":  { "$value": 4,  "$type": "dimension" },
    "radius.8":  { "$value": 8,  "$type": "dimension" },
    "radius.12": { "$value": 12, "$type": "dimension" }
  },
  "color": {
    "color.7f5cfe": { "$value": "#7f5cfe", "$type": "color" },
    "color.ffffff": { "$value": "#ffffff", "$type": "color" },
    "color.1a1a2e": { "$value": "#1a1a2e", "$type": "color" }
  },
  "typography": {}
}

Format W3C Design Tokens Community Group-ish है: हर token $value और $type के साथ एक object है। यह strict W3C DTCG implementation नहीं है — figmascope final spec publication से पहले का है और fontFamily जैसे composite types implement नहीं करता — लेकिन DTCG-aware tooling minor adaptation के साथ इसे parse कर सकती है।

Empty typography object एक bug नहीं है। यह नीचे covered है।

Value-derived key naming

जब Figma file में Variables हों, token keys उन Variable names से आती हैं जो designer ने set किए। spacing.md, color.brand.primary, जो भी design system use करती है।

जब Figma file में Variables नहीं होतीं — जो real-world Figma files का majority है — figmascope value-derived naming पर fall back करता है। 16 का spacing value spacing.16 बन जाता है। #7f5cfe color color.7f5cfe बन जाता है। 4 का corner radius radius.4 बन जाता है।

यह एक deliberate tradeoff है। Value-derived names ugly हैं लेकिन stable हैं। वे actual value से derived हैं, इसलिए same Figma file के दो different runs same key produce करते हैं। spacing.16 हमेशा 16dp का मतलब है। Agent इस पर rely कर सकता है।

Alternative positional names जैसे spacing.1, spacing.2 आदि होंगे। वे brittle हैं — एक छोटा spacing value add करें और सब कुछ shift हो जाता है। Value-derived names shift नहीं होते।

Value-derived names उन files के लिए fallback हैं जिनमें Variables होनी चाहिए लेकिन नहीं हैं। अगर आपके design system में 40 spacing values हैं जिन्हें semantic names चाहिए, designer को Variables setup करने के लिए push करें। Inference fallback real-world files के लिए exist करता है, real token system के substitute के रूप में नहीं।

tokensSource field और इसका मतलब

_meta.json में एक tokensSource field है जो बताता है tokens कैसे derived हुए:

Valueमतलब
"figma-variables" Figma file में Variables हैं और directly use हुए। Token names designer-assigned हैं। Full coverage।
"inferred-from-frequency" कोई Variables नहीं। figmascope ने सभी nodes scan किए, frequently-recurring values find किए, उन्हें tokens पर promote किया। Coverage design की consistency पर depend करती है।
"none" कोई Variables नहीं और inference ने कुछ useful नहीं दिया। tokens.json में empty या near-empty sections होंगे।

_meta.json में "tokens-inferred-from-frequency" warning इसे mirror करती है। अगर आप इसे देखते हैं, token coverage best-effort है।

जब tokensSource "inferred-from-frequency" है, inference algorithm है: सभी dimension values find करें जो तीन या अधिक nodes के padding, gap, या cornerRadius fields में appear होते हैं। उन्हें क्रमशः spacing या radius tokens पर promote करें। Fill colors के लिए same करें। Values जो केवल एक या दो बार appear होती हैं उन्हें one-off treat करते हैं, promoted नहीं।

यह internally consistent designs के लिए well काम करता है। Exploratory designs के लिए poorly काम करता है जहां spacing freely vary करती है। _meta.json warnings exist करती हैं precisely ताकि agent जाने कि वह किस situation में है।

Typography अक्सर empty क्यों होती है

Typography tokens को reliably extract होने के लिए FLOAT या STRING type के Figma Variables चाहिए। Text styles Figma में shared styles के रूप में exist करती हैं, Variables के रूप में नहीं, और styles के लिए API surface Variables API से different है।

figmascope v0.4 typography extract करता है जब Variables इसे cover करती हैं। यह typography के लिए frequency-based inference attempt नहीं करता क्योंकि useful typography tokens — font family, line height, letter spacing, weight combos — के पास obvious value-derived names नहीं हैं जैसे spacing.16 के पास हैं। एक fontSize.14 key typography.body.small से बहुत कम useful है, और bad name generate करना कोई name न generate करने से worse है।

तो result honest है: अगर आपकी Figma file में typography Variables हैं, आपको typography tokens मिलते हैं। अगर नहीं, तो आपको empty object मिलता है और agent को CONTEXT.md के माध्यम से बताया जाता है कि typography coverage partial हो सकती है।

// _meta.json
{
  "tokensSource": "inferred-from-frequency",
  "warnings": [
    "tokens-inferred-from-frequency"
  ]
}

Agent यह देखता है और typography token references के बारे में conservative होना जानता है। यह explicit values और एक TODO comment के साथ fallback code generate करता है बजाय token name invent करने के।

Agent tokens.json कैसे use करता है

CONTEXT.md constraint है: "अगर ±2dp के भीतर token exist करता है तो dp values कभी hardcode मत करो।" ±2dp tolerance rounding handle करता है। अगर किसी node में paddingLeft: 15 है और spacing.16 exist करता है, agent spacing.16 use करता है। अगर closest token spacing.24 है, कोई match नहीं — agent literal value use करता है।

Colors के लिए, matching 6-digit lowercase पर normalization के बाद hex value पर exact है। #7F5CFE color.7f5cfe से match करता है।

Corner radius के लिए, spacing जैसा ±2dp rule।

Jetpack Compose target के लिए practical output इस तरह दिखता है:

// figma-variables tokensSource के साथ
Surface(
    shape = RoundedCornerShape(Radius.radius8),
    color = Color.Brand.Primary
) {
    Column(
        verticalArrangement = Arrangement.spacedBy(Spacing.spacing16),
        modifier = Modifier.padding(horizontal = Spacing.spacing24)
    ) { ... }
}

// inferred-from-frequency tokensSource के साथ (same visual output, same token refs)
Surface(
    shape = RoundedCornerShape(Radius.radius8),
    color = Color.color7f5cfe
) { ... }

Value-derived names कम readable हैं। फिर भी hardcoded values से बेहतर हैं।

अन्य token extraction approaches से comparison

Figma का native "Inspect" panel per-node values दिखाता है। कोई exported token file नहीं है। आपको manually एक create करना होगा या Tokens Studio जैसे plugin use करना होगा। दोनों के लिए designer effort और ongoing maintenance चाहिए।

figmascope हर export पर automatically tokens extract करता है। अगर file बदलती है, re-export करें और tokens current state reflect करते हैं। Tradeoff यह है कि Variables के बिना, names semantic की बजाय value-derived हैं — लेकिन आपको हर बार token file मिलती है, बिना plugin या extra workflow step के।

Tokens Studio (formerly Style Dictionary integration) designer को plugin setup करने, Figma file में JSON file maintain करने, और sync करने की जरूरत होती है। यह mature design system के लिए सही solution है। figmascope का approach उन files के लिए सही solution है जो अभी वहाँ नहीं हैं, जो कि अधिकांश files हैं।

Token extraction file में जो exist करता है उसका best-effort snapshot है। यह token-first design system का substitute नहीं है। यह वह चीज़ है जो आप उसकी ओर build करते हुए use करते हैं।

tokens.json को अपने codebase से wire करना

JSON structure इतना flat है कि इससे Kotlin object या TypeScript module generate करना straightforward है। एक simple script:

// tokens.json → Kotlin object (simplified)
const tokens = JSON.parse(fs.readFileSync('tokens.json', 'utf-8'));

let output = 'object Spacing {\n';
for (const [key, token] of Object.entries(tokens.spacing)) {
    const name = key.replace('spacing.', 'spacing').replace('.', '_');
    output += `    val ${name} = ${token.$value}.dp\n`;
}
output += '}';
// → val spacing16 = 16.dp

अगर आप already design token pipeline use कर रहे हैं, W3C-ish format $value/$type keys के लिए custom transformer के साथ Style Dictionary में drop करने के लिए काफी close है।

IR के साथ tokens कैसे interact करते हैं इसका बाकी Per-Screen IR में covered है। Tokens broader agent context के साथ कैसे interact करते हैं इसके लिए, CONTEXT.md की संरचना देखें।