@radicool/throughline 0.12.0 → 0.13.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/README.md CHANGED
@@ -154,7 +154,7 @@ For the technically curious — how the machine actually runs.
154
154
 
155
155
  **Modes, within Figma's limits.** Light/Dark lives on the semantic collections; brand variants live on the primitive palette. Splitting the two axes across two collections keeps each one under Figma's 4-modes-per-collection cap on the Professional plan while still resolving correctly (`bg/default` → `{gray/50}` → the active brand's gray).
156
156
 
157
- **Model routing.** Setup runs on **Haiku** automatically to keep first-run costs low. Everyday work runs on whatever model your session is set to**Sonnet** is a sensible default. For the heaviest authoring (large token systems, intricate variant matrices), **Opus** gives the best results: `/model opus`, then back to `/model sonnet`. Nothing forces an expensive model on you.
157
+ **Model routing.** ThroughLine routes work by *cognition, not guesswork* — the expensive thinking on the best model, the mechanical doing on a cheap one. Setup runs on **Haiku** automatically to keep first-run costs low. Inside a skill, the deciding a token architecture, a variant matrix, a slot contract — is planned once on the strongest tier, while the long mechanical part placing Figma nodes, transcribing component code, running SVGR — runs on a cheap tier and self-verifies. You get the best model where it matters and a cheap one where it doesn't, without micromanaging it. The recommended mapping is **Haiku → Sonnet → Opus** for the `fast < balanced < deep` tiers, but nothing is hardcoded — the ladder resolves against whatever models your install actually has, and on hosts without subagents skills degrade cleanly to a single model. You can still steer the session yourself (`/model opus` for the heaviest authoring, back to `/model sonnet` after); nothing forces an expensive model on you.
158
158
 
159
159
  ## Who it's for
160
160
 
@@ -88,8 +88,23 @@ of the primitive→semantic token seam:
88
88
  slot the atoms.
89
89
 
90
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).
91
+ Build bottom-up in dependency order.
92
+
93
+ **Execution model — sequential subagents with model routing.** If your host
94
+ supports subagent dispatch, plan the whole set once with one **architect**
95
+ dispatch (deep tier) — it reads existing Figma state and emits a
96
+ transcription-grade spec in stable identifiers — then build **each component**
97
+ with one **figma-executor** dispatch (fast→balanced), strictly sequentially:
98
+ preflight `figma_get_status` and never run two Figma-touching subagents at once
99
+ (the single bridge is concurrency-1). Each executor builds into a `WIP:` frame
100
+ and finalizes by build-verify-then-replace (see
101
+ `.throughline/references/figma-scripting.md`); gate each finished
102
+ component with a **reviewer** visual pass. Route per
103
+ `.throughline/references/agent-routing.md`, and only dispatch a
104
+ component once its slice of the spec is complete enough to transcribe. **Keep the
105
+ human checkpoint between components** — subagents run continuously within a
106
+ component, but you pause for the human between them. If your host has no subagent
107
+ dispatch, build and verify each component inline, sequentially, as before.
93
108
 
94
109
  ## Step 3 — Build each component, bound to tokens/styles
95
110
 
@@ -169,8 +169,16 @@ Execute the library's mechanism:
169
169
  install/run and subset selection.
170
170
  - **Custom SVGs:** batch-import and componentize them.
171
171
 
172
- This is a Figma-authoring step — sequential, with the user in the loop; no
173
- subagents. When scripting the SVG-to-component pass, follow
172
+ **Execution model sequential Figma-lane subagent with model routing.** If your
173
+ host supports subagent dispatch, run the bring-in + componentize pass as a
174
+ **`figma-executor`** dispatch (balanced tier): preflight `figma_get_status`,
175
+ never run two Figma-touching subagents at once (the single bridge is
176
+ concurrency-1), build into a `WIP:` frame and finalize by build-verify-then-
177
+ replace with the read-back audit in Step 3. The subset + naming contract were
178
+ already settled with the user in Step 1, so no separate architect dispatch is
179
+ needed here. Route per `.throughline/references/agent-routing.md`. If
180
+ your host has no subagent dispatch, script the SVG-to-component pass inline,
181
+ sequentially, with the user in the loop. Either way, follow
174
182
  `.throughline/references/figma-scripting.md`.
175
183
 
176
184
  ## Step 3 — Normalize: page, naming, sizing, variants
@@ -67,13 +67,19 @@ Match the deterministic naming so `Button` (Figma) ↔ `Button` (code).
67
67
 
68
68
  ## Step 3 — Generate stories (subagent-driven, parallel)
69
69
 
70
- Story generation is independent and verifiable per component, so use the
71
- **subagent-driven model** (code-gen skills parallelize; this is the opposite of
72
- the sequential Figma-authoring skills): dispatch one subagent per component to
73
- write its stories a story per meaningful variant, controls wired to props,
74
- slot props demonstrated. Each subagent verifies its work (the story builds and
75
- renders). Two-stage review (does it match the component spec; is it quality
76
- code) before combining.
70
+ Story generation is independent and verifiable per component, so it
71
+ parallelizes one worker per component, unlike the concurrency-1 Figma lane.
72
+
73
+ **Execution modelparallel subagents with model routing.** If your host
74
+ supports subagent dispatch, dispatch **one `code-executor` per component** (fast
75
+ tier) to write its stories a story per meaningful variant, controls wired to
76
+ props, slot props demonstrated — each verifying its own work (the story builds
77
+ and renders); then a **`reviewer`** (balanced) two-stage pass (does it match the
78
+ component spec; is it quality code) before combining. Route per
79
+ `.throughline/references/agent-routing.md`, and only dispatch a
80
+ component once its story spec is complete enough to transcribe. If your host has
81
+ no subagent dispatch, generate and verify each component's stories inline
82
+ instead.
77
83
 
78
84
  **Controls must actually drive the component (args-through render).** A `render`
79
85
  that ignores its args silently breaks the Controls panel — the toggle writes to
@@ -51,6 +51,22 @@ and why large `WRAP` grids time out. For a simple verification read, prefer the
51
51
  dedicated `figma_get_variables` tool (it handles dynamic-page correctly and
52
52
  resolves aliases with `resolveAliases: true`) over a hand-written script.
53
53
 
54
+ **Execution model — sequential architect → figma-executor with model routing.**
55
+ If your host supports subagent dispatch, plan the token architecture once with
56
+ one **architect** dispatch (deep tier) — it reads existing Figma state and emits
57
+ a transcription-grade spec in stable identifiers (collection/variable *names*,
58
+ never nodeIds) — then build the variables with **figma-executor** dispatches
59
+ (balanced tier), strictly sequentially: preflight `figma_get_status` and never
60
+ run two Figma-touching subagents at once (the single bridge is concurrency-1).
61
+ Each executor finalizes by build-verify-then-replace with a programmatic
62
+ read-back (`figma_get_variables`, not a screenshot); gate the result with a
63
+ **reviewer** pass. **Keep the human checkpoint between tiers** (the PAUSE in
64
+ Steps 2–4) — subagents run continuously within a tier, but you pause for the
65
+ human between them. Route per
66
+ `.throughline/references/agent-routing.md`; never parallelize Figma
67
+ work. If your host has no subagent dispatch, build and verify each tier inline,
68
+ sequentially, as the steps below describe.
69
+
54
70
  ## Step 1 — Brainstorm the structure (before building anything)
55
71
 
56
72
  Run the protocol in `.throughline/references/brainstorm-before-build.md`. **First establish
@@ -33,6 +33,20 @@ swatch/type grids — exactly the layouts that hit the two worst traps: the
33
33
  single-call `layoutWrap = "WRAP"` timeout on big grids (build manual rows or split
34
34
  across calls instead). Also run the single-bridge-instance preflight before writing.
35
35
 
36
+ **Execution model — sequential architect → figma-executor with model routing.**
37
+ If your host supports subagent dispatch, plan the sheet layout once with one
38
+ **architect** dispatch (deep tier) — a lighter plan than token-builder's, since
39
+ the tokens already exist; it emits a stable-identifier layout spec (which
40
+ collections/sections, how much per-token detail) — then build the page with
41
+ **figma-executor** dispatches (balanced tier), strictly sequentially: preflight
42
+ `figma_get_status`, concurrency-1, `WIP:` frame + build-verify-then-replace with
43
+ a programmatic read-back (spot-check that the swatches resolved to their bound
44
+ variables via `figma_get_variables`, not just a screenshot), gated by a
45
+ **reviewer** visual pass. Route per
46
+ `.throughline/references/agent-routing.md`; never parallelize Figma
47
+ work. If your host has no subagent dispatch, build and verify the page inline,
48
+ sequentially, as the steps below describe.
49
+
36
50
  ## Step 1 — Brainstorm the layout (lightly)
37
51
 
38
52
  Run `.throughline/references/brainstorm-before-build.md`, but keep it light — this is a
@@ -141,7 +155,7 @@ refresh the "Last updated" date instead of creating a second Cover.)
141
155
  ## Step 3 — Checkpoint
142
156
 
143
157
  Show the user the Foundations page and the Cover page. Sequential review (this is
144
- a Figma-authoring skill — no subagents). Iterate on layout/styling if they want
158
+ a Figma-authoring skill). Iterate on layout/styling if they want
145
159
  changes. Then update the manifest: `sheets.built` = `true`, append
146
160
  `token-sheet-builder` to `completedSkills`.
147
161
 
@@ -139,13 +139,18 @@ register the platform, transform group, format, and `outputReferences`
139
139
  flattens). Web adapters emit `:root`/`.dark` (or `[data-theme]`); the shadcn
140
140
  adapter also emits a Tailwind preset.
141
141
 
142
- **Execution model — subagent-driven for multiple platforms.** When more than one
143
- platform is targeted, generating each platform's output is independent and
144
- verifiable, so dispatch **one subagent per adapter**: each produces its
142
+ **Execution model — subagent dispatch with model routing.** Generating each
143
+ platform's output is independent and verifiable. If your host supports subagent
144
+ dispatch, dispatch **one `code-executor` per adapter** each produces its
145
145
  platform's files and verifies them (the config builds, the expected files
146
- appear, references resolve correctly for web / flatten for native). Review each
147
- before combining. For a single platform, run inline. (See the selective-
148
- subagent decision: code-gen skills parallelize; Figma-authoring skills don't.)
146
+ appear, references resolve for web / flatten for native) then a **`reviewer`**
147
+ to check each before combining. Choose each subagent's model from its role tier
148
+ per `.throughline/references/agent-routing.md` (`code-executor` fast,
149
+ `reviewer` → balanced), and only dispatch once each adapter's spec is complete
150
+ enough to transcribe. If your host has no subagent dispatch, generate and verify
151
+ each adapter inline instead. For a single platform, run inline either way. This
152
+ is a code-gen stage, so these subagents may run in parallel — unlike Figma
153
+ authoring, which is always sequential.
149
154
 
150
155
  ## Step 4 — Build and place outputs
151
156
 
@@ -169,7 +174,9 @@ icons (`icons.built` true):
169
174
  - **Custom icons** — these the repo owns, so generate them: export the custom
170
175
  SVGs from Figma, optimize, and componentize via SVGR into `packages/ui` (or a
171
176
  dedicated icons package). This is real code generation and rides the same
172
- PR-review and subagent model as token output.
177
+ **`code-executor` (fast) + `reviewer` (balanced)** routing and PR-review as
178
+ token output (SVGR transforms are the textbook mechanical op the fast tier is
179
+ for) — see the Step 4 execution model.
173
180
 
174
181
  ## Step 5 — Full regeneration + rename detection (the safety net)
175
182
 
@@ -92,8 +92,23 @@ of the primitive→semantic token seam:
92
92
  slot the atoms.
93
93
 
94
94
  This guarantees a composite's typed slot points at a real, already-built target.
95
- Build bottom-up; checkpoint after each component (sequential — this is Figma
96
- authoring, no subagents).
95
+ Build bottom-up in dependency order.
96
+
97
+ **Execution model — sequential subagents with model routing.** If your host
98
+ supports subagent dispatch, plan the whole set once with one **architect**
99
+ dispatch (deep tier) — it reads existing Figma state and emits a
100
+ transcription-grade spec in stable identifiers — then build **each component**
101
+ with one **figma-executor** dispatch (fast→balanced), strictly sequentially:
102
+ preflight `figma_get_status` and never run two Figma-touching subagents at once
103
+ (the single bridge is concurrency-1). Each executor builds into a `WIP:` frame
104
+ and finalizes by build-verify-then-replace (see
105
+ `.throughline/references/figma-scripting.md`); gate each finished
106
+ component with a **reviewer** visual pass. Route per
107
+ `.throughline/references/agent-routing.md`, and only dispatch a
108
+ component once its slice of the spec is complete enough to transcribe. **Keep the
109
+ human checkpoint between components** — subagents run continuously within a
110
+ component, but you pause for the human between them. If your host has no subagent
111
+ dispatch, build and verify each component inline, sequentially, as before.
97
112
 
98
113
  ## Step 3 — Build each component, bound to tokens/styles
99
114
 
@@ -173,8 +173,16 @@ Execute the library's mechanism:
173
173
  install/run and subset selection.
174
174
  - **Custom SVGs:** batch-import and componentize them.
175
175
 
176
- This is a Figma-authoring step — sequential, with the user in the loop; no
177
- subagents. When scripting the SVG-to-component pass, follow
176
+ **Execution model sequential Figma-lane subagent with model routing.** If your
177
+ host supports subagent dispatch, run the bring-in + componentize pass as a
178
+ **`figma-executor`** dispatch (balanced tier): preflight `figma_get_status`,
179
+ never run two Figma-touching subagents at once (the single bridge is
180
+ concurrency-1), build into a `WIP:` frame and finalize by build-verify-then-
181
+ replace with the read-back audit in Step 3. The subset + naming contract were
182
+ already settled with the user in Step 1, so no separate architect dispatch is
183
+ needed here. Route per `.throughline/references/agent-routing.md`. If
184
+ your host has no subagent dispatch, script the SVG-to-component pass inline,
185
+ sequentially, with the user in the loop. Either way, follow
178
186
  `.throughline/references/figma-scripting.md`.
179
187
 
180
188
  ## Step 3 — Normalize: page, naming, sizing, variants
@@ -71,13 +71,19 @@ Match the deterministic naming so `Button` (Figma) ↔ `Button` (code).
71
71
 
72
72
  ## Step 3 — Generate stories (subagent-driven, parallel)
73
73
 
74
- Story generation is independent and verifiable per component, so use the
75
- **subagent-driven model** (code-gen skills parallelize; this is the opposite of
76
- the sequential Figma-authoring skills): dispatch one subagent per component to
77
- write its stories a story per meaningful variant, controls wired to props,
78
- slot props demonstrated. Each subagent verifies its work (the story builds and
79
- renders). Two-stage review (does it match the component spec; is it quality
80
- code) before combining.
74
+ Story generation is independent and verifiable per component, so it
75
+ parallelizes one worker per component, unlike the concurrency-1 Figma lane.
76
+
77
+ **Execution modelparallel subagents with model routing.** If your host
78
+ supports subagent dispatch, dispatch **one `code-executor` per component** (fast
79
+ tier) to write its stories a story per meaningful variant, controls wired to
80
+ props, slot props demonstrated — each verifying its own work (the story builds
81
+ and renders); then a **`reviewer`** (balanced) two-stage pass (does it match the
82
+ component spec; is it quality code) before combining. Route per
83
+ `.throughline/references/agent-routing.md`, and only dispatch a
84
+ component once its story spec is complete enough to transcribe. If your host has
85
+ no subagent dispatch, generate and verify each component's stories inline
86
+ instead.
81
87
 
82
88
  **Controls must actually drive the component (args-through render).** A `render`
83
89
  that ignores its args silently breaks the Controls panel — the toggle writes to
@@ -55,6 +55,22 @@ and why large `WRAP` grids time out. For a simple verification read, prefer the
55
55
  dedicated `figma_get_variables` tool (it handles dynamic-page correctly and
56
56
  resolves aliases with `resolveAliases: true`) over a hand-written script.
57
57
 
58
+ **Execution model — sequential architect → figma-executor with model routing.**
59
+ If your host supports subagent dispatch, plan the token architecture once with
60
+ one **architect** dispatch (deep tier) — it reads existing Figma state and emits
61
+ a transcription-grade spec in stable identifiers (collection/variable *names*,
62
+ never nodeIds) — then build the variables with **figma-executor** dispatches
63
+ (balanced tier), strictly sequentially: preflight `figma_get_status` and never
64
+ run two Figma-touching subagents at once (the single bridge is concurrency-1).
65
+ Each executor finalizes by build-verify-then-replace with a programmatic
66
+ read-back (`figma_get_variables`, not a screenshot); gate the result with a
67
+ **reviewer** pass. **Keep the human checkpoint between tiers** (the PAUSE in
68
+ Steps 2–4) — subagents run continuously within a tier, but you pause for the
69
+ human between them. Route per
70
+ `.throughline/references/agent-routing.md`; never parallelize Figma
71
+ work. If your host has no subagent dispatch, build and verify each tier inline,
72
+ sequentially, as the steps below describe.
73
+
58
74
  ## Step 1 — Brainstorm the structure (before building anything)
59
75
 
60
76
  Run the protocol in `.throughline/references/brainstorm-before-build.md`. **First establish
@@ -37,6 +37,20 @@ swatch/type grids — exactly the layouts that hit the two worst traps: the
37
37
  single-call `layoutWrap = "WRAP"` timeout on big grids (build manual rows or split
38
38
  across calls instead). Also run the single-bridge-instance preflight before writing.
39
39
 
40
+ **Execution model — sequential architect → figma-executor with model routing.**
41
+ If your host supports subagent dispatch, plan the sheet layout once with one
42
+ **architect** dispatch (deep tier) — a lighter plan than token-builder's, since
43
+ the tokens already exist; it emits a stable-identifier layout spec (which
44
+ collections/sections, how much per-token detail) — then build the page with
45
+ **figma-executor** dispatches (balanced tier), strictly sequentially: preflight
46
+ `figma_get_status`, concurrency-1, `WIP:` frame + build-verify-then-replace with
47
+ a programmatic read-back (spot-check that the swatches resolved to their bound
48
+ variables via `figma_get_variables`, not just a screenshot), gated by a
49
+ **reviewer** visual pass. Route per
50
+ `.throughline/references/agent-routing.md`; never parallelize Figma
51
+ work. If your host has no subagent dispatch, build and verify the page inline,
52
+ sequentially, as the steps below describe.
53
+
40
54
  ## Step 1 — Brainstorm the layout (lightly)
41
55
 
42
56
  Run `.throughline/references/brainstorm-before-build.md`, but keep it light — this is a
@@ -145,7 +159,7 @@ refresh the "Last updated" date instead of creating a second Cover.)
145
159
  ## Step 3 — Checkpoint
146
160
 
147
161
  Show the user the Foundations page and the Cover page. Sequential review (this is
148
- a Figma-authoring skill — no subagents). Iterate on layout/styling if they want
162
+ a Figma-authoring skill). Iterate on layout/styling if they want
149
163
  changes. Then update the manifest: `sheets.built` = `true`, append
150
164
  `token-sheet-builder` to `completedSkills`.
151
165
 
@@ -143,13 +143,18 @@ register the platform, transform group, format, and `outputReferences`
143
143
  flattens). Web adapters emit `:root`/`.dark` (or `[data-theme]`); the shadcn
144
144
  adapter also emits a Tailwind preset.
145
145
 
146
- **Execution model — subagent-driven for multiple platforms.** When more than one
147
- platform is targeted, generating each platform's output is independent and
148
- verifiable, so dispatch **one subagent per adapter**: each produces its
146
+ **Execution model — subagent dispatch with model routing.** Generating each
147
+ platform's output is independent and verifiable. If your host supports subagent
148
+ dispatch, dispatch **one `code-executor` per adapter** each produces its
149
149
  platform's files and verifies them (the config builds, the expected files
150
- appear, references resolve correctly for web / flatten for native). Review each
151
- before combining. For a single platform, run inline. (See the selective-
152
- subagent decision: code-gen skills parallelize; Figma-authoring skills don't.)
150
+ appear, references resolve for web / flatten for native) then a **`reviewer`**
151
+ to check each before combining. Choose each subagent's model from its role tier
152
+ per `.throughline/references/agent-routing.md` (`code-executor` fast,
153
+ `reviewer` → balanced), and only dispatch once each adapter's spec is complete
154
+ enough to transcribe. If your host has no subagent dispatch, generate and verify
155
+ each adapter inline instead. For a single platform, run inline either way. This
156
+ is a code-gen stage, so these subagents may run in parallel — unlike Figma
157
+ authoring, which is always sequential.
153
158
 
154
159
  ## Step 4 — Build and place outputs
155
160
 
@@ -173,7 +178,9 @@ icons (`icons.built` true):
173
178
  - **Custom icons** — these the repo owns, so generate them: export the custom
174
179
  SVGs from Figma, optimize, and componentize via SVGR into `packages/ui` (or a
175
180
  dedicated icons package). This is real code generation and rides the same
176
- PR-review and subagent model as token output.
181
+ **`code-executor` (fast) + `reviewer` (balanced)** routing and PR-review as
182
+ token output (SVGR transforms are the textbook mechanical op the fast tier is
183
+ for) — see the Step 4 execution model.
177
184
 
178
185
  ## Step 5 — Full regeneration + rename detection (the safety net)
179
186
 
@@ -88,8 +88,23 @@ of the primitive→semantic token seam:
88
88
  slot the atoms.
89
89
 
90
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).
91
+ Build bottom-up in dependency order.
92
+
93
+ **Execution model — sequential subagents with model routing.** If your host
94
+ supports subagent dispatch, plan the whole set once with one **architect**
95
+ dispatch (deep tier) — it reads existing Figma state and emits a
96
+ transcription-grade spec in stable identifiers — then build **each component**
97
+ with one **figma-executor** dispatch (fast→balanced), strictly sequentially:
98
+ preflight `figma_get_status` and never run two Figma-touching subagents at once
99
+ (the single bridge is concurrency-1). Each executor builds into a `WIP:` frame
100
+ and finalizes by build-verify-then-replace (see
101
+ `.throughline/references/figma-scripting.md`); gate each finished
102
+ component with a **reviewer** visual pass. Route per
103
+ `.throughline/references/agent-routing.md`, and only dispatch a
104
+ component once its slice of the spec is complete enough to transcribe. **Keep the
105
+ human checkpoint between components** — subagents run continuously within a
106
+ component, but you pause for the human between them. If your host has no subagent
107
+ dispatch, build and verify each component inline, sequentially, as before.
93
108
 
94
109
  ## Step 3 — Build each component, bound to tokens/styles
95
110
 
@@ -169,8 +169,16 @@ Execute the library's mechanism:
169
169
  install/run and subset selection.
170
170
  - **Custom SVGs:** batch-import and componentize them.
171
171
 
172
- This is a Figma-authoring step — sequential, with the user in the loop; no
173
- subagents. When scripting the SVG-to-component pass, follow
172
+ **Execution model sequential Figma-lane subagent with model routing.** If your
173
+ host supports subagent dispatch, run the bring-in + componentize pass as a
174
+ **`figma-executor`** dispatch (balanced tier): preflight `figma_get_status`,
175
+ never run two Figma-touching subagents at once (the single bridge is
176
+ concurrency-1), build into a `WIP:` frame and finalize by build-verify-then-
177
+ replace with the read-back audit in Step 3. The subset + naming contract were
178
+ already settled with the user in Step 1, so no separate architect dispatch is
179
+ needed here. Route per `.throughline/references/agent-routing.md`. If
180
+ your host has no subagent dispatch, script the SVG-to-component pass inline,
181
+ sequentially, with the user in the loop. Either way, follow
174
182
  `.throughline/references/figma-scripting.md`.
175
183
 
176
184
  ## Step 3 — Normalize: page, naming, sizing, variants
@@ -67,13 +67,19 @@ Match the deterministic naming so `Button` (Figma) ↔ `Button` (code).
67
67
 
68
68
  ## Step 3 — Generate stories (subagent-driven, parallel)
69
69
 
70
- Story generation is independent and verifiable per component, so use the
71
- **subagent-driven model** (code-gen skills parallelize; this is the opposite of
72
- the sequential Figma-authoring skills): dispatch one subagent per component to
73
- write its stories a story per meaningful variant, controls wired to props,
74
- slot props demonstrated. Each subagent verifies its work (the story builds and
75
- renders). Two-stage review (does it match the component spec; is it quality
76
- code) before combining.
70
+ Story generation is independent and verifiable per component, so it
71
+ parallelizes one worker per component, unlike the concurrency-1 Figma lane.
72
+
73
+ **Execution modelparallel subagents with model routing.** If your host
74
+ supports subagent dispatch, dispatch **one `code-executor` per component** (fast
75
+ tier) to write its stories a story per meaningful variant, controls wired to
76
+ props, slot props demonstrated — each verifying its own work (the story builds
77
+ and renders); then a **`reviewer`** (balanced) two-stage pass (does it match the
78
+ component spec; is it quality code) before combining. Route per
79
+ `.throughline/references/agent-routing.md`, and only dispatch a
80
+ component once its story spec is complete enough to transcribe. If your host has
81
+ no subagent dispatch, generate and verify each component's stories inline
82
+ instead.
77
83
 
78
84
  **Controls must actually drive the component (args-through render).** A `render`
79
85
  that ignores its args silently breaks the Controls panel — the toggle writes to
@@ -51,6 +51,22 @@ and why large `WRAP` grids time out. For a simple verification read, prefer the
51
51
  dedicated `figma_get_variables` tool (it handles dynamic-page correctly and
52
52
  resolves aliases with `resolveAliases: true`) over a hand-written script.
53
53
 
54
+ **Execution model — sequential architect → figma-executor with model routing.**
55
+ If your host supports subagent dispatch, plan the token architecture once with
56
+ one **architect** dispatch (deep tier) — it reads existing Figma state and emits
57
+ a transcription-grade spec in stable identifiers (collection/variable *names*,
58
+ never nodeIds) — then build the variables with **figma-executor** dispatches
59
+ (balanced tier), strictly sequentially: preflight `figma_get_status` and never
60
+ run two Figma-touching subagents at once (the single bridge is concurrency-1).
61
+ Each executor finalizes by build-verify-then-replace with a programmatic
62
+ read-back (`figma_get_variables`, not a screenshot); gate the result with a
63
+ **reviewer** pass. **Keep the human checkpoint between tiers** (the PAUSE in
64
+ Steps 2–4) — subagents run continuously within a tier, but you pause for the
65
+ human between them. Route per
66
+ `.throughline/references/agent-routing.md`; never parallelize Figma
67
+ work. If your host has no subagent dispatch, build and verify each tier inline,
68
+ sequentially, as the steps below describe.
69
+
54
70
  ## Step 1 — Brainstorm the structure (before building anything)
55
71
 
56
72
  Run the protocol in `.throughline/references/brainstorm-before-build.md`. **First establish
@@ -33,6 +33,20 @@ swatch/type grids — exactly the layouts that hit the two worst traps: the
33
33
  single-call `layoutWrap = "WRAP"` timeout on big grids (build manual rows or split
34
34
  across calls instead). Also run the single-bridge-instance preflight before writing.
35
35
 
36
+ **Execution model — sequential architect → figma-executor with model routing.**
37
+ If your host supports subagent dispatch, plan the sheet layout once with one
38
+ **architect** dispatch (deep tier) — a lighter plan than token-builder's, since
39
+ the tokens already exist; it emits a stable-identifier layout spec (which
40
+ collections/sections, how much per-token detail) — then build the page with
41
+ **figma-executor** dispatches (balanced tier), strictly sequentially: preflight
42
+ `figma_get_status`, concurrency-1, `WIP:` frame + build-verify-then-replace with
43
+ a programmatic read-back (spot-check that the swatches resolved to their bound
44
+ variables via `figma_get_variables`, not just a screenshot), gated by a
45
+ **reviewer** visual pass. Route per
46
+ `.throughline/references/agent-routing.md`; never parallelize Figma
47
+ work. If your host has no subagent dispatch, build and verify the page inline,
48
+ sequentially, as the steps below describe.
49
+
36
50
  ## Step 1 — Brainstorm the layout (lightly)
37
51
 
38
52
  Run `.throughline/references/brainstorm-before-build.md`, but keep it light — this is a
@@ -141,7 +155,7 @@ refresh the "Last updated" date instead of creating a second Cover.)
141
155
  ## Step 3 — Checkpoint
142
156
 
143
157
  Show the user the Foundations page and the Cover page. Sequential review (this is
144
- a Figma-authoring skill — no subagents). Iterate on layout/styling if they want
158
+ a Figma-authoring skill). Iterate on layout/styling if they want
145
159
  changes. Then update the manifest: `sheets.built` = `true`, append
146
160
  `token-sheet-builder` to `completedSkills`.
147
161
 
@@ -139,13 +139,18 @@ register the platform, transform group, format, and `outputReferences`
139
139
  flattens). Web adapters emit `:root`/`.dark` (or `[data-theme]`); the shadcn
140
140
  adapter also emits a Tailwind preset.
141
141
 
142
- **Execution model — subagent-driven for multiple platforms.** When more than one
143
- platform is targeted, generating each platform's output is independent and
144
- verifiable, so dispatch **one subagent per adapter**: each produces its
142
+ **Execution model — subagent dispatch with model routing.** Generating each
143
+ platform's output is independent and verifiable. If your host supports subagent
144
+ dispatch, dispatch **one `code-executor` per adapter** each produces its
145
145
  platform's files and verifies them (the config builds, the expected files
146
- appear, references resolve correctly for web / flatten for native). Review each
147
- before combining. For a single platform, run inline. (See the selective-
148
- subagent decision: code-gen skills parallelize; Figma-authoring skills don't.)
146
+ appear, references resolve for web / flatten for native) then a **`reviewer`**
147
+ to check each before combining. Choose each subagent's model from its role tier
148
+ per `.throughline/references/agent-routing.md` (`code-executor` fast,
149
+ `reviewer` → balanced), and only dispatch once each adapter's spec is complete
150
+ enough to transcribe. If your host has no subagent dispatch, generate and verify
151
+ each adapter inline instead. For a single platform, run inline either way. This
152
+ is a code-gen stage, so these subagents may run in parallel — unlike Figma
153
+ authoring, which is always sequential.
149
154
 
150
155
  ## Step 4 — Build and place outputs
151
156
 
@@ -169,7 +174,9 @@ icons (`icons.built` true):
169
174
  - **Custom icons** — these the repo owns, so generate them: export the custom
170
175
  SVGs from Figma, optimize, and componentize via SVGR into `packages/ui` (or a
171
176
  dedicated icons package). This is real code generation and rides the same
172
- PR-review and subagent model as token output.
177
+ **`code-executor` (fast) + `reviewer` (balanced)** routing and PR-review as
178
+ token output (SVGR transforms are the textbook mechanical op the fast tier is
179
+ for) — see the Step 4 execution model.
173
180
 
174
181
  ## Step 5 — Full regeneration + rename detection (the safety net)
175
182
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radicool/throughline",
3
- "version": "0.12.0",
3
+ "version": "0.13.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": {
@@ -0,0 +1,70 @@
1
+ # Agent routing — choosing a model per subagent
2
+
3
+ **Claude-only.** This reference governs subagent dispatch, a Claude Code
4
+ capability. Hosts without subagent dispatch (Codex, generic AGENTS.md) run the
5
+ work inline on their single model and ignore this file.
6
+
7
+ ## Why route
8
+
9
+ Do the *thinking* on the best model and the *doing* on a cheap one. Deciding a
10
+ component's variant matrix, token architecture, or adapter strategy is reasoning
11
+ — it earns the best model. Running the resulting spec — transcribing code,
12
+ placing Figma nodes, emitting adapter output — is mechanical, and a cheap model
13
+ does it well **once the plan is complete**.
14
+
15
+ ## The tier ladder
16
+
17
+ Relative, never a hardcoded model name — installers have different plans, so we
18
+ name a *capability tier* and resolve it against the models actually available.
19
+
20
+ - `fast` — cheapest/fastest tier. Transcription-grade work from a complete spec.
21
+ - `balanced` — mid tier. Judgment, integration, review scaled to risk.
22
+ - `deep` — most capable tier available. Planning, architecture, hard reasoning.
23
+
24
+ ### Recommended mapping (Anthropic)
25
+
26
+ | Tier | Recommended model |
27
+ |---|---|
28
+ | `fast` | Haiku |
29
+ | `balanced` | Sonnet |
30
+ | `deep` | Opus (or the most capable model you have) |
31
+
32
+ **Override in one place:** edit this table for your plan. Everything downstream
33
+ reads tiers, not model names.
34
+
35
+ ### Resolution + fallback
36
+
37
+ At dispatch, resolve the role's tier to a concrete model **from the models you
38
+ actually have**, then pass it explicitly (an omitted model inherits the session
39
+ model — often the most expensive — which defeats routing). If a tier's model is
40
+ unavailable, **collapse to the nearest lower tier you have**; `deep` always maps
41
+ to the most capable model available. An installer with only one model degrades
42
+ to that model everywhere — routing becomes a no-op, never a failure.
43
+
44
+ ## Roles → tiers
45
+
46
+ | Agent | Tier | Concurrency | Role |
47
+ |---|---|---|---|
48
+ | `code-executor` | `fast` | parallel-safe | Transcribe code/adapter output from a complete spec; verify its own build. |
49
+ | `reviewer` | `balanced` (scale to risk) | parallel-safe | Spec-compliance + quality gate; code-diff or Figma-visual mode. |
50
+ | `architect` | `deep` | 1 | Plan a stage; read Figma read-only; emit a transcription-grade spec in stable identifiers (names, never nodeIds). |
51
+ | `figma-executor` | `fast`→`balanced` (default **`balanced`** for a real component build; `fast` only for trivial mechanical ops) | **1 (bridge-locked)** | Resolve names→nodeIds at run time; build into a `WIP:` frame; verify via `COMPONENT_SET` read-back (not screenshot-only); finalize by build-verify-then-replace and reap `WIP:` debris. |
52
+
53
+ ## The spec-completeness gate
54
+
55
+ Dispatch an executor on `fast` **only when the spec is transcription-grade** —
56
+ complete enough that execution is copying, not deciding. Turn count beats token
57
+ price: a cheap model on a vague task takes 2–3× the turns and costs more. If the
58
+ spec is incomplete, run the work inline on the stronger model instead.
59
+
60
+ ## Escalation
61
+
62
+ A `BLOCKED` executor is re-dispatched **one tier up**, never the same model
63
+ unchanged. If still blocked at `deep`, escalate to the human.
64
+
65
+ ## Concurrency
66
+
67
+ Code-gen roles are parallel-safe. Figma work is **not**: the figma-console
68
+ bridge is a single live connection with global selection/current-page state, so
69
+ the entire Figma surface is concurrency-1. Route Figma work through
70
+ sequential subagents — model routing yes, parallelism never.
@@ -227,6 +227,30 @@ variant explosion), so **prefer them for composite components**.
227
227
  plain instance-swap property instead — slots are for freeform/repeating areas.)
228
228
  - **Single icon** (button leading icon) → instance-swap property, not a slot.
229
229
 
230
+ ### Rule: icons match the component's text color
231
+
232
+ **A leading or trailing icon inside a text-bearing component ALWAYS takes the
233
+ same color token as that component's adjacent text/label — in every variant,
234
+ tone, and state.** Bind the icon to the *same* variable the label uses (e.g. a
235
+ badge icon and its label both bind the tone's `fg`; a primary button's icon and
236
+ label both bind `text/onEmphasis`). This is what prevents the mismatch failures:
237
+ a white-text/black-icon control, an icon that stays one fixed color while the
238
+ text changes per tone, or an icon that ignores the theme.
239
+
240
+ Apply the color on the channel the icon actually draws with, and only that
241
+ channel:
242
+
243
+ - **Line / outline icons** (Lucide, Material Symbols outlined — most sets here)
244
+ draw with a **stroke and no fill.** Bind the color on the vectors' **stroke**
245
+ and leave the **fill empty.** Never bind a line icon's fill — a filled
246
+ outline path renders as a solid blob.
247
+ - **Solid / filled glyphs** draw with a **fill.** Bind the color on the fill;
248
+ they have no meaningful stroke.
249
+
250
+ Never hardcode an icon color, and never leave a fixed dark (or light) icon color
251
+ across tones/states. Bind the override on the icon **instance's** vectors — never
252
+ edit the shared `icon/*` source component, which would recolor every other usage.
253
+
230
254
  **Practical rules (from Figma's constraints):**
231
255
  - **Auto layout must be clean first.** Slots depend on a correct auto layout
232
256
  setup — a messy one makes everything shift. This is why auto-layout-on-
@@ -38,6 +38,37 @@ This is the bridge-side application of the read-discipline principle (B4) in
38
38
  `${CLAUDE_PLUGIN_ROOT}/references/brownfield-retrofit.md`: don't assert "another
39
39
  instance is active" without confirming it's actually live.
40
40
 
41
+ ## Preflight: confirm the *active* file is your target (writes hit the active file)
42
+
43
+ A connected bridge is **not** the same as the *right* file. `figma_execute` (and
44
+ every write) targets whichever file is currently **active** in Figma Desktop — it
45
+ takes no `fileUrl`/`fileKey` argument. So a green `figma_get_status` only proves a
46
+ bridge exists; the active file can silently drift to a different open file between
47
+ your preflight and your write (a user tabbing to another file, a `figma_navigate`
48
+ from an earlier step, a plugin reload). Writing then lands in the wrong file —
49
+ best case it errors with "collection/node not found"; worse case it mutates the
50
+ wrong document.
51
+
52
+ **So the preflight must assert the active file's *identity*, not just connection:**
53
+
54
+ 1. **Know your target `fileKey`** before writing (the one your architect read, or
55
+ the one the workflow is scoped to).
56
+ 2. **Read the active file and compare.** `figma_get_status` reports
57
+ `currentFileKey` / `currentFileName`; `figma_list_open_files` shows every
58
+ connected file and which is active. Confirm the active `fileKey` equals your
59
+ target before the first write **and** re-confirm after any step that could have
60
+ switched it.
61
+ 3. **If it drifted, navigate — don't just retry.** `figma_navigate` to the target
62
+ file URL, then re-read status to confirm the switch took, then write. A bare
63
+ re-run without navigating will hit the wrong file again.
64
+
65
+ This is the file-level analogue of the live-instance discipline above: the
66
+ instance preflight guards against *two* live bridges; this guards against the *one*
67
+ live bridge pointing at the *wrong file*. (Observed live: a status probe reported
68
+ the intended file connected, but by write time the active file had drifted to a
69
+ different open document, and the build failed with "collection not found" until a
70
+ `figma_navigate` corrected it.)
71
+
41
72
  ## Read discipline: never report "empty" without a verified read (B1/B2)
42
73
 
43
74
  Before reporting that a file has no variables, no text styles, or no effect styles,
@@ -276,3 +307,34 @@ const totalBindings = Object.values(tally).reduce((a, b) => a + b, 0);
276
307
  - **This is the number `design-system-audit` records** as
277
308
  `audit.figmaInventory.bindings`, and the before/after gate the `token-builder`
278
309
  brownfield branch runs around every rename.
310
+
311
+ ## Subagent authoring: named working frame + finalize protocol
312
+
313
+ Figma writes are not git-committable, so a dead executor must never leave a
314
+ corrupted live component. Any subagent authoring a component (`figma-executor`)
315
+ uses **build-verify-then-replace**:
316
+
317
+ 1. **Always build into a distinct working frame** named `WIP: <ComponentName>` —
318
+ never edit the live component in place.
319
+ 2. **Verify the working frame green before touching anything real** — a
320
+ screenshot alone is **insufficient**: 10 tone-colored frames render
321
+ identically to 10 real variants, so a fast model can build plain frames and
322
+ self-report success. The gate is a **programmatic read-back** (`figma_execute`)
323
+ that asserts `node.type === 'COMPONENT_SET'` (never `'FRAME'`), the child count
324
+ matches the variant matrix with every child a `'COMPONENT'`,
325
+ `variantGroupProperties` names the expected axes, and a spot-check of ≥2
326
+ variants shows fills/strokes/radius bound to variables (not raw values) with
327
+ the expected `clipsContent`. A `figma_capture_screenshot` is a **secondary**
328
+ check (create → read-back → screenshot → iterate, max ~3), never the sole one.
329
+ 3. **Only then finalize:** remove/replace any existing same-named component,
330
+ rename the working frame's component set to the real `<ComponentName>`, **and
331
+ reap leftover artifacts** — search for and remove any stray `WIP:` frames or
332
+ orphaned fragments (from this or a prior failed run) so the file is left with
333
+ exactly one finalized component and zero `WIP:` debris.
334
+ 4. **On failure / `BLOCKED`:** leave the `WIP:` frame intact and named; the
335
+ existing real component is **never touched**. A resumed run finds the `WIP:`
336
+ frame by name and either continues or rebuilds it. A failure therefore leaves
337
+ an obvious, named, resumable artifact — not a half-built live component.
338
+
339
+ Concurrency-1 still applies: the whole Figma surface serializes through the one
340
+ bridge, so only one subagent runs this protocol at a time.
@@ -139,3 +139,8 @@ each platform's output is independent and verifiable, which makes it a good fit
139
139
  for **parallel subagent generation** — one subagent per adapter, each producing
140
140
  and validating its platform's files, reviewed before the combined result is
141
141
  landed in a PR. See the token-sync skill for the execution model.
142
+
143
+ Token-adapter generation parallelizes because each adapter writes independent
144
+ files. Figma authoring does **not**: the single figma-console bridge is
145
+ concurrency-1, so Figma work uses sequential subagents — model routing yes,
146
+ parallel never (see `${CLAUDE_PLUGIN_ROOT}/references/agent-routing.md`).
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, copyFileSync } from 'node:fs';
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, copyFileSync, realpathSync } from 'node:fs';
3
3
  import { join, dirname, relative, sep } from 'node:path';
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
  import { rewritePluginRoot } from './adapters/translate.mjs';
@@ -129,7 +129,14 @@ export function install({ target, dir, pkgRoot = PKG_ROOT }) {
129
129
  return { target, dir, written, payload };
130
130
  }
131
131
 
132
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
132
+ function isDirectInvocation() {
133
+ if (!process.argv[1]) return false;
134
+ let invoked = process.argv[1];
135
+ try { invoked = realpathSync(invoked); } catch { /* keep original */ }
136
+ return import.meta.url === pathToFileURL(invoked).href;
137
+ }
138
+
139
+ if (isDirectInvocation()) {
133
140
  const args = parseArgs(process.argv.slice(2));
134
141
  if (args.help) { console.log(USAGE); process.exit(0); }
135
142
  if (args.cmd !== 'init') { console.error(`✗ unknown command; expected "init"\n\n${USAGE}`); process.exit(1); }