@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,22 @@
1
+ This is the **first step** for building a design system with ThroughLine. The
2
+ user invoked it explicitly, so begin immediately — do **not** invoke any
3
+ brainstorming or planning skill first. There is nothing to brainstorm until the
4
+ environment exists: the local working folder must be created and Figma must be
5
+ connected before any design work can happen.
6
+
7
+ Invoke the `figma-environment-setup` skill now and follow it exactly. It will:
8
+
9
+ 1. Locate or create the project directory and scan what's already there.
10
+ 2. Create the local working folder and write the `design-system.json` manifest.
11
+ 3. Connect the agent to Figma and verify the connection.
12
+
13
+ If `design-system.json` already exists in this folder, the setup skill will
14
+ detect it and route the user to the right next step rather than starting over —
15
+ let it make that call. That routing now covers brownfield systems too: an
16
+ existing/mature repo or populated Figma file is sent to `design-system-audit`
17
+ first, and an in-progress retrofit (`retrofit.phase` set) resumes at its phase
18
+ via `retrofit-planner` — the setup skill makes that call.
19
+
20
+ Scale all explanation to the user's coding level. Assume they may be
21
+ design-fluent but new to developer tooling, terminals, and API tokens.
22
+
@@ -0,0 +1,22 @@
1
+ Re-run the token sync pipeline to catch any updates made in Figma.
2
+
3
+ Follow the `token-sync-layer` skill's pipeline using the settings already
4
+ recorded in `design-system.json` (`sync.platforms`, `figma.mechanism`,
5
+ `figma.fileKey`) — don't re-ask configuration that's already set. Specifically:
6
+
7
+ 1. Verify Figma is connected (cheap liveness read); if not, offer
8
+ `figma-environment-setup`.
9
+ 2. Re-extract Figma variables to DTCG JSON.
10
+ 3. Rebuild outputs through Style Dictionary for every platform in
11
+ `sync.platforms`.
12
+ 4. Run full-regeneration with **rename detection** — diff against the previous
13
+ output, flag probable renames (vanished + reappeared with identical
14
+ `$value`/`$type`) and plain deletions.
15
+ 5. Open a **reviewable PR** (or a reviewed branch diff if the repo is only
16
+ `local-git`) summarizing added / changed / deleted / probable-renames. Never
17
+ write silently.
18
+ 6. Update `sync.lastRun` and `tokens.lastSync` in the manifest.
19
+
20
+ Scale explanation to `user.codingLevel`. This is the recurring loop of the whole
21
+ system: tokens change in Figma → `/sync-figma-tokens` → review PR → merge.
22
+
@@ -0,0 +1,272 @@
1
+ # Component builder
2
+
3
+ Creates the foundational component set in Figma: well-structured components with
4
+ variant matrices, bound to the system's tokens/styles, with slots typed so they
5
+ translate cleanly to code later.
6
+
7
+ ## Prerequisites
8
+
9
+ Needs tokens (`tokens.semanticBuilt` true) — offer to run `token-builder` if
10
+ missing. Needs a live Figma connection (offer `figma-environment-setup` if not).
11
+ Use the mechanism in `figma.mechanism`.
12
+
13
+ **Before scripting any `figma_execute`, read
14
+ `.throughline/references/figma-scripting.md`** — the single-bridge-instance
15
+ preflight, the `resize()` axis-lock trap (collapses auto-layout frames to ~10px),
16
+ the `dynamic-page` async setters, and why large `WRAP` grids time out. These cause
17
+ silent, screenshot-invisible corruption if not handled up front.
18
+
19
+ **Recommend icons first (soft gate).** Almost every foundational component
20
+ (button, input, select, chip…) takes an icon prop, so the icon set should usually
21
+ exist *before* components — otherwise icon slots have no targets. If
22
+ `icons.built` is false, **recommend running `icon-system-builder` first** and
23
+ explain why in one plain sentence, but let the user override and build icon-less
24
+ if they want (some intentionally do). This is a recommendation, not a hard block.
25
+
26
+ > **Model tip (#3):** this skill does heavy structural reasoning — variant
27
+ > matrices, slot contracts. It runs on your session model; Sonnet is a solid
28
+ > default and Opus helps for large or intricate component sets. See the model
29
+ > guide in the ThroughLine README.
30
+
31
+ ## Step 1 — Capture framework + brainstorm the set and variant matrices
32
+
33
+ **First, check the scope.** If the user wants to **retrofit or migrate an existing
34
+ codebase** rather than build a clean set — e.g. converting a hand-rolled
35
+ component/motion layer to shadcn, or any change that re-architects the system —
36
+ this has outgrown a single skill. Follow
37
+ `.throughline/references/scaling-up-handoff.md`: surface the risks and major parts, confirm
38
+ scope, and brainstorm/plan before building (handing off to Superpowers if it's
39
+ available, else planning natively — never required). For a normal from-the-system
40
+ build, continue here.
41
+
42
+ **Framework (capture lazily, here if not already set).** Read
43
+ `project.uiFramework` from the manifest. If it's null, this is the first
44
+ relevant moment — ask which UI framework the components target (shadcn, MUI,
45
+ vanilla, etc.; reuse the same value the sync adapter will use) and record it.
46
+ If sync already set it, reuse it — don't re-ask. The framework does **not**
47
+ change component structure/anatomy; it informs **variant vocabulary and naming**
48
+ so the Figma component API lines up with the code API, **and it drives the focus-state
49
+ idiom** (shadcn ring vs. MUI per-component vs. vanilla-css outline — see "State
50
+ handling" in `.throughline/references/figma-component-standards.md`). For
51
+ multi-framework targets, use a neutral vocabulary and the default shadcn-style ring.
52
+
53
+ **Recommended core set (editable).** Propose a sensible foundation and let the
54
+ user add/remove — don't impose a fixed list or make them build from a blank page.
55
+ A good default core: atoms (avatar, badge, spinner) and common components
56
+ (button, input, select, checkbox, radio, chip, card, modal, tooltip). Explain
57
+ why these are the foundation. The user edits the set; whatever they land on gets
58
+ dependency-ordered (next step).
59
+
60
+ **Variant matrices.** Run `.throughline/references/brainstorm-before-build.md`. For each
61
+ component, lock the **variant matrix** — the decisions that, if guessed, produce
62
+ inconsistent output:
63
+
64
+ - **Types** (e.g. button: per the framework's vocabulary — shadcn
65
+ `default/secondary/destructive/outline/ghost/link`, MUI
66
+ `contained/outlined/text`, or neutral for multi-framework).
67
+ - **Sizes** (sm, md, lg). Each size is its **own variant row**, not a state — see
68
+ the layout law below.
69
+ - **States** — **include the full relevant set, don't trim it.** The baseline is
70
+ default, hover, focus, active (pressed), disabled; add the conditional states
71
+ wherever they apply (loading, selected, success/error). Decide which conditional
72
+ states a given component can reach, but never drop a state it genuinely has. See
73
+ "State handling" in `.throughline/references/figma-component-standards.md`
74
+ for the per-component checklist.
75
+ - **Slots** — leading/trailing icons, avatars, adornments (see slot types below).
76
+
77
+ Show the proposed set and matrices back and get sign-off before building.
78
+
79
+ ## Step 2 — Order: atoms before composites
80
+
81
+ Components compose other components — a card slots an avatar, a chip embeds an
82
+ icon. So build in **dependency order, atoms first**, the component-tier analog
83
+ of the primitive→semantic token seam:
84
+
85
+ 1. **Atoms** — avatar, badge, spinner, (icons already exist). No DS-component
86
+ slots, or only icon slots.
87
+ 2. **Composites** — card, chip, list item, modal, input-with-adornments — which
88
+ slot the atoms.
89
+
90
+ This guarantees a composite's typed slot points at a real, already-built target.
91
+ Build bottom-up; checkpoint after each component (sequential — this is Figma
92
+ authoring, no subagents).
93
+
94
+ ## Step 3 — Build each component, bound to tokens/styles
95
+
96
+ For each component, using the active write mechanism (scripted where helpful),
97
+ following `.throughline/references/figma-component-standards.md` (auto layout on everything,
98
+ variants vs. properties used correctly, state handling, shallow nesting,
99
+ deterministic naming):
100
+
101
+ - Construct the variant matrix (Figma variants/component properties), and lay the
102
+ resulting **component set out as an auto-layout grid** following the fixed layout
103
+ law: **variants are rows, states are columns.** One row per variant — each `type`,
104
+ and each `size` (size is a variant, so it gets its own row) — stepping through the
105
+ component's **full relevant state set** across the columns, size groups stacked
106
+ vertically. Per "Component set arrangement" and "State handling" in the standards
107
+ doc.
108
+ - For the **focus state**, build the ring as the target library's real idiom keyed off
109
+ `project.uiFramework` (shadcn/default → border recolor + a `0 0 0 3px` ring;
110
+ vanilla-css → an outside-aligned offset stroke via `offset/focus`; MUI → per-component;
111
+ ios-swift → skip), **not** a house-style stroke. Because a Figma drop-shadow only casts
112
+ from opaque pixels, build it per fill: **filled** control → a drop-shadow effect
113
+ (control frame `clipsContent = true`); **transparent** control → an
114
+ absolutely-positioned ring **child** (`strokeAlign = "OUTSIDE"`). **Never wrap the
115
+ control** in a padded frame to make room for the ring — it inflates the component. See
116
+ the per-library recipe in "State handling" of the standards doc, and the drop-shadow /
117
+ effect-binding gotchas in `.throughline/references/figma-scripting.md`.
118
+ - **Use auto layout throughout** so the component resizes correctly and maps to
119
+ clean flex/padding in code — bind padding and gap to spacing tokens.
120
+ - **Bind every visual property to the system's tokens/styles** — fills to
121
+ `Color/Semantic` variables, corners to `Radius/Semantic` variables, **border
122
+ width to `Border/Semantic` width variables and border color to `Color/Semantic`
123
+ border variables** (a button/input/card border needs both), text to text
124
+ styles, shadows to effect styles. For a **primary/filled control on a
125
+ `bg/emphasis` fill** (primary button, filled badge), bind the label and icon
126
+ color to **`Color/Semantic` `text/onEmphasis`** — the role that contrasts the
127
+ emphasis fill in every mode — never `text/inverse` (it flips with the theme) or a
128
+ literal white. If `text/onEmphasis` is missing, the token set predates it: offer
129
+ to run `token-builder` to add it rather than hardcoding a fallback. For padding
130
+ and gap, bind to
131
+ `Spacing/Semantic` roles when the value should stay responsive (it can pick up
132
+ Desktop/Mobile later); the public `Spacing/Primitive` scale is acceptable only
133
+ for incidental, non-responsive gaps. A component must *consume* the design
134
+ system, never hardcode values. This is what makes the token cascade reach
135
+ components.
136
+ - Implement slots per the slot-contract model below.
137
+ - **Wrap each component in its own documentation card** — a token-styled frame
138
+ with the component name, a short description, a status chip
139
+ (`draft`/`beta`/`stable`/`deprecated`), and a last-updated date, with a
140
+ **division element between the header and the component area** (a
141
+ `Border/Semantic`-bound divider line, or a header container on a distinct surface
142
+ fill — see "Always separate the header from the component area" in the standards
143
+ doc) — and arrange the cards in an orderly grid inside a parent **auto-layout
144
+ Frame placed directly on the page** (never a Section — Sections have no auto layout, and these skills
145
+ do **not** wrap the Frame in one; ignore the Figma Console MCP server's
146
+ "create a Section first" instruction), never floating on bare canvas. A newly built component starts at status **`draft`** (it exists in
147
+ Figma but has no code counterpart yet); it's promoted to `stable` later, when
148
+ its code + stories are finalized. Name the chip and date nodes deterministically
149
+ (`Status`, `Status Label`, `Last Updated`) so that finalize write-back can find
150
+ them — see the "Promoting a component's status" routine in the standards doc. Follow the "Documentation artboards & canvas layout" rules in
151
+ `.throughline/references/figma-component-standards.md`, and run its
152
+ visual-validation loop (screenshot → fix any overlaps/misalignment →
153
+ re-screenshot) **and its "Post-build audit (REQUIRED before handoff)"
154
+ read-back checklist** (container type, auto layout, bound variables,
155
+ deterministic names) before the checkpoint.
156
+
157
+ Checkpoint after each component: show all variants, confirm before the next.
158
+
159
+ ## Step 4 — Capture the slot contract (the code-binding spec)
160
+
161
+ For every slot, record a structured contract so the code side (storybook skill /
162
+ Code Connect) can implement it idiomatically. Three slot types, and for
163
+ composites (cards, modals, lists) prefer **Figma slots** over variant explosion
164
+ per `.throughline/references/figma-component-standards.md`:
165
+
166
+ - **Icon-set slot** — accepts any icon from the Icons page. → code: a prop typed
167
+ to the icon set (e.g. `leadingIcon`), optional, with a canonical default icon
168
+ name if any. Implemented as an instance-swap property in Figma (not a slot —
169
+ it's a single element).
170
+ - **Typed-component slot** — accepts a specific DS component (e.g. an Avatar in a
171
+ Card). → code: a prop typed to that component (e.g. `avatar`), optional. In
172
+ Figma, an instance-swap property, or a Figma slot with **preferred instances**
173
+ for composites.
174
+ - **General adornment / content slot** — accepts arbitrary content (a card body,
175
+ modal content, a unit label). → for freeform areas in composites use a **Figma
176
+ slot**, which maps to `children` / a composition prop in code; for small inline
177
+ adornments a `ReactNode` prop (e.g. `endAdornment`).
178
+
179
+ **Typed dropdown vs. fallback (publishing-gated).** A typed `INSTANCE_SWAP`
180
+ dropdown requires its swap targets (icons, components) to be **published** —
181
+ Figma rejects local unpublished keys for swap targets. Before adding the dropdown,
182
+ check publish state per `.throughline/references/figma-publishing.md`:
183
+
184
+ - **Resolve publish state first (detect-or-ask, bug B3):** a default/`false`
185
+ `figma.libraryPublished` is *unverified* — attempt detection, but know it's
186
+ **usually inconclusive for a self-publish** (REST `figma_get_library_components` 401s
187
+ without a `FIGMA_ACCESS_TOKEN`; bridge `figma_get_library_variables` lists only
188
+ *subscribed* external libraries, never the file's own publish), so **trust the user's
189
+ confirmation and proceed** — don't wait on a check the tools can't give. Never treat a
190
+ `false` as a final "not published". The **real signal is the bridge**: if adding the
191
+ typed `INSTANCE_SWAP` is then rejected for a local/unpublished key, *that's* the
192
+ authoritative "not published yet" — fall back to the toggle + manual-swap slot. See
193
+ `.throughline/references/figma-publishing.md`.
194
+ - **Confirmed published (`figma.libraryPublished` true after detect-or-ask):** add the
195
+ typed `INSTANCE_SWAP` dropdown with preferred values.
196
+ - **Not published (free plan, or not yet):** build the **toggle + manual-swap**
197
+ slot instead — it's fully functional — explain why in plain terms, and add this
198
+ component to `components.instanceSwapUpgradePending` so a later run (after the
199
+ user publishes) can add the typed dropdown. Never present this as a failure.
200
+
201
+ Two rules for every slot:
202
+
203
+ - **Show/hide collapses into prop optionality.** A Figma `hasLeadingIcon`
204
+ boolean does NOT become a separate code boolean — the icon prop is simply
205
+ optional; passing it shows it, omitting hides it. Don't generate a redundant
206
+ boolean prop alongside the slot prop.
207
+ - **The contract syncs; per-instance choices don't.** The slot's existence,
208
+ type, and default sync to code. A specific icon swapped into a specific screen
209
+ instance is a usage decision (made in code by whoever builds the screen, just
210
+ as a designer swaps an instance) and does not sync.
211
+
212
+ Record each component's slots, variant matrix, and token bindings in the
213
+ component spec (for Code Connect when available, else the repo component spec).
214
+
215
+ ## Step 5 — Naming as contract
216
+
217
+ Name components deterministically so Figma↔code mapping is automatic: `Button` ↔
218
+ `Button`, `Avatar` ↔ `Avatar`. This is what lets typed-component slots and the
219
+ storybook build resolve the right imports. Same discipline as icon naming —
220
+ without it, components silently diverge between Figma and code.
221
+
222
+ ## Step 6 — Checkpoint and hand off
223
+
224
+ Update the manifest: add each built component to `components.built`, and record
225
+ its `components.meta[name]` (`status: "draft"`, `updatedAt`) to match the doc
226
+ card. (Finalize to `stable` happens later, in storybook-chromatic-builder.) Ensure
227
+ any component built with the toggle + manual-swap fallback is listed in
228
+ `components.instanceSwapUpgradePending`. Append `component-builder` to
229
+ `completedSkills`.
230
+
231
+ **Upgrade pass:** if `components.instanceSwapUpgradePending` is non-empty, re-resolve
232
+ publish state (detect-or-ask per `.throughline/references/figma-publishing.md`);
233
+ only when it is **confirmed published** (`figma.libraryPublished` true via a verified
234
+ detect-or-ask, not a stale default) offer to add the typed `INSTANCE_SWAP` dropdowns to
235
+ those components and clear each from the list.
236
+
237
+ Offer next steps: build the code counterparts and stories
238
+ (storybook-chromatic-builder), or build a single new component end-to-end later
239
+ (the component-pipeline orchestrator).
240
+
241
+ ## What this skill must NOT do
242
+
243
+ - Never hardcode values that should be token/style bindings — components consume
244
+ the system.
245
+ - Never generate a redundant show/hide boolean alongside an optional slot prop.
246
+ - Never build a composite before its atomic slot targets exist.
247
+ - Never guess variant matrices — brainstorm and confirm them first.
248
+ - Never claim to publish a Figma library — publishing is a manual user step;
249
+ instruct and verify only.
250
+ - Never leave components floating on bare canvas — each goes on a token-styled
251
+ doc card arranged in an auto-layout Frame placed directly on the page (never a
252
+ Section), with the layout visually validated.
253
+ - Never lay out a component set as scattered variants — the `ComponentSet` is an
254
+ auto-layout grid where **variants are rows and states are columns**: one row per
255
+ variant (each `type`, and each `size`, since size is a variant) stepping through
256
+ states across the columns, size groups stacked vertically (see the standards doc).
257
+ - Never ship a component with only its `default` state — include the full relevant
258
+ state set (default/hover/focus/active/disabled plus applicable
259
+ loading/selected/success/error).
260
+ - Never run the component header and the component area together with no division —
261
+ every doc card segments the header from the component area with a divider line or
262
+ a distinct header surface.
263
+ - Never invent a house-style focus ring or wrap the control in a padded frame to make
264
+ room for one — derive the focus state from `project.uiFramework`'s real idiom, built
265
+ as a drop-shadow effect (filled controls) or an absolutely-positioned ring **child**
266
+ (transparent controls), per "State handling" in the standards doc.
267
+ - Never rebuild a published/consumed component set with a delete-and-recreate without
268
+ re-instancing downstream — deleting and recreating a set (e.g. to change the Button's
269
+ internal architecture) **detaches every instance** that referenced its variants (the
270
+ Card's footer buttons, etc.). Record which components consume which, warn before an
271
+ architectural rebuild, and re-instance the affected consumers afterward.
272
+
@@ -0,0 +1,81 @@
1
+ # Component pipeline (orchestrator)
2
+
3
+ Sequences a single new component through the whole flow: Figma → tokens →
4
+ code/stories. This skill holds **zero domain logic of its own** — it is a
5
+ sequencer that invokes the real skills and gates each stage on a human
6
+ confirmation. All the actual work lives in the skills it calls; this keeps it
7
+ from rotting when those skills improve.
8
+
9
+ ## When to use vs. the individual skills
10
+
11
+ Use this for **one new component, end to end**, on a system that already has
12
+ foundations (tokens, repo, sync, Storybook). For initial setup, the individual
13
+ skills run directly. This is the "I have a system; add a Tooltip and take it all
14
+ the way to a tested story" flow.
15
+
16
+ ## Prerequisites
17
+
18
+ Read the manifest. The pipeline assumes foundations exist: tokens built, a repo
19
+ at least `local-git`, sync configured, Storybook initialized. For any missing
20
+ piece, offer to run the relevant skill — but note that if a lot is missing, the
21
+ user probably wants the individual setup skills first, not this orchestrator.
22
+
23
+ ## The sequence (confirm between every stage)
24
+
25
+ Confirm the goal first: "New `Tooltip` component, right? I'll build it in Figma,
26
+ sync any new tokens, then build the code component and its stories — checking
27
+ with you between each step." Then:
28
+
29
+ ### Stage 1 — Build in Figma (invoke component-builder)
30
+
31
+ Invoke the `component-builder` skill for this one component: brainstorm its
32
+ variant matrix and slots, build it bound to tokens following the component
33
+ standards, capture its slot contract. **Checkpoint:** show the finished Figma
34
+ component. Get explicit confirmation before continuing.
35
+
36
+ If the build fails or the user wants changes, stop here — they still have a
37
+ valid (or fixable) Figma component and a clean place to resume. Never push a
38
+ half-built component down the pipeline.
39
+
40
+ ### Stage 2 — Sync new tokens (offer token-sync-layer)
41
+
42
+ The new component may have introduced new tokens (a new semantic role, a new
43
+ spacing step). Offer: "This component added a couple of new tokens — want me to
44
+ sync them to code now?" If yes, invoke `token-sync-layer` (which lands a
45
+ reviewable PR per its own rules). If the component introduced no new tokens, say
46
+ so and skip. **Checkpoint:** confirm the sync PR before continuing.
47
+
48
+ ### Stage 3 — Build code component + stories (offer storybook-chromatic-builder)
49
+
50
+ Offer: "Tokens are synced. Build the code component and its stories now?" If yes,
51
+ invoke `storybook-chromatic-builder` for this one component: build the code
52
+ counterpart implementing the captured slot contract, generate its stories
53
+ (subagent-driven), wire Code Connect if available. **Checkpoint:** confirm the
54
+ component renders and stories build. On approval, that skill **finalizes** the
55
+ component — promoting its status from `draft` to `stable` and writing the new
56
+ chip color + last-updated date back into its Figma doc card (its Step 6). Since
57
+ Figma is still connected from stage 1, the card updates live; the chip should no
58
+ longer read `draft` once the pipeline finishes.
59
+
60
+ ## Resumability
61
+
62
+ Because each stage is gated and invokes a real skill, a failure at any stage
63
+ leaves a clean resume point: the Figma component exists after stage 1, the token
64
+ PR after stage 2, the code/stories after stage 3. The user can stop after any
65
+ stage and pick up later — the manifest reflects what's done.
66
+
67
+ ## After completion
68
+
69
+ Confirm the component went all the way through. Update nothing the sub-skills
70
+ didn't already update (they own their manifest fields). Note the ongoing loops:
71
+ more components via this pipeline, token changes via `/sync-figma-tokens`.
72
+
73
+ ## What this skill must NOT do
74
+
75
+ - Never reimplement what the sub-skills do — only sequence them. If you find
76
+ yourself writing component-building or sync logic here, stop and invoke the
77
+ real skill instead.
78
+ - Never skip a confirmation between stages — the gates are what make it
79
+ resumable and prevent half-updated state.
80
+ - Never push a half-built or unconfirmed component to the next stage.
81
+
@@ -0,0 +1,122 @@
1
+ # Design-system audit (brownfield front door)
2
+
3
+ Measures **both sides** of a pre-existing system so a retrofit can be right-sized,
4
+ before anything is built or changed. It is the brownfield analog of
5
+ `/design-system-status`: where status reports a *local* manifest, this assesses an
6
+ *external, mature* system — a real codebase and an already-populated Figma file.
7
+
8
+ This is a brownfield skill. **Before doing anything, read**
9
+ `.throughline/references/brownfield-retrofit.md` — especially the
10
+ read-discipline principle (never assert absence without a verified read) and the
11
+ `audit` phase of the safe sequence. Greenfield builds skip this skill entirely.
12
+
13
+ ## Calibrate
14
+
15
+ Read `user.codingLevel` (`.throughline/references/coding-level.md`) and scale
16
+ explanation accordingly. The audit surfaces grep counts and a `percentSemantic`
17
+ number — for `new` users explain what each means and why it matters (it decides
18
+ rename-vs-rewrite); for `comfortable` users be terse. The measurements are identical
19
+ across levels.
20
+
21
+ ## Prerequisites
22
+
23
+ Read the manifest. This skill needs Figma connected (`figma.connected: true`) for the
24
+ inventory step, and a repo path for the code-surface step (`workspace.localPath`). If
25
+ Figma isn't connected, offer to run `figma-environment-setup` first. The code-surface
26
+ step works on any repo regardless of `workspace.stage`.
27
+
28
+ ## Step 1 — Size the code surface
29
+
30
+ Measure how many color decisions live in the codebase. Run the color-usage grep
31
+ scaffold against the user's repo:
32
+
33
+ ```bash
34
+ node .throughline/scripts/grep-color-usage.mjs --root <workspace.localPath>
35
+ ```
36
+
37
+ It counts five categories: SCSS color vars, Tailwind color classes, `Colors.*` JS
38
+ usages, raw hex + `rgba()` literals, and SVG hardcoded fills — producing the
39
+ case-study worklist shape.
40
+
41
+ **Tune the patterns to the actual repo, and say what you assumed (read discipline +
42
+ §11).** The shipped patterns are *defaults*, not ground truth. Before trusting the
43
+ counts:
44
+ 1. Look at the repo's real conventions — open a few SCSS/TS files, check the actual
45
+ color-variable prefixes (`$primary-*`, `$grey-*`, a custom prefix), the Tailwind
46
+ color-class names, and whether colors come through a `Colors.*` object or some other
47
+ accessor.
48
+ 2. If the defaults don't fit, write a `--config <patterns.json>` of
49
+ `{ "<category>": { "files": "<regex>", "pattern": "<regex>" } }` tuned to this repo
50
+ and re-run with it.
51
+ 3. **Report which categories used the assumed defaults vs. a tuned pattern** — never
52
+ present default-pattern counts as if they were measured. The script prints this; pass
53
+ it through to the user so partial coverage is visible, not hidden.
54
+
55
+ **Don't assume the stack.** The categories are color-specific but framework-agnostic; a
56
+ repo with no Tailwind simply scores `0` there. Detect what the repo actually uses (is
57
+ there a `tailwind.config`? SCSS? CSS-in-JS?) and explain the counts in those terms.
58
+
59
+ ## Step 2 — Inventory the Figma file (verified per-class reads)
60
+
61
+ Variables, text styles, and effect/paint styles are **different surfaces** — read each
62
+ independently and report "none" only for the class whose own read came back empty
63
+ (read discipline, fixes B2). Before counting variables, ensure all pages are loaded
64
+ (`await figma.loadAllPagesAsync()`); treat a `0` on first read as suspect and re-read
65
+ before reporting (fixes B1).
66
+
67
+ - **Variables** — `figma_get_variables` (handles `dynamic-page`, resolves aliases).
68
+ Record the count.
69
+ - **Bindings** — run the binding-survival audit snippet in
70
+ `.throughline/references/figma-scripting.md` to count consuming bindings.
71
+ This is the load-bearing number: it's what a careless rename would destroy.
72
+ - **Text styles** — `figma_get_text_styles`. Record the count.
73
+ - **Effect/paint styles** — `figma_get_styles`. Record the count.
74
+ - **Modes** — record the mode names per collection (e.g. `["Light", "Dark"]`).
75
+
76
+ Never report a count you didn't read. If a read genuinely returns empty after a
77
+ reliable load, that's a real `0`; if it's suspect, re-read or ask the user once and
78
+ persist — never guess.
79
+
80
+ ## Step 3 — Compute "% semantic"
81
+
82
+ From the inventory, estimate how much of the existing system is already **semantic**
83
+ (named by role — `text/default`, `surface/raised`) vs. **raw/primitive** (named by
84
+ value — `grey-900`, or bare hex). Report it as an integer 0–100 (`audit.percentSemantic`).
85
+
86
+ This single number right-sizes the retrofit: a largely-semantic system (~90%) is a
87
+ **rename-in-place + cleanup** job; a low-semantic one is closer to a **rewrite**.
88
+ Surface it early and plainly — "you're ~90% semantic, so this is mostly renames and a
89
+ cleanup, not a rebuild" — so the user calibrates effort before committing.
90
+
91
+ ## Step 4 — Write the manifest and recommend the next step
92
+
93
+ Write the `audit` section (this skill owns it):
94
+
95
+ - `codeSurface` — the per-category counts from Step 1 (keys vary by what the repo uses;
96
+ omit categories that don't apply rather than reporting a misleading `0`).
97
+ - `figmaInventory` — `{ variables, bindings, textStyles, effectStyles, modes }` from
98
+ Step 2's verified reads.
99
+ - `percentSemantic` — the integer from Step 3.
100
+ - `ranAt` — the current ISO timestamp.
101
+
102
+ Set `tokens.intakeMode: "retrofit"` (this skill establishes the brownfield path — it
103
+ owns this transition). Append `design-system-audit` to `completedSkills`.
104
+
105
+ Then recommend the next step:
106
+ - If the user wants the guided, gated end-to-end retrofit → **`retrofit-planner`**
107
+ (the orchestrator; recommended for multi-session retrofits).
108
+ - If they only want the crosswalk backbone next → **`token-crosswalk-builder`** (it
109
+ reads this `audit` section to seed its rows).
110
+
111
+ ## What this skill must NOT do
112
+
113
+ - Never build, rename, or delete anything — this is a **measurement** skill. Changes
114
+ belong to `token-builder` (refine), the retrofit phases, and cleanup.
115
+ - Never report a count without a verified read (read discipline). An unexpectedly-empty
116
+ read is a suspected error, not ground truth.
117
+ - Never present default grep patterns as measured truth — say what was assumed.
118
+ - Never assume the case-study stack (Tailwind/SCSS/Chromatic). Detect what the repo
119
+ actually uses and degrade gracefully.
120
+ - Never write another skill's manifest fields (e.g. `tokenCrosswalk`, `retrofit.phase`).
121
+ - Never overwrite `workspace.origin` — it is immutable after intake.
122
+