@radicool/throughline 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/adapters/codex/AGENTS.md +29 -0
  4. package/adapters/codex/codex-mcp.toml +4 -0
  5. package/adapters/codex/prompts/component-builder.md +272 -0
  6. package/adapters/codex/prompts/component-pipeline.md +81 -0
  7. package/adapters/codex/prompts/design-system-audit.md +122 -0
  8. package/adapters/codex/prompts/design-system-status.md +41 -0
  9. package/adapters/codex/prompts/figma-environment-setup.md +456 -0
  10. package/adapters/codex/prompts/icon-system-builder.md +268 -0
  11. package/adapters/codex/prompts/new-component.md +13 -0
  12. package/adapters/codex/prompts/repository-builder.md +163 -0
  13. package/adapters/codex/prompts/retrofit-planner.md +136 -0
  14. package/adapters/codex/prompts/start.md +22 -0
  15. package/adapters/codex/prompts/storybook-chromatic-builder.md +261 -0
  16. package/adapters/codex/prompts/sync-figma-tokens.md +22 -0
  17. package/adapters/codex/prompts/token-builder.md +361 -0
  18. package/adapters/codex/prompts/token-crosswalk-builder.md +120 -0
  19. package/adapters/codex/prompts/token-sheet-builder.md +162 -0
  20. package/adapters/codex/prompts/token-sync-layer.md +232 -0
  21. package/adapters/cursor/.cursor/commands/design-system-status.md +41 -0
  22. package/adapters/cursor/.cursor/commands/new-component.md +13 -0
  23. package/adapters/cursor/.cursor/commands/start.md +22 -0
  24. package/adapters/cursor/.cursor/commands/sync-figma-tokens.md +22 -0
  25. package/adapters/cursor/.cursor/mcp.json +14 -0
  26. package/adapters/cursor/.cursor/rules/component-builder.mdc +276 -0
  27. package/adapters/cursor/.cursor/rules/component-pipeline.mdc +85 -0
  28. package/adapters/cursor/.cursor/rules/design-system-audit.mdc +126 -0
  29. package/adapters/cursor/.cursor/rules/figma-environment-setup.mdc +460 -0
  30. package/adapters/cursor/.cursor/rules/icon-system-builder.mdc +272 -0
  31. package/adapters/cursor/.cursor/rules/repository-builder.mdc +167 -0
  32. package/adapters/cursor/.cursor/rules/retrofit-planner.mdc +140 -0
  33. package/adapters/cursor/.cursor/rules/storybook-chromatic-builder.mdc +265 -0
  34. package/adapters/cursor/.cursor/rules/token-builder.mdc +365 -0
  35. package/adapters/cursor/.cursor/rules/token-crosswalk-builder.mdc +124 -0
  36. package/adapters/cursor/.cursor/rules/token-sheet-builder.mdc +166 -0
  37. package/adapters/cursor/.cursor/rules/token-sync-layer.mdc +236 -0
  38. package/adapters/generic/AGENTS.md +46 -0
  39. package/adapters/generic/commands/design-system-status.md +41 -0
  40. package/adapters/generic/commands/new-component.md +13 -0
  41. package/adapters/generic/commands/start.md +22 -0
  42. package/adapters/generic/commands/sync-figma-tokens.md +22 -0
  43. package/adapters/generic/skills/component-builder/SKILL.md +272 -0
  44. package/adapters/generic/skills/component-pipeline/SKILL.md +81 -0
  45. package/adapters/generic/skills/design-system-audit/SKILL.md +122 -0
  46. package/adapters/generic/skills/figma-environment-setup/SKILL.md +456 -0
  47. package/adapters/generic/skills/icon-system-builder/SKILL.md +268 -0
  48. package/adapters/generic/skills/repository-builder/SKILL.md +163 -0
  49. package/adapters/generic/skills/retrofit-planner/SKILL.md +136 -0
  50. package/adapters/generic/skills/storybook-chromatic-builder/SKILL.md +261 -0
  51. package/adapters/generic/skills/token-builder/SKILL.md +361 -0
  52. package/adapters/generic/skills/token-crosswalk-builder/SKILL.md +120 -0
  53. package/adapters/generic/skills/token-sheet-builder/SKILL.md +162 -0
  54. package/adapters/generic/skills/token-sync-layer/SKILL.md +232 -0
  55. package/package.json +29 -0
  56. package/references/brainstorm-before-build.md +139 -0
  57. package/references/brownfield-retrofit.md +93 -0
  58. package/references/coding-level.md +70 -0
  59. package/references/crosswalk-schema.md +113 -0
  60. package/references/figma-component-standards.md +532 -0
  61. package/references/figma-publishing.md +125 -0
  62. package/references/figma-scripting.md +278 -0
  63. package/references/manifest-schema.md +341 -0
  64. package/references/scaling-up-handoff.md +61 -0
  65. package/references/sync-adapters.md +141 -0
  66. package/scripts/README.md +78 -0
  67. package/scripts/adapters/emit-codex.mjs +58 -0
  68. package/scripts/adapters/emit-cursor.mjs +26 -0
  69. package/scripts/adapters/emit-generic.mjs +41 -0
  70. package/scripts/adapters/generate.mjs +73 -0
  71. package/scripts/adapters/read-sources.mjs +54 -0
  72. package/scripts/adapters/translate.mjs +51 -0
  73. package/scripts/build-reverse-index.mjs +56 -0
  74. package/scripts/crosswalk.schema.json +33 -0
  75. package/scripts/grep-color-usage.mjs +143 -0
  76. package/scripts/guard-token-removal.mjs +95 -0
  77. package/scripts/install.mjs +143 -0
  78. package/scripts/lib/crosswalk.mjs +91 -0
  79. package/scripts/validate-crosswalk.mjs +96 -0
@@ -0,0 +1,124 @@
1
+ ---
2
+ description: "Build the brownfield token crosswalk — a persistent three-way map between each new token, the old Figma variable, and the old code identifier(s) — as crosswalk.json, then install the vetted validator/reverse-index scripts into the monorepo and wire the tokens:validate CI gate. Use this when retrofitting a design system onto a mature codebase, when the user wants to map old tokens to new ones, build a crosswalk, set up tokens:validate, or generate a reverse index for SCSS/Tailwind swaps. Also trigger when retrofit-planner reaches the crosswalk stage, or after design-system-audit has sized the retrofit. Make sure to use this whenever someone needs the machine-readable backbone that drives a brownfield code retrofit and its validation gate."
3
+ alwaysApply: false
4
+ ---
5
+ # Token crosswalk builder
6
+
7
+ Builds the **backbone artifact** of a brownfield retrofit: `crosswalk.json`, a
8
+ persistent three-way map of **new token ↔ old Figma variable ↔ old code identifier**.
9
+ It drives the code retrofit and the `tokens:validate` CI gate. This skill also
10
+ installs the canonical scripts into the user's repo and wires the gate.
11
+
12
+ This is a brownfield skill. **Before doing anything, read**
13
+ `.throughline/references/brownfield-retrofit.md` (read discipline, the 7
14
+ guardrails, the safe sequence) and
15
+ `.throughline/references/crosswalk-schema.md` (the exact contract). Greenfield
16
+ builds don't need this skill.
17
+
18
+ ## Calibrate
19
+
20
+ Read `user.codingLevel` (`.throughline/references/coding-level.md`) and scale
21
+ explanation accordingly. The crosswalk involves JSON, npm scripts, and a CI gate — for
22
+ `new` users explain each plainly the first time; for `comfortable` users be terse.
23
+ Actions are identical across levels.
24
+
25
+ ## Prerequisites (offer to run them, don't bail)
26
+
27
+ Read the manifest. This skill needs:
28
+
29
+ 1. **A DTCG token source** at `packages/tokens/dtcg/tokens.json` — the validator
30
+ resolves against it. If it doesn't exist, offer to run `token-sync-layer` first
31
+ (it emits this file). Apply the read discipline: confirm the file exists by
32
+ reading it, never assume it's absent without looking.
33
+ 2. **The audit inputs** — ideally the `audit` manifest section (code surface,
34
+ Figma inventory, `percentSemantic`) populated by `design-system-audit`. If
35
+ `audit` is present, use it to seed the rows. If it is `null` (audit hasn't run —
36
+ it lands in Plan 3), don't block: ask the user for the old→new mapping inputs
37
+ directly (which old Figma variables and code symbols map to which new tokens),
38
+ and proceed. Note plainly that running `design-system-audit` first would
39
+ pre-fill this.
40
+ 3. **A repo at `local-git` or `github`** (`workspace.stage`) so the installed
41
+ scripts and `package.json` changes land as a reviewable diff/PR. If still
42
+ `folder`, offer `repository-builder`.
43
+
44
+ ## Step 1 — Build `crosswalk.json`
45
+
46
+ Write `packages/tokens/crosswalk.json` per the contract in
47
+ `.throughline/references/crosswalk-schema.md`. One row per new token:
48
+
49
+ - `newToken` — the DTCG dot-path exactly as it appears in
50
+ `packages/tokens/dtcg/tokens.json` (e.g. `color.text.primary`).
51
+ - `newValue` — the **resolved** leaf value (follow `{…}` aliases to the literal).
52
+ - `tier` — `primitive` or `semantic`.
53
+ - `figmaOld` — the old Figma variable name/path, or `null` if newly added.
54
+ - `codeTokens[]` — the old code identifiers this token replaces (`$primary-red`,
55
+ `bg-primary-red`, `Colors.primaryRed`, `--primary-red`). May be `[]`.
56
+ - `status` — `aligned | renamed | drift-fix | added | mapped-nearest`. Assign by:
57
+ same name & value → `aligned`; same value, new name → `renamed`; value
58
+ intentionally changed → `drift-fix`; brand-new token → `added`; no exact old
59
+ equivalent, mapped to nearest → `mapped-nearest`.
60
+ - `recommendedSemantic` — optional semantic target for a raw/primitive usage, else
61
+ `null`.
62
+
63
+ Do not guess values. Every `newValue` comes from a read of the DTCG source, not an
64
+ assumption (read discipline).
65
+
66
+ ## Step 2 — Install the vetted scripts + wire `tokens:validate`
67
+
68
+ Copy these from `.throughline/scripts/` into the user's repo **verbatim**
69
+ (they are zero-dependency and version with the user's repo so their CI can run them):
70
+
71
+ - `lib/crosswalk.mjs` → `packages/tokens/scripts/lib/crosswalk.mjs`
72
+ - `validate-crosswalk.mjs` → `packages/tokens/scripts/validate-crosswalk.mjs`
73
+ - `build-reverse-index.mjs` → `packages/tokens/scripts/build-reverse-index.mjs`
74
+ - `guard-token-removal.mjs` → `packages/tokens/scripts/guard-token-removal.mjs`
75
+ - `crosswalk.schema.json` → `packages/tokens/crosswalk.schema.json` (beside
76
+ `crosswalk.json`, so the `$schema` pointer resolves)
77
+
78
+ Then add to `packages/tokens/package.json` `scripts` (don't clobber existing keys):
79
+
80
+ ```jsonc
81
+ "tokens:validate": "node scripts/validate-crosswalk.mjs --crosswalk crosswalk.json --tokens dtcg/tokens.json",
82
+ "tokens:reverse-index": "node scripts/build-reverse-index.mjs --crosswalk crosswalk.json --out crosswalk.reverse.json"
83
+ ```
84
+
85
+ See `.throughline/scripts/README.md` for the full install contract.
86
+
87
+ ## Step 3 — Run the gate (must pass N/N)
88
+
89
+ Run `npm run tokens:validate` (from `packages/tokens/`). It must report **N/N** —
90
+ every row's resolved value matches its `newValue`. If it reports mismatches or
91
+ missing tokens, fix the crosswalk (or the token source) and re-run. **Never proceed
92
+ on a red validator and never edit a generated token file to make it pass** — change
93
+ the source in Figma and re-sync (guardrail 7). The validator is the source of truth
94
+ that the crosswalk and the real tokens agree.
95
+
96
+ ## Step 4 — Generate the reverse index
97
+
98
+ Run `npm run tokens:reverse-index`. This writes `crosswalk.reverse.json`
99
+ (`codeToken → newToken`), which the code-retrofit phase uses to semi-automate the
100
+ SCSS/Tailwind swaps. If it reports conflicts (one old symbol mapping to two new
101
+ tokens), resolve them in the crosswalk before relying on the index.
102
+
103
+ ## Step 5 — Update the manifest
104
+
105
+ Write the `tokenCrosswalk` section **only** (this skill owns it; never write another
106
+ skill's fields):
107
+
108
+ - `path` — the actual path written (`"packages/tokens/crosswalk.json"`).
109
+ - `statusCounts` — copy the camelCase object the validator printed
110
+ (`{ aligned, renamed, driftFix, added, mappedNearest }`).
111
+ - `validatorPassing` — `true` once `tokens:validate` passes N/N.
112
+
113
+ Append `token-crosswalk-builder` to `completedSkills`.
114
+
115
+ ## What this skill must NOT do
116
+
117
+ - Never delete old tokens or outputs here — that's the cleanup phase, gated by the
118
+ token-removal guard returning zero references (safe sequence, guardrail 4).
119
+ - Never edit generated token files to make the validator pass — fix the source.
120
+ - Never write another skill's manifest fields (e.g. `tokens.intakeMode` is owned by
121
+ `design-system-audit`).
122
+ - Never proceed past a red `tokens:validate`.
123
+ - Never assert a prerequisite is absent without a verified read (read discipline).
124
+
@@ -0,0 +1,166 @@
1
+ ---
2
+ description: "Build a beautiful, on-brand \"Foundations\" page in Figma that visually documents every variable collection and style — color ramps with swatches, the type scale, spacing, radius, shadows/elevations — with swatches live-bound to the actual variables where Figma allows. Use this when the user wants a visual stylesheet, a token reference page, a Foundations page, to document or showcase their design system, or to \"see all my tokens\" laid out. Also trigger after token-builder completes, when the user wants a visual artifact of their tokens. Make sure to use this when someone wants their tokens presented visually rather than just existing as variables."
3
+ alwaysApply: false
4
+ ---
5
+ # Token sheet builder
6
+
7
+ Creates a polished visual reference of the design system's tokens and styles on
8
+ a dedicated Figma page called **Foundations**. This is the artifact designers
9
+ and stakeholders actually look at — so it must be beautiful and on-brand, not a
10
+ utilitarian dump of swatches.
11
+
12
+ ## Live vs regenerated — set expectations clearly
13
+
14
+ Bind to variables wherever Figma allows so the sheet **live-updates** for those
15
+ properties: a color swatch bound to `gray/50` (in `_Color/Primitive`) re-colors
16
+ automatically when that primitive changes; spacing/radius examples bound to the variables resize
17
+ automatically. But labels, hex/value text, token names, descriptions, and the
18
+ set of tokens shown (adding/removing tokens) are **snapshots** — they don't
19
+ auto-update. So tell the user plainly: "The swatches update live when you change
20
+ a value, but if you rename tokens, change descriptions, or add/remove tokens,
21
+ re-run this skill to refresh the page." The sheet is regenerable; re-running
22
+ refreshes the snapshot parts.
23
+
24
+ (Tie-in: when the sync skill runs after token changes, refreshing Foundations is
25
+ a sensible companion step — the sheet and the synced code both reflect Figma.)
26
+
27
+ ## Prerequisites
28
+
29
+ Needs tokens in Figma (`tokens.semanticBuilt` true) and a live Figma connection.
30
+ If tokens don't exist, offer to run `token-builder`. If Figma isn't connected,
31
+ offer `figma-environment-setup`. Use the mechanism in `figma.mechanism`.
32
+
33
+ **Before scripting any `figma_execute`, read
34
+ `.throughline/references/figma-scripting.md`.** This sheet builds large
35
+ swatch/type grids — exactly the layouts that hit the two worst traps: the
36
+ `resize()` axis-lock (collapses a color grid or type-meta column to ~10px) and the
37
+ single-call `layoutWrap = "WRAP"` timeout on big grids (build manual rows or split
38
+ across calls instead). Also run the single-bridge-instance preflight before writing.
39
+
40
+ ## Step 1 — Brainstorm the layout (lightly)
41
+
42
+ Run `.throughline/references/brainstorm-before-build.md`, but keep it light — this is a
43
+ lower-stakes, easily-regenerated artifact. Settle: which collections get their
44
+ own section, how much per-token detail to show (just swatches, or swatches +
45
+ names + values + descriptions), and any brand styling direction for the page
46
+ itself (the page should feel like the brand it documents). Default to a clean,
47
+ sectioned layout, one section per collection/style group: Color (ramps as rows
48
+ of swatches), Typography (the type scale rendered in the actual text styles),
49
+ Spacing (visual bars), Radius (sample shapes), Border width (sample rules at
50
+ each width), Elevation (sample cards with the effect styles).
51
+
52
+ **Group semantic colors by category — never one flat list.** Primitive colors are
53
+ shown organized into ramps (gray, blue, red…); semantic colors get the **same
54
+ categorical organization**, grouped by their role family — **surface/background,
55
+ text, border, alert/feedback (success/warning/error/info), action/interactive**,
56
+ etc. — each family its own labeled sub-group of swatches. Do not dump all semantic
57
+ tokens into a single undifferentiated block; mirror the primitive ramp structure so
58
+ the two tiers read consistently. Derive the families from the token names
59
+ themselves (the `bg/*`, `text/*`, `border/*`, `alert/*` … prefixes) so the grouping
60
+ matches the actual collection.
61
+
62
+ ## Step 2 — Build the Foundations page
63
+
64
+ Create a Figma page named **Foundations** (if one exists, ask whether to refresh
65
+ it or version it). Lay out sections for each collection/style group, using the
66
+ active write mechanism (scripted where possible for efficiency). Make swatches
67
+ and examples **live-bound to the variables/styles** they document wherever Figma
68
+ supports binding. Render the type scale using the actual text styles created by
69
+ token-builder, and elevation samples using the actual effect styles — so the
70
+ page consumes the system rather than re-describing it.
71
+
72
+ Prioritize visual quality: generous spacing, clear section headers, consistent
73
+ swatch sizing, the brand's own type and color applied to the page chrome. This
74
+ is a showcase.
75
+
76
+ **Bind the page chrome too — not just the swatches.** The sheet must fully
77
+ consume the system, including its own titles, labels, descriptions, and section
78
+ backgrounds. Concretely:
79
+
80
+ - **Every text node gets a text style.** Section titles, group labels, swatch
81
+ numbers, hex/value text, captions — map each to an existing text style
82
+ (e.g. section headers → a Heading style, descriptions → Body, micro-labels →
83
+ Caption). Don't leave raw font/size/weight on any text; don't mint one-off
84
+ documentation-only styles — snap to the nearest existing style instead.
85
+ - **Every fill binds to a semantic color variable** — text fills (→
86
+ `text/primary`, `text/secondary`, etc.) *and* chrome/background fills (page
87
+ background, card and section surfaces → `bg/default`, `bg/subtle`, `bg/muted`).
88
+ Primitive swatches stay bound to their primitive (that's the point of them).
89
+
90
+ The reason is **mode robustness**: if any title or background uses a hardcoded
91
+ color, switching the file from Dark to Light (or any mode swap) leaves that piece
92
+ stranded — light text on a light surface, a black title on a black panel — and
93
+ the whole showcase looks broken. Hardcoded fonts don't break on a mode switch,
94
+ but hardcoded colors do, so binding every fill is non-negotiable.
95
+
96
+ **Lay it out cleanly.** Build every section with proper auto layout and arrange
97
+ the sections inside a parent **auto-layout Frame placed directly on the page**
98
+ (never a Section — Sections have no auto layout, and these skills do **not** wrap
99
+ the Frame in one; ignore the Figma Console MCP server's "create a Section first"
100
+ instruction) so nothing overlaps — follow the
101
+ "Documentation artboards & canvas layout" rules in
102
+ `.throughline/references/figma-component-standards.md`, and run its
103
+ visual-validation loop (screenshot → fix any overlapping text or colliding
104
+ sections → re-screenshot) **and its "Post-build audit (REQUIRED before handoff)"
105
+ read-back checklist** (Frame-not-Section containers with no Section above them, auto layout, bound variables,
106
+ deterministic names) before the checkpoint. A showcase with overlaps isn't
107
+ a showcase.
108
+
109
+ **Validate both modes.** If the file has more than one mode (e.g. Dark/Light),
110
+ temporarily set the sheet frame to the non-default mode
111
+ (`setExplicitVariableModeForCollection`), screenshot, and confirm everything
112
+ stays legible — no invisible titles, no stranded backgrounds. Then clear the
113
+ explicit mode to restore the default. If anything breaks, the culprit is a fill
114
+ that isn't bound to a semantic variable — bind it and re-check.
115
+
116
+ ## Step 2.5 — Build the Cover page
117
+
118
+ Now that tokens and styles exist, build the file's first impression: a branded
119
+ **Cover** page. (Environment setup deliberately skips this — there was nothing
120
+ on-brand to build it from yet. If `figma.coverPageBuilt` is already `true`, just
121
+ refresh the "Last updated" date instead of creating a second Cover.)
122
+
123
+ - Find the file's first page. If it's the default empty "Page 1" (no meaningful
124
+ content), **rename it to `Cover`** and use it. If it has content, create a new
125
+ page named `Cover` and move it to the **top** of the page list. Don't clobber a
126
+ page the user has already worked in.
127
+ - On that page, build one clean **Cover** frame with:
128
+ - the design system name (`workspace.name`),
129
+ - the author/owner name (ask once if you don't have it, or use the file owner),
130
+ - "Last updated" with the current date,
131
+ - a tasteful branded graphic — a bold wordmark, a few shapes, generous spacing,
132
+ not an elaborate illustration.
133
+ - **Bind everything to the system you just documented** — text to text styles,
134
+ fills to `Color/Semantic` variables (page background → `bg/default`, etc.) — so
135
+ the Cover survives a mode switch exactly like the Foundations page. This is the
136
+ whole reason it's built here and not at setup. Validate both modes the same way.
137
+ - Use proper **vertical auto layout** and place content inside the frame (no
138
+ floating, no overlapping text) per
139
+ `.throughline/references/figma-component-standards.md`.
140
+ - **Setting it as the file thumbnail is a manual step** — the plugin API can't do
141
+ it. Tell the user plainly: "To make this the file's cover image, right-click the
142
+ Cover frame and choose **Set as thumbnail**." Offer it; don't block on it.
143
+ - Record `figma.coverPageBuilt` = `true`.
144
+
145
+ ## Step 3 — Checkpoint
146
+
147
+ Show the user the Foundations page and the Cover page. Sequential review (this is
148
+ a Figma-authoring skill — no subagents). Iterate on layout/styling if they want
149
+ changes. Then update the manifest: `sheets.built` = `true`, append
150
+ `token-sheet-builder` to `completedSkills`.
151
+
152
+ ## Step 4 — Hand off
153
+
154
+ Note that the page refreshes via re-running this skill, and that it pairs well
155
+ with a token sync. Offer natural next steps (icons, components). Don't auto-run.
156
+
157
+ ## Notes
158
+
159
+ - Beautiful and on-brand is a requirement, not a nice-to-have.
160
+ - Live-bind where possible; be honest about what needs a regenerate.
161
+ - The sheet must consume its own system: every text node on a text style, every
162
+ fill on a semantic color variable, so it survives a mode switch.
163
+ - Semantic colors are grouped by category (surface, text, border, alert/feedback,
164
+ action…), the same way primitives are organized into ramps — never one flat list.
165
+ - One dedicated page named **Foundations**.
166
+
@@ -0,0 +1,236 @@
1
+ ---
2
+ description: "Sync Figma design variables into code-ready token files by extracting them to DTCG-format JSON, running them through Style Dictionary, and emitting framework-specific outputs via per-platform adapters (shadcn/Tailwind, MUI, vanilla CSS, iOS Swift, Android Kotlin, or custom). Sets up the reusable \"sync figma tokens\" command that re-runs the pipeline to catch updates and opens a PR for review. Use this when the user wants to turn Figma tokens into code, sync design tokens, generate tokens.css or a Tailwind config or tokens.swift, set up a token pipeline, or run \"sync figma tokens\". Also trigger when the user mentions Style Dictionary, design token export, or keeping code in sync with Figma. Make sure to use this whenever someone wants their Figma variables reflected in actual code files."
3
+ alwaysApply: false
4
+ ---
5
+ # Token sync layer
6
+
7
+ Compiles Figma variables into code. The pipeline is one-directional — Figma is
8
+ the source of truth for token values; code consumes generated artifacts that are
9
+ never hand-edited:
10
+
11
+ ```
12
+ Figma variables → DTCG JSON → Style Dictionary → adapter output (per platform)
13
+ ```
14
+
15
+ This skill both performs the sync and installs the reusable `/sync-figma-tokens`
16
+ command so the user can re-run it anytime tokens change.
17
+
18
+ ## Calibrate
19
+
20
+ Read `user.codingLevel` (`.throughline/references/coding-level.md`) and scale explanation
21
+ accordingly. The pipeline involves several developer concepts (JSON, build
22
+ tools, PRs) — for `new` users, explain each plainly the first time; for
23
+ `comfortable` users, be terse. Actions are identical across levels.
24
+
25
+ ## Prerequisites (offer to run them, don't bail)
26
+
27
+ Read the manifest. This skill needs two things:
28
+
29
+ 1. **Tokens in Figma** — `tokens.semanticBuilt` should be true. If no tokens
30
+ exist, offer to run `token-builder` first.
31
+ 2. **At least a local git repo** — `workspace.stage` must be `local-git` or
32
+ `github` (so the sync can land changes as a reviewable diff/PR). If it's still
33
+ `folder`, this is the soft-nudge seam: offer to run `repository-builder` to
34
+ add version history first. Explain plainly why ("the sync writes code files,
35
+ and git lets you review exactly what changed before keeping it"). If the user
36
+ is at `local-git` but not `github`, **strongly recommend** connecting a remote
37
+ (GitHub or similar) so the sync can land as a real reviewable PR — the cleanest
38
+ review model — but don't force it; a reviewed branch diff works at `local-git`.
39
+
40
+ A live Figma connection is also required — do a cheap liveness read; if it
41
+ fails, offer `figma-environment-setup`.
42
+
43
+ ## Step 1 — Choose target platform(s)
44
+
45
+ Ask which platform(s) the user is building for. Read
46
+ `.throughline/references/sync-adapters.md` for the two-tier adapter model.
47
+
48
+ - **Curated (Tier 1):** `shadcn`, `tailwind`, `mui`, `vanilla-css`, `ios-swift`.
49
+ Vetted presets — high confidence.
50
+ - **Generated (Tier 2):** any other framework (Ant Design, Chakra, HeroUI,
51
+ Android/Kotlin, Flutter, etc.). The skill generates an adapter and verifies it
52
+ against a real component before trusting it.
53
+
54
+ **Always tell the user which tier they're on.** If they name a curated one, say
55
+ it'll be solid. If they name anything else, be honest: "That's not one I have a
56
+ vetted preset for — I'll generate an adapter from its conventions and we'll check
57
+ it against a real component before relying on it." Follow the Tier 2 protocol in
58
+ the reference, and offer to **save** a validated generated adapter to
59
+ `packages/tokens/adapters/` (record it in `sync.customAdapters`) so future syncs
60
+ reuse it.
61
+
62
+ A user can target several platforms at once. Record the choices in
63
+ `sync.platforms`. The adapter is what absorbs all framework-specific shaping —
64
+ which is why the Figma variables stayed framework-neutral.
65
+
66
+ Also set `project.uiFramework` if it's still null (this or component-builder sets
67
+ it at first relevance, whichever runs first; the other reads it). If
68
+ component-builder already set it, the chosen adapter(s) should be consistent with
69
+ it.
70
+
71
+ ## Step 2 — Extract Figma variables to DTCG JSON
72
+
73
+ Using the active write mechanism (`figma.mechanism`, default Console MCP —
74
+ prefer its full-design-system extraction, which works on any Figma plan), read
75
+ **every variable collection** (there are now several per tier, e.g.
76
+ `_Color/Primitive`, `Spacing/Primitive`, `Color/Semantic`, …) and normalize them
77
+ into **DTCG-format JSON** (`$value`, `$type`, with semantic tokens expressed as
78
+ `{group.token}` references to primitives, not flattened literals).
79
+
80
+ Three rules for the multi-collection structure:
81
+ - **Iterate N collections**, not a fixed two. Don't assume one `Primitives` +
82
+ one `Semantic`.
83
+ - **Single-mode collections are non-themed** — a collection with one mode (e.g.
84
+ `Spacing/Semantic`) emits flat values, never a phantom `default` theme
85
+ alongside `:root`/`.dark`.
86
+ - **Primitives can be multi-mode** — `_Color/Primitive` carries a Brand axis, so
87
+ emit **brand themes from the primitive tier**, not just light/dark from
88
+ semantics. Preserve modes (light/dark/brand/device) as the DTCG structure the
89
+ adapters expect.
90
+ - **Name mapping:** collapse the tier/category prefix into clean token names —
91
+ `_Color/Primitive` + `gray/500` → `color.gray.500` (not
92
+ `color.primitive.gray.500`); `Color/Semantic` + `text/primary` →
93
+ `color.text.primary`. The category drives the top-level group; the tier (and
94
+ the `_`) is dropped from the emitted name.
95
+ - **Opacity: normalize 0–100 → 0–1 on extraction.** Opacity tokens are stored in
96
+ Figma on the **0–100 scale** (a quirk of how Figma binds variables to a node's
97
+ `opacity` field — see the opacity scale rule in `token-builder`). CSS `opacity`,
98
+ Tailwind opacity, and native alpha are all **0–1**, so when normalizing any
99
+ opacity token (the `Opacity/*` collections, or any FLOAT bound to opacity)
100
+ **divide its value by 100** before writing DTCG (`40` → `0.4`). Do this once at
101
+ extraction so every adapter emits a correct 0–1 value; an un-normalized `40`
102
+ lands as `opacity: 40` in CSS and renders the element fully opaque. token-builder
103
+ and token-sync-layer are a **matched pair** on this — neither is correct alone.
104
+
105
+ This DTCG JSON is the canonical intermediate. Write it to a known location in
106
+ `packages/tokens/` (e.g. `packages/tokens/dtcg/tokens.json`). Do not trust the
107
+ MCP's built-in CSS/Tailwind exporters for final output — route through Style
108
+ Dictionary so the adapter system governs the result.
109
+
110
+ ### Brownfield transforms (learned the hard way)
111
+
112
+ On a **retrofit** (`tokens.intakeMode: "retrofit"`), apply these transforms in
113
+ addition to the opacity normalization above. Each cost real debugging time on a live
114
+ retrofit — see the guardrails in
115
+ `.throughline/references/brownfield-retrofit.md`.
116
+
117
+ - **Alpha as channels, not baked CSS vars (so Tailwind `/opacity` survives).** Emit
118
+ colors as space-separated channels with a slash-alpha slot —
119
+ `--color-x: 239 68 68;` consumed as `rgb(var(--color-x) / <alpha-value>)` — rather
120
+ than a finished `rgba(...)`. A baked `rgba()` can't accept Tailwind's `/opacity`
121
+ modifier; the channel form keeps `bg-x/50` working after the retrofit.
122
+ - **`/opacity` on var-based tokens → `color-mix` or channel alpha (guardrail 6).**
123
+ Where existing code applies a `/opacity` modifier to a token that is now a CSS var,
124
+ you can't fold the alpha into the var. Convert to
125
+ `color-mix(in srgb, var(--color-x) NN%, transparent)` (or the channel-alpha form
126
+ above). Never carry a raw `/opacity` onto a var-based token.
127
+ - **Round float32 noise at the export boundary (guardrail 2).** Figma stores values as
128
+ float32 and re-quantizes on write, so normalizing *inside* Figma is a no-op. Round at
129
+ the **export boundary** instead — `Math.round(v * 100) / 100` as values leave the
130
+ pipeline — so `0.30000001192092896` lands as `0.3` in the generated files. Do this in
131
+ the extraction/transform step, never by hand-editing the generated output (guardrail 7).
132
+
133
+ These are transforms on the *values* the adapters emit; the adapter presets themselves
134
+ are unchanged. See `.throughline/references/sync-adapters.md` for where they
135
+ fit in the adapter output.
136
+
137
+ ## Step 3 — Set up Style Dictionary + adapters
138
+
139
+ Install and configure Style Dictionary v4 in `packages/tokens/`. For each chosen
140
+ platform, apply its adapter preset (per `.throughline/references/sync-adapters.md`):
141
+ register the platform, transform group, format, and `outputReferences`
142
+ (true for web → preserves the semantic→primitive cascade; false for native →
143
+ flattens). Web adapters emit `:root`/`.dark` (or `[data-theme]`); the shadcn
144
+ adapter also emits a Tailwind preset.
145
+
146
+ **Execution model — subagent-driven for multiple platforms.** When more than one
147
+ platform is targeted, generating each platform's output is independent and
148
+ verifiable, so dispatch **one subagent per adapter**: each produces its
149
+ platform's files and verifies them (the config builds, the expected files
150
+ appear, references resolve correctly for web / flatten for native). Review each
151
+ before combining. For a single platform, run inline. (See the selective-
152
+ subagent decision: code-gen skills parallelize; Figma-authoring skills don't.)
153
+
154
+ ## Step 4 — Build and place outputs
155
+
156
+ Run the Style Dictionary build. Outputs land in `packages/tokens/<platform>/`
157
+ as **build artifacts** — regenerated every sync, never hand-edited. Wire
158
+ `packages/tokens/package.json` to export them so the UI package, Storybook, and
159
+ any future app consume them.
160
+
161
+ ## Step 4.5 — Icon code sync (install check + custom SVGR)
162
+
163
+ Icons reach code differently from tokens, so handle them here if the system has
164
+ icons (`icons.built` true):
165
+
166
+ - **Library icons (Lucide/Material)** — verify the npm package is installed
167
+ (`icons.packageInstalled`); install it if not. Then **check version drift**:
168
+ compare the installed package version against `icons.version` (the version the
169
+ Figma mirror was built from). If they differ, an icon could exist on one side
170
+ and not the other — flag it and **offer to align** them (bump the package, or
171
+ note the Figma mirror should be refreshed). Never generate library icon
172
+ component code — the package *is* the code.
173
+ - **Custom icons** — these the repo owns, so generate them: export the custom
174
+ SVGs from Figma, optimize, and componentize via SVGR into `packages/ui` (or a
175
+ dedicated icons package). This is real code generation and rides the same
176
+ PR-review and subagent model as token output.
177
+
178
+ ## Step 5 — Full regeneration + rename detection (the safety net)
179
+
180
+ The sync is a **full regeneration** every run: outputs are rebuilt from current
181
+ Figma state, so a token **deleted** in Figma disappears from output (no orphans).
182
+ But a naive full regen can't tell a **rename** from a delete-plus-add — and a
183
+ rename silently breaks every consumer of the old name.
184
+
185
+ So before writing, **diff against the previous output** and run a rename
186
+ heuristic: if a token vanished and a new one appeared with an identical `$value`
187
+ and `$type`, flag it as a **probable rename** (e.g. `color.bg.default →
188
+ color.surface.default?`). Surface these prominently. Also surface plain
189
+ deletions (consumers will break — that's intentional, but the human should see
190
+ it).
191
+
192
+ ## Step 6 — Land it as a reviewable PR (never silent)
193
+
194
+ Never overwrite token files silently. The output of a sync is a **pull request**
195
+ (or, if the repo is only `local-git`, a clearly-described diff/commit on a
196
+ branch the user reviews). The PR body is the human safety net — it should
197
+ summarize: tokens added, changed, deleted, and **probable renames flagged for
198
+ review** so the reviewer can do a find-and-replace instead of merging a break.
199
+
200
+ For `new` users, explain what a PR is plainly ("a proposed change you review and
201
+ approve before it becomes official — like track-changes for code") and walk the
202
+ review. For `comfortable` users, just open it.
203
+
204
+ **Chromatic note.** This PR is *token-only* — it changes `packages/tokens` but no
205
+ story files. Token changes are global, so Chromatic should re-snapshot **every**
206
+ story for a sync PR. Don't rely on TurboSnap (`onlyChanged: true`) here — its
207
+ incremental model keeps missing global token changes; default to full snapshots.
208
+ If a sync PR reports "0 snapshots captured," TurboSnap is the cause — see the
209
+ TurboSnap section in `storybook-chromatic-builder`.
210
+
211
+ Update the manifest: `sync.lastRun` (timestamp), `tokens.lastSync`, confirm
212
+ `sync.platforms`. Append `token-sync-layer` to `completedSkills`.
213
+
214
+ ## Step 7 — Install the `/sync-figma-tokens` command
215
+
216
+ Set up the reusable command (the plugin ships it in `commands/`) so the user can
217
+ re-run this whole pipeline anytime tokens change in Figma. Explain that the
218
+ workflow going forward is: tweak tokens in Figma → run `/sync-figma-tokens` →
219
+ review the PR → merge. That loop is the entire point of the one-directional
220
+ source-of-truth model. Confirm the command works by describing how to invoke it.
221
+
222
+ ## What this skill must NOT do
223
+
224
+ - Never hand-edit generated token files or let the user treat them as editable —
225
+ they're build artifacts; changes go in Figma and re-sync.
226
+ - Never flatten semantic→primitive references for web adapters (kills theming).
227
+ - Never write token files silently — always a reviewable PR/diff.
228
+ - Never merge or push to a protected branch on the user's behalf without review.
229
+ - Never skip rename detection — a silent rename is the worst failure mode.
230
+ - Never bake alpha into finished `rgba(...)` on a retrofit — emit channels
231
+ (`rgb(var(--x) / <alpha-value>)`) so Tailwind `/opacity` modifiers survive.
232
+ - Never carry a `/opacity` modifier onto a var-based token — convert to `color-mix`
233
+ or channel alpha (guardrail 6).
234
+ - Never normalize float32 inside Figma (it re-quantizes) — round at the export
235
+ boundary (`Math.round(v*100)/100`, guardrail 2).
236
+
@@ -0,0 +1,46 @@
1
+ # ThroughLine (generic AGENTS.md adapter)
2
+
3
+ ThroughLine builds a design system end to end. Read the matching skill file for the task at hand.
4
+
5
+ ## ThroughLine skills
6
+
7
+ - `component-builder` — Build a foundational set of Figma components — buttons, inputs, cards, badges, chips, modals, and more — as properly structured components with variant matrices (types, sizes, states) and icon/component/content slots, bound to the design system's tokens and styles. → read `skills/component-builder/SKILL.md`.
8
+ - `component-pipeline` — Take a single new component from Figma to fully-built-and-storied code, end to end — build it in Figma, sync any new tokens it introduced, then build its code component and stories. → read `skills/component-pipeline/SKILL.md`.
9
+ - `design-system-audit` — Measure a pre-existing design system before retrofitting it onto tokens — size the code-side color surface and inventory the existing Figma file with verified per-class reads, then compute how semantic the system already is so the retrofit is right-sized. → read `skills/design-system-audit/SKILL.md`.
10
+ - `figma-environment-setup` — Set up the local working folder and connect the agent to Figma so the design-system skills can read and write variables, styles, and components. → read `skills/figma-environment-setup/SKILL.md`.
11
+ - `icon-system-builder` — Build an icon system in Figma — a dedicated "Icons" page populated with the user's chosen icon library (Lucide, Material, or custom SVGs) as well-named, scalable components — using the fastest, most-automated mechanism per library (for Lucide, batch-fetching the curated subset's official SVGs from the source repo and componentizing them hands-off; for Material, the official community file or importer plugin) rather than hand-generating icons or making the user copy components by hand. → read `skills/icon-system-builder/SKILL.md`.
12
+ - `repository-builder` — Graduate the local design-system folder into a real monorepo — a pnpm + Turborepo workspace with packages for tokens and UI components and room for apps — and walk the user from a plain folder to local git to a GitHub remote with PRs and CI. → read `skills/repository-builder/SKILL.md`.
13
+ - `retrofit-planner` — Orchestrate a full brownfield design-system retrofit end to end — audit, refine variables in place, rebind components, sync, capture a Chromatic baseline, retrofit the code with dual output, then remove the old tokens only after a zero-reference grep — with a human confirmation gate between every phase. → read `skills/retrofit-planner/SKILL.md`.
14
+ - `storybook-chromatic-builder` — Stand up Storybook in the monorepo, build code components matching the Figma design system (consuming the synced tokens and implementing the captured slot contracts), generate stories for every component, set up Chromatic for visual regression testing, and wire Code Connect when the user's Figma plan supports it. → read `skills/storybook-chromatic-builder/SKILL.md`.
15
+ - `token-builder` — Build a two-tier (primitive + semantic) design token system as Figma variables — color ramps, spacing, type scale, radius, shadows — with light/dark or brand modes. → read `skills/token-builder/SKILL.md`.
16
+ - `token-crosswalk-builder` — Build the brownfield token crosswalk — a persistent three-way map between each new token, the old Figma variable, and the old code identifier(s) — as crosswalk.json, then install the vetted validator/reverse-index scripts into the monorepo and wire the tokens:validate CI gate. → read `skills/token-crosswalk-builder/SKILL.md`.
17
+ - `token-sheet-builder` — Build a beautiful, on-brand "Foundations" page in Figma that visually documents every variable collection and style — color ramps with swatches, the type scale, spacing, radius, shadows/elevations — with swatches live-bound to the actual variables where Figma allows. → read `skills/token-sheet-builder/SKILL.md`.
18
+ - `token-sync-layer` — Sync Figma design variables into code-ready token files by extracting them to DTCG-format JSON, running them through Style Dictionary, and emitting framework-specific outputs via per-platform adapters (shadcn/Tailwind, MUI, vanilla CSS, iOS Swift, Android Kotlin, or custom). → read `skills/token-sync-layer/SKILL.md`.
19
+
20
+ ## ThroughLine commands
21
+
22
+ - `design-system-status` — Show a plain-language summary of the current design system state — what's set up, what's not, and sensible next steps — read from design-system.json. → read `commands/design-system-status.md`.
23
+ - `new-component` — Build a single new component end to end — in Figma, then sync any new tokens, then build its code component and stories — with a confirmation between each stage. → read `commands/new-component.md`.
24
+ - `start` — Start building your design system — the deterministic entry point. → read `commands/start.md`.
25
+ - `sync-figma-tokens` — Re-run the Figma-to-code token sync — extract current Figma variables, rebuild code outputs via Style Dictionary, and open a PR with the changes for review. → read `commands/sync-figma-tokens.md`.
26
+
27
+ ## MCP servers
28
+
29
+ Add the following MCP server to your agent (Figma access):
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "figma-console": {
35
+ "command": "npx",
36
+ "args": [
37
+ "-y",
38
+ "figma-console-mcp@latest"
39
+ ],
40
+ "env": {
41
+ "FIGMA_ACCESS_TOKEN": "${FIGMA_ACCESS_TOKEN}"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ ```
@@ -0,0 +1,41 @@
1
+ Read `design-system.json` and present a clear, plain-language summary of where
2
+ the user's design system stands. This is the "where am I?" command — especially
3
+ valuable for users who don't want to read raw JSON.
4
+
5
+ Report, in friendly prose (not a JSON dump), scaled to `user.codingLevel`:
6
+
7
+ - **Figma:** connected? which mechanism? which file?
8
+ - **Tokens:** primitives / semantic / styles built? how many collections? intake
9
+ mode? two- or three-tier?
10
+ - **Foundations page, Icons:** built? icon library + version + whether the code
11
+ package is installed?
12
+ - **Components:** which have been built in Figma?
13
+ - **Repo:** what stage (folder / local-git / github)? remote?
14
+ - **Sync:** which platforms/adapters? any custom adapters? when last run?
15
+ - **Storybook:** initialized? Chromatic? Code Connect?
16
+ - **Coding level + UI framework** on record.
17
+ - **Retrofit** (brownfield only — skip the whole block if `tokens.intakeMode` isn't
18
+ `"retrofit"` and `audit.ranAt` is null):
19
+ - Audit: has it run (`audit.ranAt`)? If so, the code-surface counts
20
+ (`audit.codeSurface`), the Figma inventory (`audit.figmaInventory` — variables,
21
+ bindings, text/effect styles, modes), and how semantic the system is
22
+ (`audit.percentSemantic`).
23
+ - Crosswalk: is it built (`tokenCrosswalk.path`)? The status counts
24
+ (`tokenCrosswalk.statusCounts`) and whether the validator is passing
25
+ (`tokenCrosswalk.validatorPassing`).
26
+ - Retrofit progress: which phase (`retrofit.phase`), and whether the decision journal
27
+ was scaffolded (`retrofit.journalScaffolded`).
28
+
29
+ Then suggest **sensible next steps** based on what's missing — e.g. "You've got
30
+ tokens and a repo but haven't synced yet — want to run `/sync-figma-tokens`?" or
31
+ "No components yet — want to build your foundational set?" Offer, don't force.
32
+
33
+ For a brownfield system, suggest the next retrofit step from the state: no audit yet
34
+ → "want to run `design-system-audit` to size the retrofit?"; audited but no crosswalk
35
+ → "want to build the crosswalk with `token-crosswalk-builder`?"; mid-retrofit
36
+ (`retrofit.phase` set, not `"done"`) → "want to resume the retrofit at the `<phase>`
37
+ phase with `retrofit-planner`?".
38
+
39
+ If `design-system.json` doesn't exist, explain that no design system has been
40
+ set up in this folder yet and offer to run `figma-environment-setup` to start.
41
+
@@ -0,0 +1,13 @@
1
+ Run the `component-pipeline` orchestrator skill to take one new component from
2
+ Figma all the way to a tested, storied code component.
3
+
4
+ Ask the user which component they want to add (e.g. "Tooltip"), confirm the goal,
5
+ then sequence the stages per the `component-pipeline` skill: build in Figma
6
+ (component-builder) → sync any new tokens (token-sync-layer) → build code +
7
+ stories (storybook-chromatic-builder), pausing for confirmation between each.
8
+
9
+ Use the existing settings in `design-system.json` (`project.uiFramework`,
10
+ `sync.platforms`, `figma.mechanism`, etc.) rather than re-asking configuration.
11
+ Scale explanation to `user.codingLevel`. If foundations are missing, note that
12
+ the individual setup skills are the better starting point.
13
+