@radicool/throughline 0.14.0 → 0.15.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.
- package/adapters/codex/AGENTS.md +10 -10
- package/adapters/codex/prompts/component-builder.md +59 -15
- package/adapters/codex/prompts/document-component.md +42 -10
- package/adapters/codex/prompts/storybook-chromatic-builder.md +52 -9
- package/adapters/cursor/.cursor/commands/document-component.md +42 -10
- package/adapters/cursor/.cursor/rules/component-builder.mdc +60 -16
- package/adapters/cursor/.cursor/rules/component-pipeline.mdc +1 -1
- package/adapters/cursor/.cursor/rules/design-system-audit.mdc +1 -1
- package/adapters/cursor/.cursor/rules/figma-environment-setup.mdc +1 -1
- package/adapters/cursor/.cursor/rules/icon-system-builder.mdc +1 -1
- package/adapters/cursor/.cursor/rules/repository-builder.mdc +1 -1
- package/adapters/cursor/.cursor/rules/retrofit-planner.mdc +1 -1
- package/adapters/cursor/.cursor/rules/storybook-chromatic-builder.mdc +53 -10
- package/adapters/cursor/.cursor/rules/token-builder.mdc +1 -1
- package/adapters/cursor/.cursor/rules/token-crosswalk-builder.mdc +1 -1
- package/adapters/cursor/.cursor/rules/token-sheet-builder.mdc +1 -1
- package/adapters/cursor/.cursor/rules/token-sync-layer.mdc +1 -1
- package/adapters/generic/AGENTS.md +10 -10
- package/adapters/generic/commands/document-component.md +42 -10
- package/adapters/generic/skills/component-builder/SKILL.md +59 -15
- package/adapters/generic/skills/storybook-chromatic-builder/SKILL.md +52 -9
- package/package.json +1 -1
- package/references/component-doc-archetypes.md +15 -11
- package/references/component-doc-schema.md +23 -5
- package/references/doc-card-builder.md +565 -0
- package/references/doc-writing-standard.md +144 -0
- package/references/figma-component-standards.md +63 -16
- package/references/guide-voice.md +96 -0
- package/references/manifest-schema.md +22 -4
- package/scripts/README.md +23 -0
- package/scripts/build-doc-card-builder.mjs +143 -0
- package/scripts/docs-check.mjs +18 -4
- package/scripts/docs-lint.mjs +163 -0
- package/scripts/install.mjs +13 -1
- package/scripts/lib/doc-card-plan.mjs +101 -0
- package/scripts/lib/doc-card-render.figma.js +371 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Stand up Storybook in the monorepo, build code components matching the Figma design system
|
|
2
|
+
description: "Stand up Storybook in the monorepo, build code components matching the Figma design system, generate stories for every component, set up Chromatic for visual regression testing, and wire Code Connect when the user's Figma plan supports it. Use this when the user wants to set up Storybook, build component stories, add visual regression testing, set up Chromatic, connect Figma components to code, or build the code side of their design system. Also trigger after components and token sync exist, when moving the component library into code."
|
|
3
3
|
alwaysApply: false
|
|
4
4
|
---
|
|
5
5
|
# Storybook + Chromatic builder
|
|
@@ -31,15 +31,16 @@ system). Wire it to consume `packages/tokens` output so stories render with the
|
|
|
31
31
|
real design tokens (import the generated CSS/theme). Checkpoint: confirm
|
|
32
32
|
Storybook runs and shows the token-themed canvas.
|
|
33
33
|
|
|
34
|
-
Install the documentation scripts alongside the token scripts
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- `"docs:check": "node scripts/docs-check.mjs"`
|
|
34
|
+
Install the documentation scripts alongside the token scripts: copy the five
|
|
35
|
+
files and register the three npm scripts listed under **Documentation scripts —
|
|
36
|
+
install as a set** in `.throughline/scripts/README.md`. That table is
|
|
37
|
+
the single source of truth for what a consuming repo gets; do not restate the
|
|
38
|
+
list here.
|
|
40
39
|
|
|
41
40
|
These are the documentation analog of `tokens:validate`; see
|
|
42
|
-
`.throughline/scripts/README.md`.
|
|
41
|
+
`.throughline/scripts/README.md`. This copy is setup, not a forever-fork:
|
|
42
|
+
`/document-component` re-checks these files' freshness on every run and refreshes
|
|
43
|
+
them from the plugin when it has moved on.
|
|
43
44
|
|
|
44
45
|
**pnpm build-script allowlist (first-run gotcha).** On pnpm workspaces, the
|
|
45
46
|
`@storybook/react-vite` install pulls `esbuild`, whose postinstall is blocked by
|
|
@@ -163,6 +164,43 @@ Configure Chromatic to snapshot everything (do **not** set `onlyChanged`), and
|
|
|
163
164
|
verify a token-only PR re-snapshots all stories — they should flip orange against
|
|
164
165
|
the green baseline.
|
|
165
166
|
|
|
167
|
+
### Usage & cost guardrails
|
|
168
|
+
|
|
169
|
+
The full-snapshot default above is the right call for catching regressions, and it
|
|
170
|
+
is also the **maximum-usage** choice: every story, every run. Chromatic bills per
|
|
171
|
+
snapshot, so name this cost shape to the user when you set Chromatic up, and put the
|
|
172
|
+
guardrails in *before* the first big token PR, not after the bill.
|
|
173
|
+
|
|
174
|
+
What Chromatic actually offers (re-verify the live numbers at
|
|
175
|
+
`chromatic.com/pricing` — they drift):
|
|
176
|
+
|
|
177
|
+
- **Free plan (~5,000 snapshots/month):** testing **auto-pauses** when the ceiling
|
|
178
|
+
is hit. No surprise bill, but visual-regression coverage silently *stops* until
|
|
179
|
+
the monthly reset or an upgrade. For a full-suite design system that ceiling
|
|
180
|
+
arrives fast — treat a *paused* build as a red flag, not a passing one.
|
|
181
|
+
- **Paid plans: no hard spending cap.** Overage snapshots auto-bill at month-end.
|
|
182
|
+
The only native guardrail is **usage alerts** — an email when consumption crosses
|
|
183
|
+
a threshold you set (e.g. 90%).
|
|
184
|
+
|
|
185
|
+
The math, so the user sizes the plan honestly: **snapshots ≈ stories × modes ×
|
|
186
|
+
builds.** One `/sync-figma-tokens` PR re-snapshots the *entire* suite × every mode
|
|
187
|
+
in a single build — e.g. 40 components × 2 modes = 80 snapshots per build, and a
|
|
188
|
+
handful of token PRs plus daily `main` builds clears a free tier in a week.
|
|
189
|
+
|
|
190
|
+
So the guardrails, all of them user-controlled (Chromatic will not cap you):
|
|
191
|
+
|
|
192
|
+
1. **Set usage alerts** at ~80% on a paid plan so the bill cannot sneak up. On the
|
|
193
|
+
free plan, make sure the user knows testing *pauses* at the ceiling.
|
|
194
|
+
2. **Scope the CI trigger.** Run Chromatic on **pull requests and `main` only** —
|
|
195
|
+
never on every branch push — path-filter out docs-only changes, and keep it to
|
|
196
|
+
one Chromatic build per commit (no duplicate runs).
|
|
197
|
+
3. **Size the plan to the math** before the first token PR. A large story count is
|
|
198
|
+
also the *only* reason to revisit TurboSnap (see above), and even then treat
|
|
199
|
+
every token change as a full run.
|
|
200
|
+
|
|
201
|
+
Do not silently pick a plan or leave the trigger wide open. Name the tradeoff and
|
|
202
|
+
let the user choose with the numbers in front of them.
|
|
203
|
+
|
|
166
204
|
## Step 5 — Code Connect (plan-gated, skip gracefully)
|
|
167
205
|
|
|
168
206
|
Code Connect ties Figma components to their code counterparts so Figma's dev
|
|
@@ -238,8 +276,10 @@ the `figma_execute` scripting gotchas — `getNodeByIdAsync` and an explicit
|
|
|
238
276
|
re-render the affected surfaces so `docs:check` stays green.
|
|
239
277
|
- If Figma is connected (per `figma.mechanism`), open the component's doc card and
|
|
240
278
|
update the `Status Label` text to `stable`, re-bind the `Status` chip fill to
|
|
241
|
-
the **success** semantic color variable (mode-aware, not a hardcoded hex),
|
|
242
|
-
|
|
279
|
+
the **success** semantic color variable (mode-aware, not a hardcoded hex), then
|
|
280
|
+
re-run the canonical doc-card builder against the same card to refresh the
|
|
281
|
+
header date from the `record.updatedAt` already set above (it locates the date
|
|
282
|
+
node under either header shape) — then screenshot to confirm the chip
|
|
243
283
|
recolored and the date changed.
|
|
244
284
|
- If Figma isn't connected, still update the manifest and tell the user the card
|
|
245
285
|
will reconcile next Figma session (or offer to reconnect and fix it now).
|
|
@@ -300,6 +340,9 @@ that may not exist.
|
|
|
300
340
|
- Never rely on TurboSnap (`onlyChanged: true`) for a token-driven design system
|
|
301
341
|
— its incremental model keeps missing global token changes. Default to full
|
|
302
342
|
snapshots (every story, every run); revisit only at large story counts.
|
|
343
|
+
- Never leave Chromatic's cost shape unspoken or the CI trigger wide open — there
|
|
344
|
+
is no hard spend cap on paid plans, so set usage alerts, run it on PRs + `main`
|
|
345
|
+
only, and size the plan to stories × modes × builds before the first token PR.
|
|
303
346
|
- Never use the sequential model for story-gen — parallelize via subagents.
|
|
304
347
|
- Never capture the Chromatic baseline *after* a code retrofit — baseline before, so
|
|
305
348
|
intended drift-fixes are distinguishable from regressions.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "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
|
|
2
|
+
description: "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, using one collection per category per tier. Use this when the user wants to create design tokens, design variables, a color system, a type scale, a spacing system, or 'build my tokens' in Figma. Also trigger when the user mentions primitives and semantic tokens, variable collections, design system foundations, or modes/themes in Figma."
|
|
3
3
|
alwaysApply: false
|
|
4
4
|
---
|
|
5
5
|
# Token builder
|
|
@@ -1,5 +1,5 @@
|
|
|
1
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) —
|
|
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) — then 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."
|
|
3
3
|
alwaysApply: false
|
|
4
4
|
---
|
|
5
5
|
# Token crosswalk builder
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Build
|
|
2
|
+
description: "Build an 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. 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."
|
|
3
3
|
alwaysApply: false
|
|
4
4
|
---
|
|
5
5
|
# Token sheet builder
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Sync Figma design variables into code-ready token files
|
|
2
|
+
description: "Sync Figma design variables into code-ready token files via DTCG JSON and Style Dictionary, emitting framework-specific outputs (shadcn/Tailwind, MUI, vanilla CSS, iOS Swift, Android Kotlin, or custom), and set up the reusable \"sync figma tokens\" command. 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."
|
|
3
3
|
alwaysApply: false
|
|
4
4
|
---
|
|
5
5
|
# Token sync layer
|
|
@@ -4,18 +4,18 @@ ThroughLine builds a design system end to end. Read the matching skill file for
|
|
|
4
4
|
|
|
5
5
|
## ThroughLine skills
|
|
6
6
|
|
|
7
|
-
- `component-builder` — Build
|
|
7
|
+
- `component-builder` — Build Figma components — buttons, inputs, cards, badges, chips, modals, and more — 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
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
|
|
9
|
+
- `design-system-audit` — Measure a pre-existing design system before retrofitting it onto tokens, so the retrofit is right-sized. → read `skills/design-system-audit/SKILL.md`.
|
|
10
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
|
|
12
|
-
- `repository-builder` — Graduate the local design-system folder into a real monorepo — a pnpm + Turborepo workspace with packages for tokens and UI components
|
|
13
|
-
- `retrofit-planner` — Orchestrate a full brownfield design-system retrofit end to end — audit, refine
|
|
14
|
-
- `storybook-chromatic-builder` — Stand up Storybook in the monorepo, build code components matching the Figma design system
|
|
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) —
|
|
17
|
-
- `token-sheet-builder` — Build
|
|
18
|
-
- `token-sync-layer` — Sync Figma design variables into code-ready token files
|
|
11
|
+
- `icon-system-builder` — Build an icon system in Figma — a dedicated "Icons" page of well-named, scalable icon components from Lucide, Tabler, Phosphor, Material, or custom SVGs. → 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 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, rebind, sync, baseline, code, docs, cleanup — 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, 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, using one collection per category per tier. → 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) — then wire the tokens:validate CI gate. → read `skills/token-crosswalk-builder/SKILL.md`.
|
|
17
|
+
- `token-sheet-builder` — Build an 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. → read `skills/token-sheet-builder/SKILL.md`.
|
|
18
|
+
- `token-sync-layer` — Sync Figma design variables into code-ready token files via DTCG JSON and Style Dictionary, emitting framework-specific outputs (shadcn/Tailwind, MUI, vanilla CSS, iOS Swift, Android Kotlin, or custom), and set up the reusable "sync figma tokens" command. → read `skills/token-sync-layer/SKILL.md`.
|
|
19
19
|
|
|
20
20
|
## ThroughLine commands
|
|
21
21
|
|
|
@@ -8,17 +8,49 @@ Ask which component to document (e.g. "Button"), then:
|
|
|
8
8
|
the `component-builder` skill's *Author the documentation record* step —
|
|
9
9
|
ingest any existing docs first (brownfield), then infer → enrich (from
|
|
10
10
|
`.throughline/references/component-doc-archetypes.md`) → specialize →
|
|
11
|
-
interview.
|
|
12
|
-
|
|
11
|
+
interview. Authored prose follows
|
|
12
|
+
`.throughline/references/doc-writing-standard.md`. Set `updatedAt` to
|
|
13
|
+
today's date (ISO, `YYYY-MM-DD`) whenever the record is written or rewritten —
|
|
14
|
+
it is a projected field and the doc card's header renders it. Once the record is
|
|
15
|
+
written, run `node .throughline/scripts/docs-lint.mjs
|
|
16
|
+
design-system/docs/components/<Name>.doc.json` and fix its warnings. Do not
|
|
17
|
+
raise a separate confirmation for a warning on an `imported`/`user` block:
|
|
18
|
+
draft the rewrite and carry it into the approval gate below, shown as
|
|
19
|
+
before/after and labelled with the block's provenance, so one approval covers
|
|
20
|
+
the whole record. The user approves the drafted record before anything is
|
|
21
|
+
projected (Figma description, doc card, manifest). Blocks the user did not
|
|
22
|
+
clear keep their existing text; blocks the user did clear are stamped
|
|
23
|
+
`imported+user` so a later run neither re-asks nor rewrites them.
|
|
13
24
|
2. **Project it.** Write `design-system/docs/components/<Name>.doc.json`, set the
|
|
14
|
-
Figma component `description`,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
Figma component `description`, rebuild the doc card's `Usage` band with the
|
|
26
|
+
canonical builder (`.throughline/references/doc-card-builder.md` —
|
|
27
|
+
verify its returned summary and stamp `surfaces.docCard.{src,render,renderer}`
|
|
28
|
+
from it), and (if the repo/code side exists) render MDX/JSDoc and run
|
|
29
|
+
`docs:digest` per the `storybook-chromatic-builder` render step.
|
|
30
|
+
3. **Reconcile drift.** Before trusting `docs:check`, confirm the repo's copy of
|
|
31
|
+
the doc scripts is current: compare `DOC_CARD_RENDERER_VERSION` in the repo's
|
|
32
|
+
`scripts/lib/doc-card-plan.mjs` against the same constant in
|
|
33
|
+
`.throughline/scripts/lib/doc-card-plan.mjs`. If the repo file is
|
|
34
|
+
missing, or its version is lower, `docs:check` is reading stale rules and its
|
|
35
|
+
"no drift" is meaningless — say so plainly, and offer to refresh the repo's
|
|
36
|
+
doc scripts from the plugin copy. Refresh the whole set and re-check the npm
|
|
37
|
+
registrations, both per **Documentation scripts — install as a set** in
|
|
38
|
+
`.throughline/scripts/README.md` — a refreshed file whose script was
|
|
39
|
+
never registered is the same failure in a new place. Run `docs:check` (with the
|
|
40
|
+
refreshed scripts, if any). For each drifted surface, offer a per-item
|
|
41
|
+
choice — **re-render** (canonical wins) or **pull-back**
|
|
42
|
+
(fold the surface edit into the record) — and land the result as a reviewable
|
|
43
|
+
change. On a brownfield component's first pass, adopt existing content
|
|
44
|
+
(`provenance: imported`) rather than overwriting it.
|
|
45
|
+
`docs:check` may also report `layout-upgrade-available` (informational, never
|
|
46
|
+
failing): the card's layout predates the current builder. Offer to re-render
|
|
47
|
+
the `Usage` band now — rebuild happens on this touch, never unprompted.
|
|
48
|
+
4. **Close the flow.** Hand back in the four-beat guide voice from
|
|
49
|
+
`.throughline/references/guide-voice.md`: the outcome, what you set
|
|
50
|
+
aside and why, one recommended next step, and at most one light alternative.
|
|
51
|
+
Read existing state to name what is actually outstanding rather than guessing —
|
|
52
|
+
a component at `status: "draft"` with no code surface in `meta[name].doc.surfaces`
|
|
53
|
+
means the code side is deferred. Do not close with a grid of co-equal options.
|
|
22
54
|
|
|
23
55
|
See `.throughline/references/component-doc-schema.md` for the record schema,
|
|
24
56
|
fingerprint contract, and projection mapping. If a component was never built in
|
|
@@ -236,7 +236,9 @@ Read `.throughline/references/component-doc-schema.md` for the exact JSON
|
|
|
236
236
|
schema, the fingerprint algorithm, and the projection contract.
|
|
237
237
|
|
|
238
238
|
**Run the generation pipeline (each layer only fills what it legitimately knows;
|
|
239
|
-
stamp `provenance` per block):**
|
|
239
|
+
stamp `provenance` per block):** all authored prose follows
|
|
240
|
+
`.throughline/references/doc-writing-standard.md` — its plain
|
|
241
|
+
reference register, not this skill's guide voice.
|
|
240
242
|
|
|
241
243
|
0. **Ingest existing docs — brownfield only, runs first.** If docs already exist
|
|
242
244
|
for this component (code JSDoc/MDX/README, or a populated Figma component
|
|
@@ -255,32 +257,74 @@ stamp `provenance` per block):**
|
|
|
255
257
|
accessibility idiom to the target framework (the same field you read for variant
|
|
256
258
|
vocabulary). Provenance `framework`.
|
|
257
259
|
4. **Interview for the non-inferable.** Ask the user for brand/product-specific
|
|
258
|
-
do's & don'ts and intent. Provenance `user`.
|
|
259
|
-
|
|
260
|
-
|
|
260
|
+
do's & don'ts and intent. Provenance `user`. Write the draft to
|
|
261
|
+
`design-system/docs/components/<Name>.doc.json`, run
|
|
262
|
+
`node .throughline/scripts/docs-lint.mjs design-system/docs/components/<Name>.doc.json`,
|
|
263
|
+
and fix the warnings it raises. Do not raise a separate confirmation for
|
|
264
|
+
a warning on an `imported`/`user` block: draft the rewrite and carry it
|
|
265
|
+
into the approval gate below, shown as before/after and labelled with the
|
|
266
|
+
block's provenance. **Show the whole drafted record and get explicit
|
|
267
|
+
approval before projecting it anywhere** (Figma description, doc card,
|
|
268
|
+
manifest) — one approval covers the whole record. Blocks the user did not
|
|
269
|
+
clear keep their existing text; blocks the user did clear are stamped
|
|
270
|
+
`imported+user` so a later run neither re-asks nor rewrites them.
|
|
261
271
|
|
|
262
272
|
**Write the record and project it:**
|
|
263
273
|
|
|
264
274
|
- Write `design-system/docs/components/<Name>.doc.json` (JSON; required fields
|
|
265
275
|
`name`, `summary`, `description`).
|
|
266
276
|
- **Figma component description.** Set the component's native `description` field
|
|
267
|
-
(via `figma_set_description`)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
(via `figma_set_description`) from this exact template — this is the surface
|
|
278
|
+
Dev Mode and Code Connect read, and it must be reproducible byte-for-byte by
|
|
279
|
+
any agent from the same record:
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
<summary>
|
|
283
|
+
|
|
284
|
+
**When to use**
|
|
285
|
+
- <whenToUse[n]>
|
|
286
|
+
|
|
287
|
+
**When not to use**
|
|
288
|
+
- <whenNotToUse[n]>
|
|
289
|
+
|
|
290
|
+
**Do**
|
|
291
|
+
- <dos[n]>
|
|
292
|
+
|
|
293
|
+
**Don't**
|
|
294
|
+
- <donts[n]>
|
|
295
|
+
|
|
296
|
+
**Accessibility**
|
|
297
|
+
- <accessibility.keyboard[n]>
|
|
298
|
+
- <accessibility.notes[n]>
|
|
299
|
+
|
|
300
|
+
<!-- tl:doc <fp> -->
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Rules: every line is a record string **verbatim** — no re-wording, no added
|
|
304
|
+
connectives, no sentences that appear nowhere in the record. A block whose
|
|
305
|
+
source array is empty is omitted along with its bold label. The **Accessibility**
|
|
306
|
+
label is omitted only when both `accessibility.keyboard` and `accessibility.notes`
|
|
307
|
+
are empty; when one is empty its bullets are simply absent and the label stays.
|
|
308
|
+
Sections are separated by exactly one blank line, and the fingerprint marker is
|
|
309
|
+
always last.
|
|
310
|
+
- **Doc card body.** Render the card's `Usage` band with the canonical builder
|
|
311
|
+
snippet in `.throughline/references/doc-card-builder.md` (via
|
|
312
|
+
`figma_execute` with an explicit `timeout`, one card per call): fill the
|
|
313
|
+
RECORD/CANONICAL_FP slots, resolve the nine required semantic variables and
|
|
314
|
+
the `Body/Default` text style per that file's call contract, run it, and
|
|
315
|
+
verify the returned summary (`rowsRendered`, `blocksCreated`, `cardWidth`) —
|
|
316
|
+
not a screenshot. The builder creates the `Doc Fingerprint` node itself and
|
|
317
|
+
is the only thing that may build the usage body — never hand-assemble it.
|
|
276
318
|
- Compute `<fp>` as the canonical fingerprint defined in the schema reference
|
|
277
319
|
(sha256 of the projected record without `provenance`, first 16 hex chars).
|
|
278
320
|
|
|
279
321
|
**Update the manifest (fields this skill owns):** set
|
|
280
322
|
`components.meta[<Name>].doc` to `{ path, fingerprint: <fp>, surfaces: {
|
|
281
323
|
figmaDescription: { src: <fp>, render: <hash of the description text> }, docCard: {
|
|
282
|
-
src: <fp>, render: <
|
|
283
|
-
|
|
324
|
+
src: <fp>, render: <summary.renderHash>, renderer: <summary.rendererVersion> } } }`
|
|
325
|
+
— the docCard entry is stamped from the builder's returned summary, never by
|
|
326
|
+
re-reading the card. The code surfaces (`storybookMdx`) are added later by
|
|
327
|
+
`storybook-chromatic-builder`.
|
|
284
328
|
|
|
285
329
|
Run the standard doc-card visual-validation + post-build audit
|
|
286
330
|
(`.throughline/references/figma-component-standards.md`) after enriching
|
|
@@ -27,15 +27,16 @@ system). Wire it to consume `packages/tokens` output so stories render with the
|
|
|
27
27
|
real design tokens (import the generated CSS/theme). Checkpoint: confirm
|
|
28
28
|
Storybook runs and shows the token-themed canvas.
|
|
29
29
|
|
|
30
|
-
Install the documentation scripts alongside the token scripts
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- `"docs:check": "node scripts/docs-check.mjs"`
|
|
30
|
+
Install the documentation scripts alongside the token scripts: copy the five
|
|
31
|
+
files and register the three npm scripts listed under **Documentation scripts —
|
|
32
|
+
install as a set** in `.throughline/scripts/README.md`. That table is
|
|
33
|
+
the single source of truth for what a consuming repo gets; do not restate the
|
|
34
|
+
list here.
|
|
36
35
|
|
|
37
36
|
These are the documentation analog of `tokens:validate`; see
|
|
38
|
-
`.throughline/scripts/README.md`.
|
|
37
|
+
`.throughline/scripts/README.md`. This copy is setup, not a forever-fork:
|
|
38
|
+
`/document-component` re-checks these files' freshness on every run and refreshes
|
|
39
|
+
them from the plugin when it has moved on.
|
|
39
40
|
|
|
40
41
|
**pnpm build-script allowlist (first-run gotcha).** On pnpm workspaces, the
|
|
41
42
|
`@storybook/react-vite` install pulls `esbuild`, whose postinstall is blocked by
|
|
@@ -159,6 +160,43 @@ Configure Chromatic to snapshot everything (do **not** set `onlyChanged`), and
|
|
|
159
160
|
verify a token-only PR re-snapshots all stories — they should flip orange against
|
|
160
161
|
the green baseline.
|
|
161
162
|
|
|
163
|
+
### Usage & cost guardrails
|
|
164
|
+
|
|
165
|
+
The full-snapshot default above is the right call for catching regressions, and it
|
|
166
|
+
is also the **maximum-usage** choice: every story, every run. Chromatic bills per
|
|
167
|
+
snapshot, so name this cost shape to the user when you set Chromatic up, and put the
|
|
168
|
+
guardrails in *before* the first big token PR, not after the bill.
|
|
169
|
+
|
|
170
|
+
What Chromatic actually offers (re-verify the live numbers at
|
|
171
|
+
`chromatic.com/pricing` — they drift):
|
|
172
|
+
|
|
173
|
+
- **Free plan (~5,000 snapshots/month):** testing **auto-pauses** when the ceiling
|
|
174
|
+
is hit. No surprise bill, but visual-regression coverage silently *stops* until
|
|
175
|
+
the monthly reset or an upgrade. For a full-suite design system that ceiling
|
|
176
|
+
arrives fast — treat a *paused* build as a red flag, not a passing one.
|
|
177
|
+
- **Paid plans: no hard spending cap.** Overage snapshots auto-bill at month-end.
|
|
178
|
+
The only native guardrail is **usage alerts** — an email when consumption crosses
|
|
179
|
+
a threshold you set (e.g. 90%).
|
|
180
|
+
|
|
181
|
+
The math, so the user sizes the plan honestly: **snapshots ≈ stories × modes ×
|
|
182
|
+
builds.** One `/sync-figma-tokens` PR re-snapshots the *entire* suite × every mode
|
|
183
|
+
in a single build — e.g. 40 components × 2 modes = 80 snapshots per build, and a
|
|
184
|
+
handful of token PRs plus daily `main` builds clears a free tier in a week.
|
|
185
|
+
|
|
186
|
+
So the guardrails, all of them user-controlled (Chromatic will not cap you):
|
|
187
|
+
|
|
188
|
+
1. **Set usage alerts** at ~80% on a paid plan so the bill cannot sneak up. On the
|
|
189
|
+
free plan, make sure the user knows testing *pauses* at the ceiling.
|
|
190
|
+
2. **Scope the CI trigger.** Run Chromatic on **pull requests and `main` only** —
|
|
191
|
+
never on every branch push — path-filter out docs-only changes, and keep it to
|
|
192
|
+
one Chromatic build per commit (no duplicate runs).
|
|
193
|
+
3. **Size the plan to the math** before the first token PR. A large story count is
|
|
194
|
+
also the *only* reason to revisit TurboSnap (see above), and even then treat
|
|
195
|
+
every token change as a full run.
|
|
196
|
+
|
|
197
|
+
Do not silently pick a plan or leave the trigger wide open. Name the tradeoff and
|
|
198
|
+
let the user choose with the numbers in front of them.
|
|
199
|
+
|
|
162
200
|
## Step 5 — Code Connect (plan-gated, skip gracefully)
|
|
163
201
|
|
|
164
202
|
Code Connect ties Figma components to their code counterparts so Figma's dev
|
|
@@ -234,8 +272,10 @@ the `figma_execute` scripting gotchas — `getNodeByIdAsync` and an explicit
|
|
|
234
272
|
re-render the affected surfaces so `docs:check` stays green.
|
|
235
273
|
- If Figma is connected (per `figma.mechanism`), open the component's doc card and
|
|
236
274
|
update the `Status Label` text to `stable`, re-bind the `Status` chip fill to
|
|
237
|
-
the **success** semantic color variable (mode-aware, not a hardcoded hex),
|
|
238
|
-
|
|
275
|
+
the **success** semantic color variable (mode-aware, not a hardcoded hex), then
|
|
276
|
+
re-run the canonical doc-card builder against the same card to refresh the
|
|
277
|
+
header date from the `record.updatedAt` already set above (it locates the date
|
|
278
|
+
node under either header shape) — then screenshot to confirm the chip
|
|
239
279
|
recolored and the date changed.
|
|
240
280
|
- If Figma isn't connected, still update the manifest and tell the user the card
|
|
241
281
|
will reconcile next Figma session (or offer to reconnect and fix it now).
|
|
@@ -296,6 +336,9 @@ that may not exist.
|
|
|
296
336
|
- Never rely on TurboSnap (`onlyChanged: true`) for a token-driven design system
|
|
297
337
|
— its incremental model keeps missing global token changes. Default to full
|
|
298
338
|
snapshots (every story, every run); revisit only at large story counts.
|
|
339
|
+
- Never leave Chromatic's cost shape unspoken or the CI trigger wide open — there
|
|
340
|
+
is no hard spend cap on paid plans, so set usage alerts, run it on PRs + `main`
|
|
341
|
+
only, and size the plan to stories × modes × builds before the first token PR.
|
|
299
342
|
- Never use the sequential model for story-gen — parallelize via subagents.
|
|
300
343
|
- Never capture the Chromatic baseline *after* a code retrofit — baseline before, so
|
|
301
344
|
intended drift-fixes are distinguishable from regressions.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@radicool/throughline",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Build a complete design system end to end — author in Figma, sync tokens to code, generate Storybook. Usable from Claude Code, Cursor, Codex, or any AGENTS.md agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,14 +12,16 @@ These are **seeds, not gospel** — the user's approval and the actual built
|
|
|
12
12
|
component override them. Sources: W3C ARIA Authoring Practices Guide (roles +
|
|
13
13
|
keyboard), Material 3, Shopify Polaris (content/usage), IBM Carbon (usage).
|
|
14
14
|
|
|
15
|
+
Seeds are clause-style shorthand; the authoring pipeline expands them into full sentences per references/doc-writing-standard.md before they enter a record.
|
|
16
|
+
|
|
15
17
|
## Button
|
|
16
18
|
|
|
17
19
|
- **whenToUse:** trigger an action or event (submit, confirm, open a dialog).
|
|
18
|
-
- **whenNotToUse:** navigation between pages/URLs
|
|
20
|
+
- **whenNotToUse:** navigation between pages/URLs (use a Link).
|
|
19
21
|
- **dos:** lead the label with a verb; keep one primary (highest-emphasis) button
|
|
20
22
|
per view; keep labels short (≤ ~3 words).
|
|
21
|
-
- **donts:** don't use a button for navigation; don't stack multiple
|
|
22
|
-
buttons; don't disable without telling the user why.
|
|
23
|
+
- **donts:** don't use a button for navigation (use a Link); don't stack multiple
|
|
24
|
+
primary buttons (keep one per view); don't disable without telling the user why.
|
|
23
25
|
- **accessibility (w3c-apg):** role `button`; Enter and Space activate; an
|
|
24
26
|
icon-only button needs an `aria-label`; disabled buttons are not focusable.
|
|
25
27
|
|
|
@@ -30,8 +32,8 @@ keyboard), Material 3, Shopify Polaris (content/usage), IBM Carbon (usage).
|
|
|
30
32
|
text (use Textarea).
|
|
31
33
|
- **dos:** always pair with a visible label; show format hints as helper text;
|
|
32
34
|
reserve space for error text to avoid layout shift.
|
|
33
|
-
- **donts:** don't use placeholder text as the only label
|
|
34
|
-
keystroke before first blur.
|
|
35
|
+
- **donts:** don't use placeholder text as the only label (pair with a visible
|
|
36
|
+
label); don't validate on every keystroke before first blur.
|
|
35
37
|
- **accessibility (w3c-apg):** every input has a programmatically associated
|
|
36
38
|
`<label>`; error state sets `aria-invalid` and links the message via
|
|
37
39
|
`aria-describedby`.
|
|
@@ -42,8 +44,8 @@ keyboard), Material 3, Shopify Polaris (content/usage), IBM Carbon (usage).
|
|
|
42
44
|
- **whenNotToUse:** a single either/or action that takes effect immediately with no
|
|
43
45
|
save (prefer a toggle) vs. a form choice (prefer radio/checkbox).
|
|
44
46
|
- **dos:** label the control, not just the group; make the label clickable.
|
|
45
|
-
- **donts:** don't use a radio group for multi-select; don't use
|
|
46
|
-
|
|
47
|
+
- **donts:** don't use a radio group for multi-select (use checkboxes); don't use
|
|
48
|
+
a toggle for choices needing a separate Save (use radio/checkbox).
|
|
47
49
|
- **accessibility (w3c-apg):** roles `checkbox` / `radio` / `switch`; Space
|
|
48
50
|
toggles; radio groups navigate with arrow keys; state exposed via
|
|
49
51
|
`aria-checked`.
|
|
@@ -51,7 +53,8 @@ keyboard), Material 3, Shopify Polaris (content/usage), IBM Carbon (usage).
|
|
|
51
53
|
## Card
|
|
52
54
|
|
|
53
55
|
- **whenToUse:** group related content and actions about a single subject.
|
|
54
|
-
- **whenNotToUse:** primary page layout scaffolding
|
|
56
|
+
- **whenNotToUse:** primary page layout scaffolding (use a layout/grid component); a
|
|
57
|
+
bare list of text (use a List).
|
|
55
58
|
- **dos:** make the primary action obvious; keep one main call-to-action per card.
|
|
56
59
|
- **donts:** don't nest cards more than one level; don't make the whole card AND an
|
|
57
60
|
inner button separately clickable in conflicting ways.
|
|
@@ -71,10 +74,11 @@ keyboard), Material 3, Shopify Polaris (content/usage), IBM Carbon (usage).
|
|
|
71
74
|
## Badge / chip / tag
|
|
72
75
|
|
|
73
76
|
- **whenToUse:** short status, count, or category label (badge); a removable/
|
|
74
|
-
selectable
|
|
77
|
+
selectable item (chip).
|
|
75
78
|
- **whenNotToUse:** interactive primary actions (use a Button).
|
|
76
|
-
- **dos:** keep text to a word or two;
|
|
77
|
-
|
|
79
|
+
- **dos:** keep text to a word or two; match badge color to its semantic meaning
|
|
80
|
+
(success, warning, error).
|
|
81
|
+
- **donts:** don't rely on color alone to convey status (include text or an icon).
|
|
78
82
|
- **accessibility:** a removable chip's remove control needs an accessible name
|
|
79
83
|
(e.g. "Remove <label>"); status conveyed with text, not color only (WCAG 1.4.1).
|
|
80
84
|
|
|
@@ -58,9 +58,17 @@ deterministically. JSON is equally machine-legible for AI consumers.
|
|
|
58
58
|
- **Lifecycle:** `status` (`draft`|`beta`|`stable`|`deprecated`), `updatedAt` (ISO date).
|
|
59
59
|
- **`provenance`** — per-block author source, one of `imported`, `ai-inferred`,
|
|
60
60
|
`best-practice`, `w3c-apg`, `framework`, `user`, or a `+`-joined combination
|
|
61
|
-
(e.g. `best-practice+user`). Regeneration re-infers
|
|
62
|
-
|
|
63
|
-
`imported`.
|
|
61
|
+
(e.g. `best-practice+user`). Regeneration **re-infers** a block whose
|
|
62
|
+
provenance includes `ai-inferred`, `framework`, `best-practice`, or `w3c-apg`,
|
|
63
|
+
and **never overwrites** one whose provenance includes `user` or `imported`.
|
|
64
|
+
Every value is assigned to exactly one of those two tiers: generated content is
|
|
65
|
+
re-inferred, human input (`user`) and pre-existing external content
|
|
66
|
+
(`imported`) are protected. Protection takes precedence: a combination that
|
|
67
|
+
contains both — `best-practice+user`, say — is protected. A block is
|
|
68
|
+
re-inferred only when it carries no `user` or `imported` marker at all. A
|
|
69
|
+
protected block may still be rewritten when the user approves the rewrite at
|
|
70
|
+
the record-approval gate; the result is stamped `imported+user`, which is
|
|
71
|
+
protected from then on and never re-proposed.
|
|
64
72
|
|
|
65
73
|
Deferred to a later version (do not emit in v1): `anatomy`, `content` (writing
|
|
66
74
|
guidelines), `examples`.
|
|
@@ -84,7 +92,7 @@ Figma-connected skill computing the identical hash over the description content.
|
|
|
84
92
|
|---|---|---|---|---|
|
|
85
93
|
| summary, description | ✔ | ✔ | ✔ | ✔ |
|
|
86
94
|
| whenToUse / whenNotToUse | ✔ | ✔ | ✔ | ✔ |
|
|
87
|
-
| variants, states (meanings) |
|
|
95
|
+
| variants, states (meanings) | — | ✔ legend | ✔ argTypes | ✔ |
|
|
88
96
|
| dos / donts | ✔ | ✔ | ✔ | ✔ |
|
|
89
97
|
| accessibility | ✔ | ✔ | ✔ | ✔ |
|
|
90
98
|
| tokensUsed | — | — | ✔ | ✔ |
|
|
@@ -105,7 +113,7 @@ The manifest stores pointers + per-surface fingerprints, never content:
|
|
|
105
113
|
"fingerprint": "<canonical fingerprint at last render>",
|
|
106
114
|
"surfaces": {
|
|
107
115
|
"figmaDescription": { "src": "<fp>", "render": "<hash of description text>" },
|
|
108
|
-
"docCard": { "src": "<fp>", "render": "<hash of card content>" },
|
|
116
|
+
"docCard": { "src": "<fp>", "render": "<hash of card content>", "renderer": "4" },
|
|
109
117
|
"storybookMdx": { "src": "<fp>", "render": "<hash of mdx file>", "file": "packages/ui/src/Button/Button.mdx" }
|
|
110
118
|
}
|
|
111
119
|
}
|
|
@@ -116,6 +124,11 @@ The manifest stores pointers + per-surface fingerprints, never content:
|
|
|
116
124
|
- `render` — a hash of the surface's rendered content at render time (detects
|
|
117
125
|
**edited**, for surfaces the tooling can re-read).
|
|
118
126
|
- `file` — repo-relative path for code surfaces so `docs:check` can re-read them.
|
|
127
|
+
- `renderer` — (docCard only) the layout version of the builder that last
|
|
128
|
+
rendered the card: `DOC_CARD_RENDERER_VERSION` in `scripts/lib/doc-card-plan.mjs`,
|
|
129
|
+
currently `"4"`. Additive and optional — absence means the card predates the
|
|
130
|
+
versioned builder. Stamped from the builder's returned summary, never by
|
|
131
|
+
re-reading the card.
|
|
119
132
|
|
|
120
133
|
## Drift + reconciliation contract
|
|
121
134
|
|
|
@@ -123,6 +136,11 @@ The manifest stores pointers + per-surface fingerprints, never content:
|
|
|
123
136
|
- **canonical-changed** — the `.doc.json` fingerprint ≠ `doc.fingerprint`.
|
|
124
137
|
- **stale** — `surface.src` ≠ current canonical fingerprint.
|
|
125
138
|
- **edited** — a re-readable surface's current content hash ≠ `surface.render`.
|
|
139
|
+
- **layout-upgrade-available** — informational, never failing, docCard only:
|
|
140
|
+
`surfaces.docCard.renderer` is missing or lower than the current
|
|
141
|
+
`DOC_CARD_RENDERER_VERSION`. The card's content is not in drift — its layout
|
|
142
|
+
predates the current builder. Re-render on next touch (no unprompted Figma
|
|
143
|
+
writes; untouched brownfield cards must not generate a standing warning wall).
|
|
126
144
|
- **missing-surface** — a repo surface that declares a `file` which is now gone.
|
|
127
145
|
Failing, and distinct from `edit-unverified`: the surface *was* re-readable and
|
|
128
146
|
its rendered output has been deleted, not merely unreadable this run.
|