Design System Extraction — turn a production codebase into a design system. Server-only: no plugin re-import needed (nothing in figma-desktop-bridge/ changed).
Seven new figma_ds_* tools plus a supporting extraction engine (src/core/extraction/). The workflow runs in order: analyze the app(s) → extract tokens → scaffold the package → wire Storybook → port components one at a time → verify with deterministic evals — and, for design-led orgs, import the extracted tokens into Figma variables with figma_import_tokens (top-level groups become collections), a full code → design system → Figma round-trip. Local Mode only: these tools read a production codebase and write a design-system package on the local filesystem, which Cloudflare Workers cannot do — so they are registered only in src/local.ts and never appear in Cloud Mode's tool list (the registerMultiFileTools precedent: no silent no-op is possible).
Added
figma_ds_analyze— scan one or more production app codebases. Detects framework (React/Next/Angular/Web Components), styling methods (Tailwind v3/v4, CSS Modules, SCSS, Emotion, styled-components), and vendor component layers (shadcn/ui, Radix, MUI, Chakra, etc.), then builds a component inventory with per-component classification (vendored / wrapped / pure-vendor / bespoke), prop contracts, real usage counts (porting rank), observed prop values from call sites (variant inference), and duplicate detection. Iconography and typography rules are captured for the scaffold's showcase pages. Multiple targets merge into one inventory with cross-app duplicates flagged — the shared design language of a product family.- Architecture classification — the "UI kit vs design system" analysis. An app ships
FollowButton,ModerationMenu,NodeCard— components named after usage. A design system shipsButton,Menu,Card, with usage expressed as variants and recipes. The analyzer assigns each component an atomic level, detects specializations (FollowButton→Button), and derivesmissingPrimitives: the canonical generic components the specializations imply but that don't exist in the codebase — which is the design-system build list, reviewed with the user rather than decided silently. - Writes the full manifest to
<outDir>/.extraction/analysis.jsonand returns a compressed summary, so a large inventory doesn't blow the context window.
- Architecture classification — the "UI kit vs design system" analysis. An app ships
figma_ds_extract_tokens— mine the app's de-facto styling into DTCG tokens. Two confidence tiers. Declared styling intent is mined first and always becomes tokens::root/@themecustom properties with multi-mode detection across theming conventions (.dark,[data-theme=…],[data-mode=…], theme classes,prefers-color-scheme— light + dark blocks become token modes), SCSS variables,tailwind.configtheme values, and shadcn HSL triples. Inferred values come second: recurring raw values (hex colors, spacing/radius/font sizes) are promoted only above a frequency threshold (minFrequency, default 4), and everything below the threshold is listed in the report for human review instead of silently dropped. Tailwind utility classes used in markup are frequency-mined and valued from the app's own installed theme (node_modules/tailwindcss/theme.css), so mined values are version-accurate rather than guessed from a hardcoded palette.- Every token carries provenance — source
file:line, confidence tier, frequency — in$extensions, so a reviewer can trace any token back to the code that justified it. - Output goes through the same formatter engine as
figma_export_tokens(canonical DTCG always; CSS vars / Tailwind v4 / Tailwind v3 / SCSS / TS / JSON / Style Dictionary / Tokens Studio on request; both DTCG dialects). The DTCG file is directly importable into Figma variables viafigma_import_tokens. - Names stay structural as mined (
--color-blue-500→color/blue/500). Semantic naming (color/primary) is deliberately a review pass with the user, layered on top as aliases — a judgment call, not something to guess.
- Every token carries provenance — source
figma_ds_scaffold— generate the design-system package.package.jsonwith the app framework as peer deps,src/componentslayout, token files via the shared formatter engine, framework-neutral token/typography/iconography showcase MDX docs pages, and a README documenting the workflow. Additive by default — existing files are skipped unlessforce(token files always refresh). Storybook itself is deliberately not baked in: runnpm create storybook@latestinside the package afterwards — the CLI detects the framework and installs the current version, so the scaffold never ships version-pinned Storybook templates that rot.figma_ds_setup_storybook— wire the fresh workshop to the extraction. A stocknpm create storybook@latestworkshop knows nothing about the source app, and every piece of glue this tool generates corresponds to a real render-fidelity failure hit during live extraction runs:.storybook/preview.css(Tailwind entry importing the extracted tokens plus the source app's@themeutility mapping, custom@utilitydefinitions,@layer base, and@font-facerules mined from its stylesheets, with a dark variant covering both.darkand[data-theme]conventions), self-hosted font files copied intostaticDirswith runtime-var fallbacks, amain.jspatch (Tailwind vite plugin + automatic JSX runtime — without it, stories die withReact is not defined), and apreview.jsxpatch (preview.css import + a theme toolbar/decorator that sets both mode conventions, using the extracted mode names). Idempotent; anything it can't patch safely is returned as a manual step.figma_ds_extract_component— per-component deep manifest for porting. Source (capped at 64KB), local import closure, prop contract, observed call-site variants, vendor classification, style touchpoints (classNames, CSS-module imports, custom properties consumed — check these againsttokens.json), and a ready-to-adapt CSF3 story scaffold with one story per real observed variant. Pure-vendor components return guidance instead of source: represent them via the token theme and document approved usage, or wrap them in the design system if the org needs a customized version.figma_ds_verify— deterministic fidelity evals. The governance gate before handing the package over or pushing tokens to Figma. Checks:tokens.jsonparses as DTCG and every alias resolves (import-ready); no quoted CSS functional expressions in generated token files (see Fixed — this class of bug shipped and was caught live); everyvar()consumed in component/preview CSS resolves somewhere in the workshop; every component directory carries a stories file and index barrel; every portable inventory component has a recorded porting status. Each check encodes a failure class found in real extraction runs. Also reports Figma round-trip readiness with the exactfigma_import_tokenscall for design-led orgs.figma_ds_status— porting progress across sessions. Read a progress summary, or record a component aspending/in-progress/ported/skippedwith notes and its story file. Persisted in<outDir>/.extraction/status.json, so an engagement spanning dozens of components and many sessions resumes where it left off instead of re-deriving what's done.
Fixed
- Token formatters quoted CSS functional expressions, silently killing transitions. The CSS-variables, SCSS, and Tailwind v4 formatters share a
needsQuoting()heuristic for string-typed token values, and it treated functional expressions as string literals — so an easing token rendered as--easing-standard: "cubic-bezier(0.4, 0, 0.2, 1)";. That is syntactically valid CSS, which is what makes it dangerous: nothing errors, the variable simply makes every declaration that consumes it invalid, and the effect is a transition that doesn't animate. Found live during extraction validation — a quotedcubic-beziereasing killed a button's hover transition with no diagnostic anywhere. Functional expressions (cubic-bezier(...),calc(...),clamp(...),var(...),color-mix(...), etc.) are now recognized as CSS values and emitted unquoted. This affectsfigma_export_tokensoutput too, not just the new extraction tools — if your exported tokens include easing, duration, or calc values, re-export to pick up the fix.figma_ds_verifyincludes a quoted-expression scan so a regression of this class fails an eval instead of shipping. figma_lint_design's AI-facing description undersold its design-system checks. The token-misuse rule — a semantic token bound to the wrong property, e.g. abg/*orsurface/*variable used as a text fill — was live in the audit, but the tool description still listed only four design-system rules. Clients that choose rules from the description had no way to know the check existed. The description now lists all five.
Internal
- New extraction engine under
src/core/extraction/(walker, detectors, component inventory, architecture classifier, token extractor, scaffolder, Storybook preset, verifier) — dependency-free scanning: package.json evidence plus file evidence, no AST, no execution of user code. New Jest suitetests/design-system-extraction.test.tsexercises it against fixture codebases intests/fixtures/.