@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.
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/adapters/codex/AGENTS.md +29 -0
- package/adapters/codex/codex-mcp.toml +4 -0
- package/adapters/codex/prompts/component-builder.md +272 -0
- package/adapters/codex/prompts/component-pipeline.md +81 -0
- package/adapters/codex/prompts/design-system-audit.md +122 -0
- package/adapters/codex/prompts/design-system-status.md +41 -0
- package/adapters/codex/prompts/figma-environment-setup.md +456 -0
- package/adapters/codex/prompts/icon-system-builder.md +268 -0
- package/adapters/codex/prompts/new-component.md +13 -0
- package/adapters/codex/prompts/repository-builder.md +163 -0
- package/adapters/codex/prompts/retrofit-planner.md +136 -0
- package/adapters/codex/prompts/start.md +22 -0
- package/adapters/codex/prompts/storybook-chromatic-builder.md +261 -0
- package/adapters/codex/prompts/sync-figma-tokens.md +22 -0
- package/adapters/codex/prompts/token-builder.md +361 -0
- package/adapters/codex/prompts/token-crosswalk-builder.md +120 -0
- package/adapters/codex/prompts/token-sheet-builder.md +162 -0
- package/adapters/codex/prompts/token-sync-layer.md +232 -0
- package/adapters/cursor/.cursor/commands/design-system-status.md +41 -0
- package/adapters/cursor/.cursor/commands/new-component.md +13 -0
- package/adapters/cursor/.cursor/commands/start.md +22 -0
- package/adapters/cursor/.cursor/commands/sync-figma-tokens.md +22 -0
- package/adapters/cursor/.cursor/mcp.json +14 -0
- package/adapters/cursor/.cursor/rules/component-builder.mdc +276 -0
- package/adapters/cursor/.cursor/rules/component-pipeline.mdc +85 -0
- package/adapters/cursor/.cursor/rules/design-system-audit.mdc +126 -0
- package/adapters/cursor/.cursor/rules/figma-environment-setup.mdc +460 -0
- package/adapters/cursor/.cursor/rules/icon-system-builder.mdc +272 -0
- package/adapters/cursor/.cursor/rules/repository-builder.mdc +167 -0
- package/adapters/cursor/.cursor/rules/retrofit-planner.mdc +140 -0
- package/adapters/cursor/.cursor/rules/storybook-chromatic-builder.mdc +265 -0
- package/adapters/cursor/.cursor/rules/token-builder.mdc +365 -0
- package/adapters/cursor/.cursor/rules/token-crosswalk-builder.mdc +124 -0
- package/adapters/cursor/.cursor/rules/token-sheet-builder.mdc +166 -0
- package/adapters/cursor/.cursor/rules/token-sync-layer.mdc +236 -0
- package/adapters/generic/AGENTS.md +46 -0
- package/adapters/generic/commands/design-system-status.md +41 -0
- package/adapters/generic/commands/new-component.md +13 -0
- package/adapters/generic/commands/start.md +22 -0
- package/adapters/generic/commands/sync-figma-tokens.md +22 -0
- package/adapters/generic/skills/component-builder/SKILL.md +272 -0
- package/adapters/generic/skills/component-pipeline/SKILL.md +81 -0
- package/adapters/generic/skills/design-system-audit/SKILL.md +122 -0
- package/adapters/generic/skills/figma-environment-setup/SKILL.md +456 -0
- package/adapters/generic/skills/icon-system-builder/SKILL.md +268 -0
- package/adapters/generic/skills/repository-builder/SKILL.md +163 -0
- package/adapters/generic/skills/retrofit-planner/SKILL.md +136 -0
- package/adapters/generic/skills/storybook-chromatic-builder/SKILL.md +261 -0
- package/adapters/generic/skills/token-builder/SKILL.md +361 -0
- package/adapters/generic/skills/token-crosswalk-builder/SKILL.md +120 -0
- package/adapters/generic/skills/token-sheet-builder/SKILL.md +162 -0
- package/adapters/generic/skills/token-sync-layer/SKILL.md +232 -0
- package/package.json +29 -0
- package/references/brainstorm-before-build.md +139 -0
- package/references/brownfield-retrofit.md +93 -0
- package/references/coding-level.md +70 -0
- package/references/crosswalk-schema.md +113 -0
- package/references/figma-component-standards.md +532 -0
- package/references/figma-publishing.md +125 -0
- package/references/figma-scripting.md +278 -0
- package/references/manifest-schema.md +341 -0
- package/references/scaling-up-handoff.md +61 -0
- package/references/sync-adapters.md +141 -0
- package/scripts/README.md +78 -0
- package/scripts/adapters/emit-codex.mjs +58 -0
- package/scripts/adapters/emit-cursor.mjs +26 -0
- package/scripts/adapters/emit-generic.mjs +41 -0
- package/scripts/adapters/generate.mjs +73 -0
- package/scripts/adapters/read-sources.mjs +54 -0
- package/scripts/adapters/translate.mjs +51 -0
- package/scripts/build-reverse-index.mjs +56 -0
- package/scripts/crosswalk.schema.json +33 -0
- package/scripts/grep-color-usage.mjs +143 -0
- package/scripts/guard-token-removal.mjs +95 -0
- package/scripts/install.mjs +143 -0
- package/scripts/lib/crosswalk.mjs +91 -0
- package/scripts/validate-crosswalk.mjs +96 -0
|
@@ -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
|
+
|
|
@@ -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,456 @@
|
|
|
1
|
+
# Figma environment setup
|
|
2
|
+
|
|
3
|
+
This skill does three foundational jobs, in order:
|
|
4
|
+
|
|
5
|
+
1. **Discover where you're working** — find or create the project directory,
|
|
6
|
+
scan what's already there, and set expectations.
|
|
7
|
+
2. **Create the local working folder** and write the `design-system.json`
|
|
8
|
+
manifest into it (if not already present from step 1).
|
|
9
|
+
3. **Connect Codex to Figma** so later skills can read and write the file,
|
|
10
|
+
then verify the connection works.
|
|
11
|
+
|
|
12
|
+
It is the required first step. Every other Figma skill does a cheap liveness
|
|
13
|
+
check and, if it fails, points the user back here.
|
|
14
|
+
|
|
15
|
+
## Who you're talking to
|
|
16
|
+
|
|
17
|
+
Assume the user is design-fluent but may have **never set up a developer tool,
|
|
18
|
+
created an API token, or used a terminal before**. Explain every concept the
|
|
19
|
+
first time it appears, in one plain sentence. Never assume they know what a
|
|
20
|
+
"token", "MCP server", "config file", or "package manager" is. Be warm and
|
|
21
|
+
concrete. When you ask them to do something outside the chat (in Figma, on a
|
|
22
|
+
website), give the exact click path, not a vague instruction.
|
|
23
|
+
|
|
24
|
+
Read `.throughline/references/manifest-schema.md` before writing the manifest so you use the
|
|
25
|
+
correct field names and defaults.
|
|
26
|
+
|
|
27
|
+
## Step 0 — Intake (Locate → Scan → Brief)
|
|
28
|
+
|
|
29
|
+
This step runs before everything else. Establish where you're working, read
|
|
30
|
+
what's already there, and set the user's expectations before taking any action.
|
|
31
|
+
It has three phases in sequence.
|
|
32
|
+
|
|
33
|
+
### Phase 1: Locate
|
|
34
|
+
|
|
35
|
+
Open by surfacing the user's current working directory and presenting three
|
|
36
|
+
explicit options — no assumptions made about where they want to work or whether
|
|
37
|
+
they have started anything already:
|
|
38
|
+
|
|
39
|
+
> "Before we get started, I want to make sure we're working in the right place.
|
|
40
|
+
> You're currently in: `[current working directory path]`
|
|
41
|
+
>
|
|
42
|
+
> Where should we set up?
|
|
43
|
+
> - **Here** — this directory is where the design system should live
|
|
44
|
+
> - **Somewhere else** — I have a project at a different path
|
|
45
|
+
> - **A new folder** — create a fresh folder somewhere"
|
|
46
|
+
|
|
47
|
+
**"Here":** Proceed to the existing manifest check below.
|
|
48
|
+
|
|
49
|
+
**"Somewhere else":** Ask for the path. Expand it to an absolute path (resolve
|
|
50
|
+
`~`, relative segments like `../`, etc.) and verify it exists on disk as a
|
|
51
|
+
directory. If it doesn't exist, ask them to double-check the spelling. Once
|
|
52
|
+
confirmed, proceed to the existing manifest check.
|
|
53
|
+
|
|
54
|
+
**"A new folder":** Ask what they'd like to name it and where it should live
|
|
55
|
+
(suggest the current directory as the default). Create it. Confirm where it was
|
|
56
|
+
created: "I've created `[name]` at `[full path]`." Proceed to the existing
|
|
57
|
+
manifest check.
|
|
58
|
+
|
|
59
|
+
**Existing manifest check:** Before scanning, check whether `design-system.json`
|
|
60
|
+
already exists in the confirmed directory.
|
|
61
|
+
|
|
62
|
+
- **If it exists:** Read it. If `schemaVersion` is out of date, migrate forward
|
|
63
|
+
(add missing fields with defaults, bump `schemaVersion` — do not delete
|
|
64
|
+
unrecognised fields). Tell the user:
|
|
65
|
+
> "Looks like we've worked here before — I'll pick up where we left off."
|
|
66
|
+
Skip Phases 2 and 3. Continue into Step 2 with the existing manifest loaded.
|
|
67
|
+
|
|
68
|
+
- **If it does not exist:** Proceed to Phase 2.
|
|
69
|
+
|
|
70
|
+
### Phase 2: Scan
|
|
71
|
+
|
|
72
|
+
Scan the confirmed directory for the following signals. Check in priority order
|
|
73
|
+
— monorepo status is the most consequential and is checked first.
|
|
74
|
+
|
|
75
|
+
| Signal | What it means |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `turbo.json` **and** `pnpm-workspace.yaml` both present | Already a monorepo |
|
|
78
|
+
| `package.json` present, no `turbo.json` or `pnpm-workspace.yaml` | Repo exists, not yet a monorepo |
|
|
79
|
+
| `.storybook/` directory present | Storybook already installed |
|
|
80
|
+
| `tokens.json` or `tokens/` directory present | Existing token pipeline |
|
|
81
|
+
| `style-dictionary.config.js` or `*.style-dictionary.js` files present | Existing sync layer |
|
|
82
|
+
|
|
83
|
+
After scanning, write a full `design-system.json` using all schema defaults
|
|
84
|
+
from `.throughline/references/manifest-schema.md`, then populate the
|
|
85
|
+
`workspace.origin` and `workspace.detectedLayers` fields with the scan results:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
"workspace": {
|
|
89
|
+
"origin": "<greenfield|existing-repo|existing-monorepo|unknown>",
|
|
90
|
+
"detectedLayers": {
|
|
91
|
+
"monorepo": <true|false>,
|
|
92
|
+
"storybook": <true|false>,
|
|
93
|
+
"tokens": <true|false>,
|
|
94
|
+
"syncLayer": <true|false>
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Setting `origin`:**
|
|
100
|
+
- No `package.json` found → `"greenfield"`
|
|
101
|
+
- `package.json` found, no `turbo.json`/`pnpm-workspace.yaml` → `"existing-repo"`
|
|
102
|
+
- Both `turbo.json` and `pnpm-workspace.yaml` found → `"existing-monorepo"`
|
|
103
|
+
- Signals present but contradictory or incomplete → `"unknown"`
|
|
104
|
+
|
|
105
|
+
**Setting `detectedLayers`:** set each boolean independently from the table
|
|
106
|
+
above. A directory can have `origin: "existing-monorepo"` and
|
|
107
|
+
`detectedLayers.storybook: false` — they are independent fields.
|
|
108
|
+
|
|
109
|
+
**Do not overwrite `workspace.origin` on subsequent runs.** If it is already
|
|
110
|
+
set to a non-null value, skip the scan and proceed to Phase 3.
|
|
111
|
+
|
|
112
|
+
### Phase 3: Brief
|
|
113
|
+
|
|
114
|
+
Produce a short, warm, plain-language situational summary. The goal is to set
|
|
115
|
+
expectations so nothing downstream feels like a surprise. No jargon. No alarm.
|
|
116
|
+
If something requires action before a later skill can run, say so as a
|
|
117
|
+
heads-up, not a warning.
|
|
118
|
+
|
|
119
|
+
**Format:**
|
|
120
|
+
|
|
121
|
+
> "Here's what I found in `[path]`:
|
|
122
|
+
> [plain-language bullet list of detected signals and what they mean]
|
|
123
|
+
>
|
|
124
|
+
> Here's what that means for us:
|
|
125
|
+
> [brief tailored roadmap: what works the same, what will be different, what
|
|
126
|
+
> to know before we hit it]
|
|
127
|
+
>
|
|
128
|
+
> Ready to continue?"
|
|
129
|
+
|
|
130
|
+
**By scenario:**
|
|
131
|
+
|
|
132
|
+
*Greenfield (no signals detected) — condensed, no need for the full format:*
|
|
133
|
+
> "Clean slate — we're building everything fresh. Ready to continue?"
|
|
134
|
+
|
|
135
|
+
*Existing single repo (`origin: "existing-repo"`):*
|
|
136
|
+
> "Here's what I found in `[path]`:
|
|
137
|
+
> - You have an existing repo, but it's not yet set up as a monorepo
|
|
138
|
+
> [any additional detected layers, one bullet each]
|
|
139
|
+
>
|
|
140
|
+
> Here's what that means for us: everything in the Figma phase — tokens,
|
|
141
|
+
> components, variables — works exactly the same. When we get to the code
|
|
142
|
+
> phase, you'll need to convert this repo to a monorepo first. I'll walk you
|
|
143
|
+
> through that step-by-step when we get there — it's a one-time setup.
|
|
144
|
+
> Because you already have a system here, we'll start by **auditing** what exists — measuring your current colors in code and what's in your Figma file — so we right-size the work before changing anything. That's the `design-system-audit` step.
|
|
145
|
+
> [one line per additional detected layer, e.g.: 'Storybook is already installed
|
|
146
|
+
> — we'll build on top of what you have rather than starting fresh.']
|
|
147
|
+
>
|
|
148
|
+
> Ready to continue?"
|
|
149
|
+
|
|
150
|
+
*Existing monorepo (`origin: "existing-monorepo"`):*
|
|
151
|
+
> "Here's what I found in `[path]`:
|
|
152
|
+
> - Your repo is already set up as a monorepo ✓
|
|
153
|
+
> [any additional detected layers, one bullet each]
|
|
154
|
+
>
|
|
155
|
+
> Here's what that means for us: you're already in great shape for the code
|
|
156
|
+
> phase. We'll build the Figma side first, then work inside your existing
|
|
157
|
+
> monorepo structure when we get to code.
|
|
158
|
+
> Because you already have a system here, we'll start by **auditing** what exists — measuring your current colors in code and what's in your Figma file — so we right-size the work before changing anything. That's the `design-system-audit` step.
|
|
159
|
+
> [one line per additional detected layer]
|
|
160
|
+
>
|
|
161
|
+
> Ready to continue?"
|
|
162
|
+
|
|
163
|
+
*Unknown:*
|
|
164
|
+
> "Here's what I found in `[path]`:
|
|
165
|
+
> - I can see some project files but I'm not sure of the full setup
|
|
166
|
+
>
|
|
167
|
+
> Before we continue: do you have an existing git repo here? And is it already
|
|
168
|
+
> set up as a monorepo (does it have a `turbo.json` or `pnpm-workspace.yaml`)?"
|
|
169
|
+
>
|
|
170
|
+
> Wait for the user to clarify, then update `workspace.origin` manually based
|
|
171
|
+
> on their answer before proceeding.
|
|
172
|
+
|
|
173
|
+
Once the user confirms they're ready, proceed to Step 2.
|
|
174
|
+
|
|
175
|
+
## Step 2 — Create the working folder and manifest
|
|
176
|
+
|
|
177
|
+
**When Step 0 already set the directory:** if the user chose "Here" or
|
|
178
|
+
"Somewhere else" in Step 0, or an existing `design-system.json` was loaded,
|
|
179
|
+
the directory already exists and the manifest has been created or loaded. In
|
|
180
|
+
that case, skip folder creation below. The only thing to confirm is that
|
|
181
|
+
`workspace.name` is set — if it is `null` or `"my-design-system"` (the
|
|
182
|
+
placeholder default), ask the user what they'd like to name their design system
|
|
183
|
+
and update the field. Then proceed directly to Step 2.5.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
Ask the user what they'd like to name their design system (suggest something
|
|
188
|
+
like `my-design-system` if they're unsure). Then:
|
|
189
|
+
|
|
190
|
+
- Create a folder with that name in a sensible location (their current directory
|
|
191
|
+
is fine; confirm where it'll live so they can find it later).
|
|
192
|
+
- Write `design-system.json` into it using the schema defaults from
|
|
193
|
+
`.throughline/references/manifest-schema.md`, with:
|
|
194
|
+
- `workspace.name` = their chosen name
|
|
195
|
+
- `workspace.stage` = `"folder"`
|
|
196
|
+
- everything else at defaults
|
|
197
|
+
|
|
198
|
+
Tell them, in plain language, what just happened: "I've made a folder called
|
|
199
|
+
`my-design-system` on your computer, and put a small file called
|
|
200
|
+
`design-system.json` inside it. That file is a checklist of what we've set up —
|
|
201
|
+
you can open it anytime, and later I can read it back to remember where we are.
|
|
202
|
+
Right now everything in it says 'not done yet', which is exactly right."
|
|
203
|
+
|
|
204
|
+
**Do not** set up git or GitHub here. The whole Figma phase works with just this
|
|
205
|
+
folder. Git arrives later, only when there's code to version (the
|
|
206
|
+
repository-builder skill handles that).
|
|
207
|
+
|
|
208
|
+
## Step 2.5 — Calibrate the coding level
|
|
209
|
+
|
|
210
|
+
Establish how much to explain code/git/terminal concepts in the later
|
|
211
|
+
code-touching skills. Read `.throughline/references/coding-level.md` and follow its
|
|
212
|
+
determination method: ask the **concrete anchoring questions** (have you set up
|
|
213
|
+
a GitHub repo before? used a terminal? worked with `.env` files?) rather than
|
|
214
|
+
"are you technical?" — self-assessment is unreliable.
|
|
215
|
+
|
|
216
|
+
Infer `new` / `some` / `comfortable` from the answers, confirm it in plain terms,
|
|
217
|
+
and record it in `user.codingLevel`. When in doubt, choose the lower level.
|
|
218
|
+
|
|
219
|
+
Frame this warmly and without judgment: "A couple quick questions so I explain
|
|
220
|
+
things at the right level for you — no wrong answers, and I can adjust anytime."
|
|
221
|
+
Make clear it changes only how much detail they get, never what they can build.
|
|
222
|
+
|
|
223
|
+
This is set now because it colors every later interaction. The Figma phase
|
|
224
|
+
itself doesn't lean on it much, but the code phase (repo, sync, Storybook) does.
|
|
225
|
+
|
|
226
|
+
## Step 3 — Choose the Figma write mechanism
|
|
227
|
+
|
|
228
|
+
Explain there are two ways to connect Codex to Figma, and recommend the first:
|
|
229
|
+
|
|
230
|
+
- **Figma Console MCP (recommended).** More capable — it can create many
|
|
231
|
+
variables at once efficiently (which saves time and usage), and it can read
|
|
232
|
+
your variables on any Figma plan, including free and Pro. Slightly more setup:
|
|
233
|
+
you'll create one access token and run a small helper plugin inside Figma.
|
|
234
|
+
- **Official Figma plugin (simpler fallback).** Less setup, but more limited —
|
|
235
|
+
some bulk operations are slower, and reading variables through it can be
|
|
236
|
+
restricted on non-Enterprise plans. Fine if the user wants the lightest path.
|
|
237
|
+
|
|
238
|
+
Let the user choose. Record their choice in `figma.mechanism`
|
|
239
|
+
(`"console-mcp"` or `"official-plugin"`). Default to `console-mcp` if they have
|
|
240
|
+
no preference.
|
|
241
|
+
|
|
242
|
+
The MCP server configuration ships **bundled with this plugin** (in the plugin's
|
|
243
|
+
`.mcp.json`), so the user does not hand-edit any config files. The one thing the
|
|
244
|
+
bundle can't contain is their personal access token — that's a per-user secret,
|
|
245
|
+
handled in the next step.
|
|
246
|
+
|
|
247
|
+
## Step 4 — Connect to Figma (Console MCP path)
|
|
248
|
+
|
|
249
|
+
Walk through these one at a time, confirming each before moving on. Never rush
|
|
250
|
+
the user past a step.
|
|
251
|
+
|
|
252
|
+
### 4a. The golden rule: use the Figma **desktop app**, not the browser
|
|
253
|
+
|
|
254
|
+
State this up front and clearly: **the Figma desktop app must be installed,
|
|
255
|
+
open, and signed in, with the file you want to work in open in it.** The
|
|
256
|
+
browser version of Figma causes connection and token errors that are painful to
|
|
257
|
+
debug. If they don't have the desktop app, point them to figma.com/downloads to
|
|
258
|
+
install it first. Desktop app, every time.
|
|
259
|
+
|
|
260
|
+
### 4b. Create a Figma access token
|
|
261
|
+
|
|
262
|
+
A token is like a password that lets Codex talk to Figma on your behalf. Walk
|
|
263
|
+
them through it:
|
|
264
|
+
|
|
265
|
+
1. In a browser, go to figma.com and sign in (same account as the desktop app).
|
|
266
|
+
2. Click your account menu, then Settings.
|
|
267
|
+
3. Open the **Security** tab.
|
|
268
|
+
4. Find **Personal access tokens** and click **Generate new token**.
|
|
269
|
+
5. Give it a name they'll recognize, like `claude-design-system`.
|
|
270
|
+
6. Copy the token immediately — Figma only shows it once. It starts with
|
|
271
|
+
`figd_`.
|
|
272
|
+
|
|
273
|
+
**Secret-handling rule (non-negotiable):** the token value must never pass
|
|
274
|
+
through the chat. Do not ask the user to paste it to you. Instead, tell them
|
|
275
|
+
exactly where it goes (the plugin's MCP configuration expects it in an
|
|
276
|
+
environment variable named `FIGMA_ACCESS_TOKEN`) and have them place it there
|
|
277
|
+
themselves, following the plugin's setup notes. If they're unsure where that is,
|
|
278
|
+
walk them to it, but you never see or handle the token. Reassure them this is
|
|
279
|
+
normal and good — their password-like token stays theirs.
|
|
280
|
+
|
|
281
|
+
### 4c. Run the desktop bridge plugin and pair
|
|
282
|
+
|
|
283
|
+
The Console MCP talks to Figma through a small "bridge" plugin running inside
|
|
284
|
+
the desktop app.
|
|
285
|
+
|
|
286
|
+
1. Import/run the Figma Console MCP **Desktop Bridge** plugin in their open
|
|
287
|
+
Figma file (one-time import; the setup docs for the MCP cover the exact
|
|
288
|
+
import step).
|
|
289
|
+
2. The plugin shows a **pairing code**.
|
|
290
|
+
3. Tell the user to keep the plugin panel open. When they ask you (in chat) to
|
|
291
|
+
connect, you'll initiate the connection and they'll enter/confirm the pairing
|
|
292
|
+
code in the plugin panel to authorize it.
|
|
293
|
+
|
|
294
|
+
Explain the shape of it plainly: "Figma needs to know it's really you allowing
|
|
295
|
+
this. The little plugin window shows a short code; you'll confirm it, and then
|
|
296
|
+
Codex and Figma are linked for this session."
|
|
297
|
+
|
|
298
|
+
### 4d. Restart the MCP client if needed
|
|
299
|
+
|
|
300
|
+
If the config was just added (token placed for the first time), the MCP client
|
|
301
|
+
may need a restart to load it. Tell them how, simply, and confirm they're back.
|
|
302
|
+
|
|
303
|
+
## Step 4 (alt) — Connect to Figma (official plugin path)
|
|
304
|
+
|
|
305
|
+
If the user chose the official plugin, the flow is lighter: install the official
|
|
306
|
+
Figma plugin for Codex per its setup, ensure the desktop app is open with
|
|
307
|
+
the file, and authenticate through the desktop app (again: desktop, not
|
|
308
|
+
browser). The same secret-handling rule applies — any token goes into config by
|
|
309
|
+
the user, never through the chat.
|
|
310
|
+
|
|
311
|
+
## Step 5 — Capture the file key
|
|
312
|
+
|
|
313
|
+
Ask the user for the URL of the Figma file they want to build the design system
|
|
314
|
+
in. Extract the file key from it (the segment after `/file/` or `/design/`) and
|
|
315
|
+
store it in `figma.fileKey`. Explain: "This just tells Codex which of your
|
|
316
|
+
Figma files to work in, so I don't have to ask every time."
|
|
317
|
+
|
|
318
|
+
## Step 6 — Liveness check (prove it actually works)
|
|
319
|
+
|
|
320
|
+
Don't declare success on faith. Run one trivial **read** against Figma to prove
|
|
321
|
+
the connection is live — for example, a low-cost call such as reading the file
|
|
322
|
+
name or a single variable collection. This probe proves *connectivity only*.
|
|
323
|
+
|
|
324
|
+
**Do not report an inventory from this probe (the false-empty read bugs B1/B2).** A cheap or early read
|
|
325
|
+
can come back empty on a fully-populated file (pages not yet loaded, cache/read
|
|
326
|
+
error), and reporting "0 variables" or "no text styles" off the back of it is a
|
|
327
|
+
confidence-destroying first impression. Proving the connection is live is a
|
|
328
|
+
separate concern from inventorying what's in the file — the full per-class
|
|
329
|
+
inventory (with `loadAllPagesAsync` and independent reads for variables, text
|
|
330
|
+
styles, and effect styles) belongs to the `design-system-audit` prompt, which
|
|
331
|
+
applies the read discipline in
|
|
332
|
+
`.throughline/references/brownfield-retrofit.md`. Here, only confirm the
|
|
333
|
+
call succeeded — never announce counts.
|
|
334
|
+
|
|
335
|
+
If the liveness probe succeeds:
|
|
336
|
+
|
|
337
|
+
- Set `figma.connected` = `true` and `figma.lastVerified` to the current
|
|
338
|
+
timestamp.
|
|
339
|
+
- Append `figma-environment-setup` to `completedSkills`.
|
|
340
|
+
- Tell the user warmly that the connection works and what they just unlocked:
|
|
341
|
+
"Codex can now see and edit your Figma file. You're ready to build your first
|
|
342
|
+
tokens whenever you are."
|
|
343
|
+
|
|
344
|
+
If it fails, first figure out **which kind** of failure it is, because the fixes
|
|
345
|
+
are completely different:
|
|
346
|
+
|
|
347
|
+
**A. The MCP server never started.** The Console MCP is downloaded and launched
|
|
348
|
+
on demand by `npx`. If the error text mentions `npx`, `npm`, `EACCES`,
|
|
349
|
+
`permission denied`, `ENOENT`, a cache path like `~/.npm/_cacache`, or a network
|
|
350
|
+
/ registry timeout, the *server process itself* failed to come up — this is an
|
|
351
|
+
environment problem, not a Figma or token problem. Walking the user through
|
|
352
|
+
tokens or pairing here is useless. Diagnose in order:
|
|
353
|
+
|
|
354
|
+
- **npm cache permission error (`EACCES` writing to `~/.npm`).** This is the
|
|
355
|
+
common one. It means some files in the user's npm cache are owned by `root`,
|
|
356
|
+
usually because `npm` was run with `sudo` at some point, so `npx` can't write
|
|
357
|
+
there. Confirm by checking ownership of `~/.npm` (look for files owned by
|
|
358
|
+
`root` rather than the user). The fix is for the **user** to run, in their own
|
|
359
|
+
terminal, the standard npm-recommended command to give the cache back to
|
|
360
|
+
themselves:
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
sudo chown -R $(whoami) ~/.npm
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Explain it plainly: "A past install left a few files in npm's download folder
|
|
367
|
+
locked to the system account, so the Figma helper can't download. This one
|
|
368
|
+
command hands that folder back to you. It'll ask for your Mac password." Never
|
|
369
|
+
run `sudo` for them — surface the command and let them run it. Then retry the
|
|
370
|
+
liveness check.
|
|
371
|
+
- **Network / registry timeout.** Have them check their connection (and any
|
|
372
|
+
VPN/proxy/corporate registry), then retry.
|
|
373
|
+
- **`node`/`npm` not installed.** `npx` needs Node.js. If it's missing entirely,
|
|
374
|
+
point them to install Node (nodejs.org LTS) and retry.
|
|
375
|
+
|
|
376
|
+
**B. The server started but the connection failed.** If there's no launch error
|
|
377
|
+
and the server is clearly running, diagnose gently and in order: Is the desktop
|
|
378
|
+
app open with the file? Was the token placed correctly (have them re-check,
|
|
379
|
+
without showing you the value)? Is the bridge plugin running and paired? Did the
|
|
380
|
+
client need a restart? Walk them back through the relevant sub-step.
|
|
381
|
+
|
|
382
|
+
Do not move on until the liveness check passes.
|
|
383
|
+
|
|
384
|
+
## Step 6.5 — Prove writes work (throwaway)
|
|
385
|
+
|
|
386
|
+
The liveness check above is a *read*. Before handing off, confirm Codex can also
|
|
387
|
+
**write** to the file — but do **not** leave a permanent artifact behind. The
|
|
388
|
+
file's branded **Cover** page is built later, by `token-sheet-builder`, once
|
|
389
|
+
tokens and styles actually exist, so it can be genuinely on-brand instead of a
|
|
390
|
+
neutral placeholder built against nothing.
|
|
391
|
+
|
|
392
|
+
- Create one trivial throwaway node (e.g. a small frame or text node named
|
|
393
|
+
`__throughline write test`) on any page.
|
|
394
|
+
- Confirm it landed with a quick read or `figma_capture_screenshot`.
|
|
395
|
+
- **Delete it.** If both the write and the delete succeed, writes are proven.
|
|
396
|
+
|
|
397
|
+
Leave `figma.coverPageBuilt` = `false` here — that flag is set later, when the
|
|
398
|
+
real Cover page is built. Keep this step quick; it's plumbing, not design.
|
|
399
|
+
|
|
400
|
+
## Step 7 — Hand off
|
|
401
|
+
|
|
402
|
+
Once live, tell the user what comes next without forcing it: "The natural next
|
|
403
|
+
step is building your color, spacing, and type tokens — just say something like
|
|
404
|
+
'let's build my tokens' and I'll take it from there. Or if you'd rather explore
|
|
405
|
+
first, that's fine too." Update the manifest and stop. Don't auto-run the next
|
|
406
|
+
skill.
|
|
407
|
+
|
|
408
|
+
## Step 8 — Brownfield routing + rollback baseline (existing systems)
|
|
409
|
+
|
|
410
|
+
After the liveness check passes, decide where to send the user. Most greenfield runs
|
|
411
|
+
continue to token building. A **brownfield** run — a mature codebase and/or an
|
|
412
|
+
already-populated Figma file — routes into the audit first, and an **in-progress
|
|
413
|
+
retrofit** resumes where it left off. This is the front-door routing the spec calls
|
|
414
|
+
for; apply the read discipline in
|
|
415
|
+
`.throughline/references/brownfield-retrofit.md` to every read here.
|
|
416
|
+
|
|
417
|
+
**Read the manifest and route:**
|
|
418
|
+
|
|
419
|
+
1. **Resume an in-progress retrofit.** If `retrofit.phase` is set and not `"done"`,
|
|
420
|
+
a retrofit is already underway — hand back to **`retrofit-planner`** to resume at
|
|
421
|
+
that phase, rather than starting anything new. Say plainly where it left off
|
|
422
|
+
(e.g. "Looks like we're mid-retrofit at the `sync` phase — want to pick up there?").
|
|
423
|
+
2. **Route a mature system to the audit.** If `workspace.origin` is `"existing-repo"`
|
|
424
|
+
or `"existing-monorepo"` (a mature codebase), recommend **`design-system-audit`**
|
|
425
|
+
as the next step instead of `token-builder`: "You've got an existing system — let's
|
|
426
|
+
audit it first so we right-size the retrofit." The audit also covers a populated
|
|
427
|
+
Figma file via its verified per-class reads.
|
|
428
|
+
3. **Greenfield stays greenfield.** If `workspace.origin` is `"greenfield"`, continue
|
|
429
|
+
the normal path (brainstorm → token-builder). Don't push greenfield users through
|
|
430
|
+
the audit.
|
|
431
|
+
|
|
432
|
+
**Capture a rollback baseline before any mutation (brownfield only).** A retrofit
|
|
433
|
+
changes a file that already has value in it, so before *any* write lands, capture a
|
|
434
|
+
restore point:
|
|
435
|
+
- **Figma version checkpoint** — note the current version (e.g. via
|
|
436
|
+
`figma_get_file_versions`) or have the user name a Figma version so there's a known-good
|
|
437
|
+
point to restore to. The plugin can read versions; it does not auto-create named
|
|
438
|
+
versions, so if none exists, ask the user to add one ("File → Save to version
|
|
439
|
+
history") and record that you did.
|
|
440
|
+
- **Token export** — if the repo already emits tokens, snapshot the current generated
|
|
441
|
+
output (git is the natural baseline once `workspace.stage` is `local-git`+).
|
|
442
|
+
|
|
443
|
+
Do this **before** routing into any skill that writes (the audit only reads, so the
|
|
444
|
+
baseline must be in place before `token-builder`'s refine phase runs). Frame it as
|
|
445
|
+
cheap insurance, not alarm.
|
|
446
|
+
|
|
447
|
+
## What this skill must NOT do
|
|
448
|
+
|
|
449
|
+
- Never set up git or GitHub (wrong phase — that's repository-builder).
|
|
450
|
+
- Never ask for, accept, store, or echo the Figma access token or any secret.
|
|
451
|
+
- Never hand-edit MCP config on the user's behalf in a way that embeds a secret.
|
|
452
|
+
- Never skip the liveness check.
|
|
453
|
+
- Never assume the browser version of Figma will work — always require desktop.
|
|
454
|
+
- Never overwrite `workspace.origin` once it has been set — it is immutable
|
|
455
|
+
after intake.
|
|
456
|
+
|