Skip to content

Lint: token-refs-resolve and cspec-shape reject tokens the compiler resolves — lint/compiler resolution mismatch ($color/bg/page, $text/Heading/2xl) #23

Open

Description

@deriazjulien

Summary

bridge-ds lint (7.3.1, bridge:recommended) and bridge-ds compile disagree on how a $token reference resolves against the KB. A CSpec whose scene graph compiles with exit 0 and executes correctly in Figma fails lint with token-refs-resolve errors on every semantic token and every text style. Two independent causes, plus a schema pattern that rejects real style names.

1. token-refs-resolve ignores the compiler's resolution rules

The compiler (lib/compiler/resolve.ts, resolveTokenRef) tries, in order: category/expandedName, expandedNameNoCat, stripped, and nameParts (name without the $category/ prefix), and routes $text/… to text-styles.json, $comp/… to components, etc.

The lint function token-exists-in-kb (functionOptions.registry: tokens) only looks up variables.json and only by the stripped name:

CSpec token Compiler Lint
$color/bg/page (variable named bg/page) resolves via nameParts Token "$color/bg/page" does not exist in the KB. Did you mean color/bleu-galaxie/500…
$color/text/heading (variable text/heading) resolves same error
$text/Heading/2xl (text style) resolves via textStyles index error — looked up in variables, suggests text/heading, text/body

Any DS whose semantic collection is not prefixed color/ (very common: bg/*, text/*, border/*), or that uses text styles at all, cannot pass token-refs-resolve.

2. cspec-shape token pattern is lowercase-only

cspec-shape.schema.json → tokens[].items.properties.name.pattern:

^\$[a-z][a-z0-9-]*(\/[a-z0-9-]+)+$

Figma text styles are commonly capitalised (Heading/2xl, Body/default, Label/button), and the compiler matches text styles by exact, case-sensitive name (textStyles.byName). So the correct reference $text/Heading/2xl is a schema error, and the "conforming" $text/heading/2xl does not compile (or worse, fuzzy-matches — see #20).

Reproduction

KB: 173 variables (semantic collection named bg/…, text/…, interactive/…, border/…, feedback/…), 23 text styles (Display/*, Heading/*, Body/*, Label/*).

name: login-screen
archetype: screen
component: LoginScreen
tokens:
  - { name: "$color/bg/page" }
  - { name: "$text/Heading/2xl" }

bridge-ds compile on the matching scene graph → exit 0, executes in Figma, both paints bound.
bridge-ds lint --config <bridge:recommended> → 2 × token-refs-resolve error + 1 × cspec-shape pattern error.

Proposal

  1. Make token-exists-in-kb reuse the compiler's resolver (resolveTokenRef against loadRegistry(kbPath)) instead of a separate lookup — one resolution semantics for compile-time and lint-time, including the $text/, $comp/, $icon/, $logo/ categories. Ideally in strict/exact mode (see Compiler: fuzzy token resolution silently binds non-existent $tokens to unrelated variables (e.g. $spacing/md → font/size/md) — request strict mode #20), so lint is the place that flags fuzzy-only matches.
  2. Relax the cspec-shape token pattern to allow the characters Figma allows in style/variable names (at least uppercase letters; ideally ^\$[a-z]+(\/[^\/\s]+)+$), or validate tokens[].name by resolution rather than by regex.

Until then we run with token-refs-resolve: off and list text styles under a custom text_styles key so the bundle passes cspec-shape. Happy to send a PR for (1) if you agree with reusing the compiler resolver.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions