@noemuch/bridge-ds 2.0.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.
@@ -0,0 +1,128 @@
1
+ # Action: spec {name}
2
+
3
+ > Write or validate a specification. Auto-detects component vs screen mode.
4
+
5
+ ---
6
+
7
+ ## Procedure
8
+
9
+ ### 1. Determine mode
10
+
11
+ Ask or infer from context:
12
+ - **Component**: design system primitive, block, or composition (Button, Card, Tag...)
13
+ - **Screen**: full interface or page (dashboard, settings, onboarding flow...)
14
+
15
+ ### 2. Gather context
16
+
17
+ - **Load design patterns** (MANDATORY for screens, recommended for components):
18
+ - `references/knowledge-base/guides/design-patterns.md` → pattern catalogue
19
+ - Identify the **closest pattern** for this screen/component
20
+ - **Read the referenced screenshots** (min 2) from `references/knowledge-base/ui-references/screenshots/`
21
+ - Study: zones, proportions, density, hierarchy, navigation, card rhythm
22
+ - The spec's **layout structure and architecture diagram** MUST be based on these patterns, not invented from scratch
23
+
24
+ - **Load DS knowledge base** — use these to make informed component and token choices:
25
+ - `references/knowledge-base/guides/components/overview.md` → component decision tree
26
+ - `references/knowledge-base/registries/components.json` → available components with Figma keys
27
+ - `references/knowledge-base/guides/tokens/spacing-usage.md` → spacing scale + usage contexts
28
+ - `references/knowledge-base/guides/tokens/color-usage.md` → color token decision tree
29
+ - `references/knowledge-base/guides/tokens/typography-usage.md` → type hierarchy + font families
30
+ - Load relevant pattern guides if screen mode (form-patterns.md, multi-step-flow.md, navigation-patterns.md, feedback-patterns.md)
31
+ - Load relevant component group guides based on the screen's needs
32
+
33
+ - **Check knowledge base exists** — if `references/knowledge-base/registries/` is empty, tell the user: "Knowledge base not built yet. Run: `setup` first."
34
+
35
+ - Check existing specs: `specs/active/`, `specs/backlog/`
36
+ - Check existing DS components in `references/knowledge-base/registries/components.json`
37
+
38
+ ### 3. Write the spec
39
+
40
+ Write to `specs/active/{name}-spec.md`.
41
+
42
+ > For multi-screen flows with their own splitting rules (e.g., `specs/active/f1/rules.md`), read those rules first for folder structure and naming conventions.
43
+
44
+ #### Component spec — mandatory sections:
45
+
46
+ - **Description** (what, why, design principle)
47
+ - **Architecture overview** (composition diagram)
48
+ - **Component hierarchy** (levels: primitive → blocks → composition)
49
+ - **Props API** (TypeScript interfaces, variant names matching Figma)
50
+ - **Layout specs** (dimensions, gaps, alignment)
51
+ - **Design tokens** (spacing, colors, typography, radius)
52
+ - **Component properties** (TEXT, INSTANCE_SWAP, BOOLEAN — Figma)
53
+ - **Reused DS components** (existing components from registry)
54
+ - **Acceptance criteria** (checkboxes, testable)
55
+ - **Open questions**
56
+
57
+ Use template from `references/templates/spec-template.md`.
58
+
59
+ #### Screen spec — mandatory sections:
60
+
61
+ - **Description** (what screen, user goal, context)
62
+ - **Visual reference** (pattern name, screenshots studied, key composition rules applied)
63
+ - **Layout structure** (zones, grid, responsive behavior — MUST follow matched pattern)
64
+ - **Sections breakdown** (header, content area, sidebar, footer...)
65
+ - **DS components used** (EXHAUSTIVE list — every visible element must be accounted for with Figma keys from registry)
66
+ - **Content structure** (real or realistic placeholder data)
67
+ - **States** (empty, loading, populated, error)
68
+ - **Design tokens** (background, spacing rhythm, elevation)
69
+ - **Responsive rules** (breakpoints, layout shifts)
70
+ - **Acceptance criteria** (checkboxes)
71
+ - **Open questions**
72
+
73
+ Use template from `references/templates/screen-template.md`.
74
+
75
+ #### Component spec — visual reference (recommended):
76
+
77
+ For components that appear in existing screens, also include:
78
+ - **Visual reference** (which pattern/screenshot shows a similar component, composition rules)
79
+ - This helps the `design` step match proportions and density
80
+
81
+ ### 3b. Identify new DS components (screen mode only)
82
+
83
+ For each UI pattern described in the spec, check if it exists in `registries/components.json`:
84
+ - If a pattern is covered by an existing DS component → reference it in "DS Components Used"
85
+ - If a pattern is NOT covered → add it to the **"New DS Components Required"** section
86
+
87
+ **This is a blocking gate.** If new components are identified:
88
+ 1. List them in the spec with: name, description, where they're used, and variants/states needed
89
+ 2. After the screen spec is validated, each new component triggers its own `spec {component}` → `design` → `done` cycle
90
+ 3. The screen `design` step is blocked until all new components exist in the DS
91
+
92
+ **Common signals that a new component is needed:**
93
+ - A card/tile with specific internal structure (icon + title + description + badge + CTA)
94
+ - A custom indicator or status pattern not covered by Badge/Tag
95
+ - A navigation pattern not covered by existing nav components
96
+ - A data display pattern not covered by existing list/table components
97
+
98
+ ### 4. Validate
99
+
100
+ **Token architecture:**
101
+ - [ ] Every visual value references a design token (no hardcoded px/hex)
102
+ - [ ] Tokens use semantic names, not visual (`danger` not `red`)
103
+ - [ ] Aliasing depth ≤ 2 levels (primitive → semantic → component max)
104
+
105
+ **Naming conventions:**
106
+ - [ ] Variant names match Figma exactly
107
+ - [ ] Props use DS naming conventions (camelCase, `is` prefix for booleans, `on` prefix for events)
108
+ - [ ] Token references follow `{category}/{role}/{emphasis}` pattern
109
+
110
+ **Component API** (component mode only):
111
+ - [ ] Props surface area is minimal (composability over configuration)
112
+ - [ ] Composition pattern appropriate (slots > mega-props)
113
+ - [ ] Platform parity considered
114
+
115
+ **General:**
116
+ - [ ] Acceptance criteria are testable (not vague)
117
+ - [ ] Reused DS components identified
118
+ - [ ] Open questions are explicit
119
+
120
+ ### 5. Present for review
121
+
122
+ Output the spec, flag assumptions, highlight open questions.
123
+
124
+ ---
125
+
126
+ ## Transition
127
+
128
+ When spec is approved → suggest: "Spec approved. Run: `design`"
@@ -0,0 +1,453 @@
1
+ # Figma Plugin API — Mandatory Rules
2
+
3
+ > **This file MUST be read before writing ANY Figma generation script.**
4
+ > Every rule here was learned from real bugs. Breaking them = broken layout.
5
+ >
6
+ > **Note:** Variable keys, text style keys, and component keys vary per design system.
7
+ > Always load them from your project's `knowledge-base/registries/` directory.
8
+
9
+ ---
10
+
11
+ ## Rule 1: FILL after appendChild (CRITICAL)
12
+
13
+ `layoutSizingHorizontal = "FILL"` and `layoutSizingVertical = "FILL"` **ONLY work on children of auto-layout frames**. Setting FILL before `appendChild()` throws an error.
14
+
15
+ ```js
16
+ // WRONG — crashes
17
+ child.layoutSizingHorizontal = "FILL";
18
+ parent.appendChild(child);
19
+
20
+ // CORRECT
21
+ parent.appendChild(child);
22
+ child.layoutSizingHorizontal = "FILL";
23
+ ```
24
+
25
+ **Helper:**
26
+ ```js
27
+ function appendFill(parent, child, fillH, fillV) {
28
+ parent.appendChild(child);
29
+ if (fillH) child.layoutSizingHorizontal = "FILL";
30
+ if (fillV) child.layoutSizingVertical = "FILL";
31
+ }
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Rule 2: Absolute positioning after appendChild
37
+
38
+ `layoutPositioning = "ABSOLUTE"` requires the node to already be inside an auto-layout parent.
39
+
40
+ ```js
41
+ // CORRECT
42
+ parent.appendChild(circle);
43
+ circle.layoutPositioning = "ABSOLUTE";
44
+ circle.x = 100; circle.y = 50;
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Rule 3: FILL + AUTO parent = collapsed layout
50
+
51
+ A child with `FILL` inside a parent with `primaryAxisSizingMode = "AUTO"` collapses to 0px. The parent must be FIXED for FILL children.
52
+
53
+ ```js
54
+ // CORRECT
55
+ root.primaryAxisSizingMode = "FIXED";
56
+ root.resize(1440, 900);
57
+ // then after appendChild:
58
+ mainArea.layoutSizingVertical = "FILL";
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Rule 4: resize() overrides sizing modes (CRITICAL)
64
+
65
+ `resize(width, height)` forces **both** axes to `"FIXED"`. Set sizing modes AFTER resize.
66
+
67
+ ```js
68
+ // CORRECT
69
+ frame.resize(700, 10);
70
+ frame.primaryAxisSizingMode = "AUTO";
71
+ frame.counterAxisSizingMode = "FIXED";
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Rule 5: counterAxisAlignItems for cross-axis centering
77
+
78
+ | Layout mode | primaryAxisAlignItems controls | counterAxisAlignItems controls |
79
+ |-------------|-------------------------------|-------------------------------|
80
+ | VERTICAL | Vertical alignment | Horizontal alignment |
81
+ | HORIZONTAL | Horizontal alignment | Vertical alignment |
82
+
83
+ ```js
84
+ // Center children horizontally in a vertical layout
85
+ container.layoutMode = "VERTICAL";
86
+ container.counterAxisAlignItems = "CENTER";
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Rule 6: Always bind spacing variables (NEVER hardcode px)
92
+
93
+ Every padding, gap, and radius value MUST use `setBoundVariable()` with a spacing token from the registry.
94
+
95
+ **Load spacing keys from `registries/variables.json`.** Look for variables with names like `layout/spacing/*` and `layout/radius/*`.
96
+
97
+ ```js
98
+ // Load spacing vars once at script start (keys from your registries/variables.json)
99
+ var spLarge = await figma.variables.importVariableByKeyAsync("YOUR_SPACING_LARGE_KEY");
100
+ var spMedium = await figma.variables.importVariableByKeyAsync("YOUR_SPACING_MEDIUM_KEY");
101
+ var radMedium = await figma.variables.importVariableByKeyAsync("YOUR_RADIUS_MEDIUM_KEY");
102
+
103
+ // Bind to frame
104
+ frame.setBoundVariable('itemSpacing', spMedium);
105
+ frame.setBoundVariable('paddingTop', spLarge);
106
+ frame.setBoundVariable('paddingBottom', spLarge);
107
+ frame.setBoundVariable('paddingLeft', spLarge);
108
+ frame.setBoundVariable('paddingRight', spLarge);
109
+ ```
110
+
111
+ **Helper:**
112
+ ```js
113
+ function bindPadding(frame, top, right, bottom, left) {
114
+ if (top) frame.setBoundVariable("paddingTop", top);
115
+ if (right) frame.setBoundVariable("paddingRight", right);
116
+ if (bottom) frame.setBoundVariable("paddingBottom", bottom);
117
+ if (left) frame.setBoundVariable("paddingLeft", left);
118
+ }
119
+
120
+ function bindRadius(frame, radiusVar) {
121
+ frame.setBoundVariable("topLeftRadius", radiusVar);
122
+ frame.setBoundVariable("topRightRadius", radiusVar);
123
+ frame.setBoundVariable("bottomLeftRadius", radiusVar);
124
+ frame.setBoundVariable("bottomRightRadius", radiusVar);
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Rule 7: Colors via setBoundVariableForPaint (not setBoundVariable)
131
+
132
+ Fills and strokes use a **different API** than layout properties.
133
+
134
+ ```js
135
+ // WRONG
136
+ frame.setBoundVariable('fills', colorVar);
137
+
138
+ // CORRECT
139
+ function mf(colorVar) {
140
+ var p = figma.util.solidPaint("#000000");
141
+ p = figma.variables.setBoundVariableForPaint(p, "color", colorVar);
142
+ return [p];
143
+ }
144
+ frame.fills = mf(myColorVar);
145
+ ```
146
+
147
+ **Load color keys from `registries/variables.json`.** Look for variables with names like `color/background/*`, `color/text/*`, `color/border/*`.
148
+
149
+ ---
150
+
151
+ ## Rule 8: Text styles via importStyleByKeyAsync (NEVER hardcode fonts)
152
+
153
+ Never set `fontName`, `fontSize`, or `lineHeight` manually. Always use text styles from the library.
154
+
155
+ ```js
156
+ // WRONG
157
+ text.fontName = { family: "Inter", style: "Bold" };
158
+ text.fontSize = 32;
159
+
160
+ // CORRECT (key from registries/text-styles.json)
161
+ var style = await figma.importStyleByKeyAsync("YOUR_TEXT_STYLE_KEY");
162
+ text.textStyleId = style.id;
163
+ ```
164
+
165
+ **Load text style keys from `registries/text-styles.json`.**
166
+
167
+ ---
168
+
169
+ ## Rule 9: Component properties — add, bind, and override
170
+
171
+ ### 9a. addComponentProperty AFTER combineAsVariants
172
+
173
+ ```js
174
+ var compSet = figma.combineAsVariants(components, figma.currentPage);
175
+ compSet.addComponentProperty('title', 'TEXT', 'Default title');
176
+ ```
177
+
178
+ ### 9b. Bind TEXT properties to text nodes
179
+
180
+ ```js
181
+ var titlePropKey = Object.keys(compSet.componentPropertyDefinitions)
182
+ .find(k => compSet.componentPropertyDefinitions[k].type === "TEXT" && k.startsWith("title"));
183
+
184
+ for (var i = 0; i < compSet.children.length; i++) {
185
+ var variant = compSet.children[i];
186
+ var titleNode = variant.findOne(n => n.name === "title" && n.type === "TEXT");
187
+ if (titleNode && titlePropKey) {
188
+ titleNode.componentPropertyReferences = { characters: titlePropKey };
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### 9c. Override TEXT properties on instances
194
+
195
+ ```js
196
+ var instance = variant.createInstance();
197
+ var propDefs = compSet.componentPropertyDefinitions;
198
+ for (var key in propDefs) {
199
+ if (key.startsWith("title") && propDefs[key].type === "TEXT") {
200
+ instance.setProperties({ [key]: "My custom title" });
201
+ }
202
+ }
203
+ ```
204
+
205
+ ### 9d. INSTANCE_SWAP properties for icons
206
+
207
+ ```js
208
+ compSet.addComponentProperty('icon', 'INSTANCE_SWAP', defaultIconId);
209
+ var iconPropKey = Object.keys(compSet.componentPropertyDefinitions)
210
+ .find(k => k.startsWith("icon") && compSet.componentPropertyDefinitions[k].type === "INSTANCE_SWAP");
211
+
212
+ for (var i = 0; i < compSet.children.length; i++) {
213
+ var variant = compSet.children[i];
214
+ var iconNode = variant.findOne(n => n.name === "icon" && n.type === "INSTANCE");
215
+ if (iconNode && iconPropKey) {
216
+ iconNode.componentPropertyReferences = { mainComponent: iconPropKey };
217
+ }
218
+ }
219
+ ```
220
+
221
+ ### 9e. BOOLEAN properties for visibility
222
+
223
+ ```js
224
+ compSet.addComponentProperty('showButton', 'BOOLEAN', true);
225
+ var btnPropKey = Object.keys(compSet.componentPropertyDefinitions)
226
+ .find(k => k.startsWith("showButton"));
227
+
228
+ for (var i = 0; i < compSet.children.length; i++) {
229
+ var variant = compSet.children[i];
230
+ var btnNode = variant.findOne(n => n.name === "button");
231
+ if (btnNode && btnPropKey) {
232
+ btnNode.componentPropertyReferences = { visible: btnPropKey };
233
+ }
234
+ }
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Rule 10: Property keys include hash suffix
240
+
241
+ `componentPropertyDefinitions` returns keys like `title#9311:226`. Use the **full key** (with hash).
242
+
243
+ ```js
244
+ function findPropKey(compSet, prefix, type) {
245
+ var defs = compSet.componentPropertyDefinitions;
246
+ return Object.keys(defs).find(function(k) {
247
+ return k.startsWith(prefix) && defs[k].type === type;
248
+ });
249
+ }
250
+ var titleKey = findPropKey(compSet, "title", "TEXT");
251
+ ```
252
+
253
+ ---
254
+
255
+ ## Rule 11: importComponentSetByKeyAsync vs importComponentByKeyAsync
256
+
257
+ | What | API |
258
+ |------|-----|
259
+ | Component with variants (Button, Tag) | `importComponentSetByKeyAsync` |
260
+ | Single component (icon, logo) | `importComponentByKeyAsync` |
261
+
262
+ Check `registries/components.json` — entries with `variantCount > 1` are component sets.
263
+
264
+ ---
265
+
266
+ ## Rule 12: textAutoResize in auto-layout
267
+
268
+ Set characters FIRST, append, FILL, then textAutoResize:
269
+
270
+ ```js
271
+ var t = figma.createText();
272
+ t.characters = "Long text...";
273
+ parent.appendChild(t);
274
+ t.layoutSizingHorizontal = "FILL";
275
+ t.textAutoResize = "HEIGHT";
276
+ ```
277
+
278
+ **GOTCHA:** `textAutoResize = "HEIGHT"` before the node has width → 0-width vertical text.
279
+
280
+ ---
281
+
282
+ ## Rule 13: strokeAlign INSIDE for cards
283
+
284
+ ```js
285
+ card.strokes = mf(borderVar);
286
+ card.strokeWeight = 1;
287
+ card.strokeAlign = "INSIDE";
288
+ ```
289
+
290
+ Always use `"INSIDE"` for cards, panels, inputs.
291
+
292
+ ---
293
+
294
+ ## Rule 14: Cannot add children to instances
295
+
296
+ Component instances are sealed. Use `setProperties()` or `swapComponent()`.
297
+
298
+ ```js
299
+ // WRONG
300
+ inst.appendChild(extraFrame); // crashes
301
+
302
+ // CORRECT
303
+ inst.setProperties({ [titleKey]: "New title" });
304
+ ```
305
+
306
+ ---
307
+
308
+ ## Rule 15: Variant grid layout after combineAsVariants
309
+
310
+ Variants stack at (0,0) after `combineAsVariants()`. Arrange in a grid:
311
+
312
+ ```js
313
+ var cols = 4;
314
+ for (var i = 0; i < compSet.children.length; i++) {
315
+ var child = compSet.children[i];
316
+ child.x = (i % cols) * (child.width + 40);
317
+ child.y = Math.floor(i / cols) * (child.height + 40);
318
+ }
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Rule 16: loadFontAsync before ANY text operation
324
+
325
+ Every script that creates or modifies text MUST load fonts first:
326
+
327
+ ```js
328
+ await figma.loadFontAsync({ family: "Inter", style: "Regular" });
329
+ await figma.loadFontAsync({ family: "Inter", style: "Medium" });
330
+ await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
331
+ await figma.loadFontAsync({ family: "Inter", style: "Bold" });
332
+ ```
333
+
334
+ Load the fonts used in YOUR design system. Check `registries/text-styles.json` for font families.
335
+
336
+ ---
337
+
338
+ ## Rule 17: Script structure
339
+
340
+ Every script executed via `figma_execute` MUST follow this structure:
341
+
342
+ ```js
343
+ return (async function() {
344
+ // 1. Load fonts
345
+ // 2. Import variables + styles + components (keys from registries)
346
+ // 3. Define helpers (mf, appendFill, bindPadding, bindRadius)
347
+ // 4. Build layout tree (create → configure → append → FILL)
348
+ // 5. Return summary
349
+ return { success: true };
350
+ })();
351
+ ```
352
+
353
+ The `return` before the IIFE is mandatory — without it, the Promise is lost.
354
+
355
+ ---
356
+
357
+ ## Rule 18: DS component reuse — NEVER recreate existing components
358
+
359
+ **This is the most critical rule. Violations require script rewrite.**
360
+
361
+ Before creating ANY visual element, check the registries:
362
+ 1. `registries/components.json` → Buttons, Tags, Inputs, Avatars, Dividers, etc.
363
+ 2. `registries/icons.json` → Icons (if exists)
364
+ 3. `registries/logos.json` → Logos (if exists)
365
+ 4. `registries/illustrations.json` → Illustrations (if exists)
366
+
367
+ **NEVER:**
368
+ - Create a raw frame/ellipse for an Avatar → import the DS component
369
+ - Create a raw rectangle for a Divider → import the DS component
370
+ - Create a raw frame with text for a Tag/Badge → import the DS component
371
+ - Hardcode hex colors → always bind variables
372
+
373
+ **Pre-script checklist (mandatory):**
374
+ ```
375
+ Elements in this step:
376
+ - Avatar → components.json key: xxx ✓
377
+ - Divider → components.json key: xxx ✓
378
+ - Label → raw text (no DS component for this) ✓
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Rule 19: Canvas positioning — never stack components
384
+
385
+ - **NEVER** leave multiple components at (0, 0)
386
+ - **Minimum gap**: 80px between components on the canvas
387
+ - **Sub-components**: horizontal row at the top
388
+ - **Main component**: 400px below sub-components
389
+
390
+ ```js
391
+ var currentX = 0;
392
+ for (var i = 0; i < subComponents.length; i++) {
393
+ subComponents[i].x = currentX;
394
+ subComponents[i].y = 0;
395
+ currentX += subComponents[i].width + 80;
396
+ }
397
+ mainComponent.x = 0;
398
+ mainComponent.y = 400;
399
+ ```
400
+
401
+ ---
402
+
403
+ ## Standard Script Boilerplate
404
+
405
+ ```js
406
+ return (async function() {
407
+
408
+ // ─── FONTS ───
409
+ // Load fonts used by your DS (check registries/text-styles.json for families)
410
+ await figma.loadFontAsync({ family: "Inter", style: "Regular" });
411
+ await figma.loadFontAsync({ family: "Inter", style: "Medium" });
412
+ await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
413
+ await figma.loadFontAsync({ family: "Inter", style: "Bold" });
414
+
415
+ // ─── VARIABLES (from registries/variables.json) ───
416
+ // Load spacing, radius, and color variables by key
417
+ // var spLarge = await figma.variables.importVariableByKeyAsync("YOUR_KEY");
418
+ // var radMedium = await figma.variables.importVariableByKeyAsync("YOUR_KEY");
419
+ // var bgColor = await figma.variables.importVariableByKeyAsync("YOUR_KEY");
420
+
421
+ // ─── HELPERS ───
422
+ function mf(colorVar) {
423
+ var p = figma.util.solidPaint("#000000");
424
+ p = figma.variables.setBoundVariableForPaint(p, "color", colorVar);
425
+ return [p];
426
+ }
427
+
428
+ function appendFill(parent, child, fillH, fillV) {
429
+ parent.appendChild(child);
430
+ if (fillH) child.layoutSizingHorizontal = "FILL";
431
+ if (fillV) child.layoutSizingVertical = "FILL";
432
+ }
433
+
434
+ function bindPadding(frame, top, right, bottom, left) {
435
+ if (top) frame.setBoundVariable("paddingTop", top);
436
+ if (right) frame.setBoundVariable("paddingRight", right);
437
+ if (bottom) frame.setBoundVariable("paddingBottom", bottom);
438
+ if (left) frame.setBoundVariable("paddingLeft", left);
439
+ }
440
+
441
+ function bindRadius(frame, radiusVar) {
442
+ frame.setBoundVariable("topLeftRadius", radiusVar);
443
+ frame.setBoundVariable("topRightRadius", radiusVar);
444
+ frame.setBoundVariable("bottomLeftRadius", radiusVar);
445
+ frame.setBoundVariable("bottomRightRadius", radiusVar);
446
+ }
447
+
448
+ // ─── BUILD ───
449
+ // ... your design code here ...
450
+
451
+ return { success: true };
452
+ })();
453
+ ```
@@ -0,0 +1,52 @@
1
+ # Knowledge Base
2
+
3
+ This directory contains your design system's complete documentation, generated by Claude during `/design-workflow setup`.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ knowledge-base/
9
+ registries/ ← Raw DS data (auto-extracted from Figma)
10
+ components.json ← Component names, keys, variants, properties
11
+ variables.json ← Variable names, keys, types, values by mode
12
+ text-styles.json ← Text style names, keys, font specs
13
+ icons.json ← Icon component keys (optional)
14
+ logos.json ← Logo component keys (optional)
15
+ illustrations.json ← Illustration keys (optional)
16
+
17
+ guides/ ← Intelligent documentation (generated by Claude)
18
+ design-patterns.md ← Layout patterns extracted from product screenshots
19
+ tokens/
20
+ color-usage.md ← Color token decision tree
21
+ spacing-usage.md ← Spacing scale + usage contexts
22
+ typography-usage.md ← Type hierarchy + font families
23
+ components/
24
+ overview.md ← Component decision tree (what to use when)
25
+ {group}.md ← Per-group guides (actions, form-controls, etc.)
26
+ patterns/
27
+ form-patterns.md ← Form field patterns, validation
28
+ navigation-patterns.md ← Sidebar, tabs, breadcrumbs
29
+ feedback-patterns.md ← Success, error, warning, loading states
30
+ multi-step-flow.md ← Stepper, progress, module flows
31
+ assets/
32
+ icons.md ← Categorized icon catalog
33
+ logos.md ← Logo catalog
34
+ illustrations.md ← Illustration catalog + usage
35
+
36
+ ui-references/ ← Product screenshots for pattern extraction
37
+ screenshots/ ← PNG/JPG files of your product's key screens
38
+ ui-references-guide.md ← Which screenshot for which pattern type
39
+ ```
40
+
41
+ ## How to populate
42
+
43
+ Run `/design-workflow setup` in Claude Code. Claude will:
44
+
45
+ 1. **Extract** your DS from Figma via `figma_get_design_system_kit`
46
+ 2. **Analyze** the raw data and write intelligent guides
47
+ 3. **Ask for screenshots** of your product's key screens
48
+ 4. **Generate** layout pattern documentation from the screenshots
49
+
50
+ ## How to update
51
+
52
+ When your DS evolves (new components, changed tokens), run `/design-workflow setup` again. Claude will detect existing registries and offer to update them incrementally.