@noemuch/bridge-ds 2.2.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.claude-plugin/plugin.json +31 -0
  2. package/.cursor-plugin/plugin.json +26 -0
  3. package/.mcp.json +12 -0
  4. package/CHANGELOG.md +66 -0
  5. package/CLAUDE.md +84 -0
  6. package/README.md +7 -3
  7. package/lib/cli.js +107 -134
  8. package/lib/mcp-setup.js +32 -28
  9. package/lib/scaffold.js +6 -3
  10. package/package.json +10 -3
  11. package/skills/design-workflow/SKILL.md +70 -17
  12. package/skills/design-workflow/references/actions/design.md +108 -11
  13. package/skills/design-workflow/references/actions/done.md +21 -3
  14. package/skills/design-workflow/references/actions/learn.md +147 -0
  15. package/skills/design-workflow/references/actions/quick.md +78 -0
  16. package/skills/design-workflow/references/actions/review.md +14 -3
  17. package/skills/design-workflow/references/actions/spec.md +58 -0
  18. package/skills/design-workflow/references/actions/sync.md +176 -0
  19. package/skills/design-workflow/references/figma-api-rules.md +116 -0
  20. package/skills/design-workflow/references/knowledge-base/README.md +18 -1
  21. package/skills/design-workflow/references/knowledge-base/schemas/assets.md +6 -0
  22. package/skills/design-workflow/references/knowledge-base/schemas/components.md +6 -0
  23. package/skills/design-workflow/references/knowledge-base/schemas/learnings.md +250 -0
  24. package/skills/design-workflow/references/knowledge-base/schemas/text-styles.md +6 -0
  25. package/skills/design-workflow/references/knowledge-base/schemas/validation.md +6 -0
  26. package/skills/design-workflow/references/knowledge-base/schemas/variables.md +6 -0
  27. package/skills/design-workflow/references/onboarding.md +51 -9
  28. package/skills/design-workflow/references/quality-gates.md +51 -2
  29. package/skills/design-workflow/references/templates/screen-template.md +37 -3
  30. package/skills/design-workflow/references/templates/spec-template.md +12 -0
  31. package/skills/design-workflow/references/transport-adapter.md +210 -0
@@ -19,10 +19,10 @@
19
19
  - Load knowledge base registries for validation:
20
20
  - `references/knowledge-base/registries/components.json` → verify component instances match registry
21
21
  - `references/knowledge-base/registries/variables.json` → verify variable bindings use correct names
22
- - Inspect Figma design via MCP:
22
+ - Inspect Figma design via MCP (tool names depend on transport — see `references/transport-adapter.md`):
23
23
  ```
24
- figma_take_screenshot({ node_id: "{nodeId}", file_key: "{fileKey}" })
25
- figma_get_variables({ file_key: "{fileKey}" })
24
+ Screenshot: console → figma_take_screenshot({ node_id, file_key }) / official → get_screenshot({ nodeId, fileKey })
25
+ Variables: console → figma_get_variables({ file_key }) / official → get_variable_defs({ fileKey })
26
26
  ```
27
27
 
28
28
  ### 2. Review checklist
@@ -106,6 +106,17 @@ Cross-reference every visual element in the design against `registries/component
106
106
  - [ ] Could the props surface be smaller?
107
107
  - [ ] Is the component reusable beyond its primary use case?
108
108
 
109
+ #### G. Learning Opportunity
110
+
111
+ If the review identifies issues that the user may want to correct manually in Figma (spacing adjustments, token swaps, component replacements):
112
+
113
+ ```
114
+ 💡 After making corrections in Figma, run: `learn`
115
+ Bridge will detect your changes and remember them for future designs.
116
+ ```
117
+
118
+ This hint is informational only — it does not block the review.
119
+
109
120
  ### 3. Report
110
121
 
111
122
  ```markdown
@@ -12,6 +12,17 @@ Ask or infer from context:
12
12
  - **Component**: design system primitive, block, or composition (Button, Card, Tag...)
13
13
  - **Screen**: full interface or page (dashboard, settings, onboarding flow...)
14
14
 
15
+ **If screen mode detected**, immediately ask the user:
16
+ ```
17
+ This is a screen spec. For reliable generation, I need a reference:
18
+
19
+ → Do you have a Figma URL of an existing screen with a similar layout?
20
+ (e.g., same sidebar + content structure, same navigation shell)
21
+
22
+ With a reference, I'll clone the shell and replace the content (fast, accurate).
23
+ Without one, I'll build from scratch (slower, may need iterations).
24
+ ```
25
+
15
26
  ### 2. Gather context
16
27
 
17
28
  - **Load design patterns** (MANDATORY for screens, recommended for components):
@@ -35,6 +46,30 @@ Ask or infer from context:
35
46
  - Check existing specs: `specs/active/`, `specs/backlog/`
36
47
  - Check existing DS components in `references/knowledge-base/registries/components.json`
37
48
 
49
+ ### 2.5. Load Learnings
50
+
51
+ Load `references/knowledge-base/learnings.json` (skip if file doesn't exist).
52
+
53
+ Filter learnings by `screenType` matching the new spec's type (from step 1 context):
54
+ - Include all **global** learnings (`scope: "global"`)
55
+ - Include **contextual** learnings where `context.screenType` matches
56
+
57
+ If matching learnings exist, include a **"Known Preferences"** section in the spec:
58
+
59
+ ```markdown
60
+ ## Known Preferences (from learnings)
61
+
62
+ The following preferences have been learned from previous design corrections:
63
+
64
+ | Rule | Property | Preferred Token | Scope | Signals |
65
+ |------|----------|----------------|-------|---------|
66
+ | {rule} | {property} | {to.token} | {scope} | {signals} |
67
+
68
+ These preferences MUST be applied during design generation unless the spec explicitly overrides them.
69
+ ```
70
+
71
+ This section goes after "Design tokens" and before "Responsive rules" (screens) or before "Acceptance criteria" (components).
72
+
38
73
  ### 3. Write the spec
39
74
 
40
75
  Write to `specs/active/{name}-spec.md`.
@@ -95,6 +130,29 @@ For each UI pattern described in the spec, check if it exists in `registries/com
95
130
  - A navigation pattern not covered by existing nav components
96
131
  - A data display pattern not covered by existing list/table components
97
132
 
133
+ ### 3c. Auto-enrich DS Components Used (screen mode)
134
+
135
+ For every component listed in "DS Components Used", resolve the exact registry key:
136
+
137
+ 1. Search `registries/components.json` by name → fill the `Key` column with the exact key
138
+ 2. Search `registries/icons.json`, `registries/logos.json` if applicable
139
+ 3. For each element, determine the **strategy**:
140
+ - Found in registry → `import`
141
+ - Not in registry but exists in reference screen → `clone` (note the reference node ID)
142
+ - Not in registry and no reference → flag as "New DS Component Required"
143
+
144
+ **Example enriched table:**
145
+ ```
146
+ | Component | Variant | Key / Source | Strategy |
147
+ |-----------|---------|-------------|----------|
148
+ | Button | primary, large | components.json → key: abc123 | import |
149
+ | Logo | finary-one | logos.json → key: 78defbf4 | import |
150
+ | SideStepper | 5 steps | components.json → key: 1668b598 | clone (reference 9569:40240) |
151
+ | ProductBackground | finaryOne | NOT IN REGISTRY | clone (reference 9569:40233) |
152
+ ```
153
+
154
+ This removes ambiguity at design time and prevents wrong component selection.
155
+
98
156
  ### 4. Validate
99
157
 
100
158
  **Token architecture:**
@@ -0,0 +1,176 @@
1
+ # Action: sync
2
+
3
+ > Incrementally sync the DS knowledge base with the current state of the Figma DS library.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ - Knowledge base exists (`references/knowledge-base/registries/` has JSON files) — abort if missing: "No knowledge base found. Run: `setup` first."
10
+ - Figma MCP transport available (console: `figma_get_status`, official: `whoami` — see `references/transport-adapter.md` Section F)
11
+
12
+ ---
13
+
14
+ ## Procedure
15
+
16
+ ### 1. Read current registries
17
+
18
+ Load all existing registries:
19
+ - `registries/components.json`
20
+ - `registries/variables.json`
21
+ - `registries/text-styles.json`
22
+ - `registries/icons.json` (if exists)
23
+ - `registries/logos.json` (if exists)
24
+ - `registries/illustrations.json` (if exists)
25
+
26
+ Note the `meta.fileKey` from any registry to identify the DS source file.
27
+
28
+ ### 2. Re-extract from Figma
29
+
30
+ Use the same MCP tools as `setup` (tool names depend on transport — see `references/transport-adapter.md`):
31
+
32
+ **Console transport:**
33
+ - `figma_get_design_system_kit({ file_key })` → full DS snapshot
34
+ - `figma_get_variables({ file_key })` → current variables
35
+ - `figma_get_styles({ file_key })` → current text/color/effect styles
36
+ - If keys missing, supplement with `figma_execute` extraction scripts (from `schemas/`)
37
+
38
+ **Official transport** (composite strategy — see transport-adapter.md Section D):
39
+ - `get_variable_defs({ fileKey })` → variables
40
+ - `search_design_system({ query: "*", includeComponents: true })` → components
41
+ - `search_design_system({ query: "*", includeStyles: true })` → styles
42
+ - Supplement with `use_figma` extraction scripts from schemas as needed
43
+
44
+ ### 3. Diff registries
45
+
46
+ Compare old vs new for each registry:
47
+
48
+ **Components (`components.json`):**
49
+ - **Added:** components in new extraction not in current registry
50
+ - **Removed:** components in current registry not in new extraction (match by `key`)
51
+ - **Modified:** same `key` but different `properties`, `name`, or `variants` count
52
+
53
+ **Variables (`variables.json`):**
54
+ - **Added:** new variable keys
55
+ - **Removed:** variable keys no longer present
56
+ - **Modified:** same `key` but different `name`, `valuesByMode`, or collection assignment
57
+
58
+ **Text styles (`text-styles.json`):**
59
+ - **Added:** new style keys
60
+ - **Removed:** style keys no longer present
61
+ - **Modified:** same `key` but different `name` or font properties
62
+
63
+ **Assets (icons/logos/illustrations):**
64
+ - Same add/remove/modify logic by `key`
65
+
66
+ ### 4. Impact analysis
67
+
68
+ For removed or modified items, check references across the knowledge base:
69
+
70
+ **Guides impact:**
71
+ - Search `guides/components/*.md` for references to removed/renamed components
72
+ - Search `guides/tokens/*.md` for references to removed/renamed variables
73
+ - Search `guides/patterns/*.md` for affected patterns
74
+
75
+ **Learnings impact:**
76
+ - Check `learnings.json` for learnings referencing removed tokens
77
+ - Flag affected learnings (don't delete — mark for user review)
78
+
79
+ **Active specs impact:**
80
+ - Check `specs/active/*.md` for references to removed/modified components or tokens
81
+
82
+ ### 5. Report to user
83
+
84
+ Present the diff report BEFORE applying changes:
85
+
86
+ ```markdown
87
+ ## DS Sync Report
88
+
89
+ ### Summary
90
+ - Components: +{added} ~{modified} -{removed}
91
+ - Variables: +{added} ~{modified} -{removed}
92
+ - Text styles: +{added} ~{modified} -{removed}
93
+ - Assets: +{added} ~{modified} -{removed}
94
+
95
+ ### Added
96
+ {list of new items per registry}
97
+
98
+ ### Modified
99
+ {list of changed items with old → new values}
100
+
101
+ ### Removed (⚠️ Breaking Changes)
102
+ {list of removed items}
103
+
104
+ #### Impact of removals:
105
+ - Guides affected: {list of guide files referencing removed items}
106
+ - Learnings affected: {list of learning IDs referencing removed tokens}
107
+ - Active specs affected: {list of spec files referencing removed items}
108
+
109
+ ### Recommended actions:
110
+ 1. {action per breaking change}
111
+ ```
112
+
113
+ **BLOCKING:** If there are removals (breaking changes), ask the user to confirm before proceeding:
114
+ ```
115
+ {n} items were removed from the DS. This affects {n} guides and {n} learnings.
116
+ Proceed with sync? (Removed items will be deleted from registries, affected guides will be patched.)
117
+ ```
118
+
119
+ ### 6. Apply updates
120
+
121
+ After user confirmation:
122
+
123
+ **Update registries:**
124
+ - Add new entries
125
+ - Update modified entries (preserve `key`, update other fields)
126
+ - Remove deleted entries
127
+
128
+ **Patch guides:**
129
+ - For removed components: remove or comment out references in affected guide files
130
+ - For renamed components: find-and-replace old name with new name
131
+ - For modified properties: update property descriptions in component guides
132
+
133
+ **Update learnings:**
134
+ - For learnings referencing removed tokens: add a flag entry noting the token was removed
135
+ - Do NOT delete learnings — they may still be conceptually valid even if the token name changed
136
+
137
+ **Re-validate registries:**
138
+ - Run sample import test (3-5 keys per registry) via `figma_execute` to confirm new/modified keys work
139
+ - Follow `schemas/validation.md` procedure
140
+
141
+ ### 7. Regenerate affected guides (optional)
142
+
143
+ If significant changes detected (>10 items changed or any category restructured), suggest:
144
+ ```
145
+ Significant DS changes detected. Regenerate affected guides?
146
+ - Token guides: {list if token changes}
147
+ - Component guides: {list if component changes}
148
+ ```
149
+
150
+ Only regenerate if user confirms. Use the same guide generation logic as `setup`.
151
+
152
+ ---
153
+
154
+ ## Output
155
+
156
+ ```
157
+ DS Sync complete.
158
+
159
+ Updated:
160
+ - components.json: +{n} ~{n} -{n}
161
+ - variables.json: +{n} ~{n} -{n}
162
+ - text-styles.json: +{n} ~{n} -{n}
163
+ - {assets}: +{n} ~{n} -{n}
164
+
165
+ Guides patched: {n} files
166
+ Learnings preserved: {n} ({n} flagged for review)
167
+ Validation: {PASS/FAIL}
168
+
169
+ Next: Review updated registries, then continue with `spec` or `design`.
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Transition
175
+
176
+ After sync → suggest: "DS synced. Run: `status` to see current state."
@@ -446,6 +446,75 @@ Same applies to `setFillStyleIdAsync`, `setStrokeStyleIdAsync`, `setEffectStyleI
446
446
 
447
447
  ---
448
448
 
449
+ ## Rule 22: Clone-first for screens with reference
450
+
451
+ When a reference Figma node is available (from the spec's "Reference Screen" section), **clone the shell structure instead of rebuilding from scratch**.
452
+
453
+ ### When to clone
454
+
455
+ Clone when the element is:
456
+ - A **layout shell** (sidebar + content + footer structure)
457
+ - A **complex pre-configured instance** (stepper with labels, navigation with active states)
458
+ - A **local/unpublished component** (backgrounds, decorative elements not in the DS library)
459
+ - An instance with **deeply nested properties** (3+ levels, properties on nested children not exposed at root)
460
+
461
+ ### How to clone
462
+
463
+ ```js
464
+ // Clone an entire subtree from a reference node
465
+ var ref = await figma.getNodeByIdAsync("REFERENCE_NODE_ID");
466
+ var clone = ref.clone();
467
+
468
+ // Position the clone
469
+ clone.x = 0;
470
+ clone.y = 0;
471
+
472
+ // Now modify the clone's content (replace text, swap instances, etc.)
473
+ var title = clone.findOne(function(n) { return n.name === "title" && n.type === "TEXT"; });
474
+ if (title) title.characters = "New Title";
475
+ ```
476
+
477
+ ### Clone vs Import decision
478
+
479
+ | Situation | Strategy |
480
+ |-----------|----------|
481
+ | Component in DS library, simple props | **Import** via `importComponentByKeyAsync` |
482
+ | Component in DS library, deeply nested | **Clone** from reference if available |
483
+ | Local/unpublished component | **Clone** from reference (only option) |
484
+ | Layout shell (sidebar + content + footer) | **Clone** the whole shell, replace content |
485
+ | Pre-configured stepper/nav with labels set | **Clone** (API can't easily override nested props) |
486
+
487
+ ### Pre-script audit format for clone elements
488
+
489
+ ```
490
+ PRE-SCRIPT AUDIT — Step {n}:
491
+ Spec requires: Source: Strategy:
492
+ ─────────────────────────────────────────────────────────────────
493
+ Sidebar shell → reference node 9569:40232 → clone ✓
494
+ ProductBackground → reference node 9569:40233 → clone ✓
495
+ SideStepper (5 steps) → reference node 9569:40240 → clone + modify labels ✓
496
+ Button (primary) → components.json key: abc123 → import ✓
497
+ Input (default) → components.json key: def456 → import ✓
498
+ ```
499
+
500
+ ---
501
+
502
+ ## Rule 23: Transport-aware scripting
503
+
504
+ Script format depends on the active MCP transport. See `references/transport-adapter.md` for full details.
505
+
506
+ | Aspect | Console (`figma_execute`) | Official (`use_figma`) |
507
+ |--------|--------------------------|------------------------|
508
+ | Wrapper | IIFE: `return (async function() { ... })();` | Top-level `await`, no IIFE |
509
+ | Parameters | `{ code }` | `{ fileKey, description, code }` |
510
+ | `figma.notify()` | Allowed | **Forbidden** |
511
+ | `getPluginData()` | Allowed | **Forbidden** (use `getSharedPluginData()`) |
512
+ | Response size | Unlimited | **20KB limit** — chunk large extractions |
513
+
514
+ **Before writing any script, check which transport is active and use the correct format.**
515
+
516
+ ---
517
+
449
518
  ## Standard Script Boilerplate
450
519
 
451
520
  ```js
@@ -497,3 +566,50 @@ return (async function() {
497
566
  return { success: true };
498
567
  })();
499
568
  ```
569
+
570
+ ### Official transport version (use_figma)
571
+
572
+ Same helpers, no IIFE wrapper. Called with `use_figma({ fileKey: "...", description: "...", code: "..." })`.
573
+
574
+ ```js
575
+ // ─── FONTS ───
576
+ await figma.loadFontAsync({ family: "Inter", style: "Regular" });
577
+ await figma.loadFontAsync({ family: "Inter", style: "Medium" });
578
+ await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
579
+ await figma.loadFontAsync({ family: "Inter", style: "Bold" });
580
+
581
+ // ─── VARIABLES (from registries/variables.json) ───
582
+ // var spLarge = await figma.variables.importVariableByKeyAsync("YOUR_KEY");
583
+
584
+ // ─── HELPERS ───
585
+ function mf(colorVar) {
586
+ var p = figma.util.solidPaint("#000000");
587
+ p = figma.variables.setBoundVariableForPaint(p, "color", colorVar);
588
+ return [p];
589
+ }
590
+
591
+ function appendFill(parent, child, fillH, fillV) {
592
+ parent.appendChild(child);
593
+ if (fillH) child.layoutSizingHorizontal = "FILL";
594
+ if (fillV) child.layoutSizingVertical = "FILL";
595
+ }
596
+
597
+ function bindPadding(frame, top, right, bottom, left) {
598
+ if (top) frame.setBoundVariable("paddingTop", top);
599
+ if (right) frame.setBoundVariable("paddingRight", right);
600
+ if (bottom) frame.setBoundVariable("paddingBottom", bottom);
601
+ if (left) frame.setBoundVariable("paddingLeft", left);
602
+ }
603
+
604
+ function bindRadius(frame, radiusVar) {
605
+ frame.setBoundVariable("topLeftRadius", radiusVar);
606
+ frame.setBoundVariable("topRightRadius", radiusVar);
607
+ frame.setBoundVariable("bottomLeftRadius", radiusVar);
608
+ frame.setBoundVariable("bottomRightRadius", radiusVar);
609
+ }
610
+
611
+ // ─── BUILD ───
612
+ // ... your design code here ...
613
+
614
+ return { success: true };
615
+ ```
@@ -43,6 +43,8 @@ knowledge-base/
43
43
  ui-references/ ← Product screenshots for pattern extraction
44
44
  screenshots/ ← PNG/JPG files of your product's key screens
45
45
  ui-references-guide.md ← Which screenshot for which pattern type
46
+
47
+ learnings.json ← Persistent learning store (generated by `learn`)
46
48
  ```
47
49
 
48
50
  ## How to populate
@@ -56,6 +58,21 @@ Run `/design-workflow setup` in Claude Code. Claude will:
56
58
  5. **Ask for screenshots** of your product's key screens
57
59
  6. **Generate** layout pattern documentation from the screenshots
58
60
 
61
+ ## Learnings
62
+
63
+ `learnings.json` stores user corrections detected by the `learn` action. See `schemas/learnings.md` for the full schema.
64
+
65
+ - **Learnings** = DS-compliant changes (user swapped one token for another) → applied in future generations
66
+ - **Flags** = non-DS-compliant changes (hardcoded hex, raw values) → surfaced for user review
67
+ - Learnings start as `contextual` (screen/component-specific) and promote to `global` after 3+ signals across 2+ screen types
68
+
59
69
  ## How to update
60
70
 
61
- When your DS evolves (new components, changed tokens), run `/design-workflow setup` again. Claude will detect existing registries and offer to update them incrementally.
71
+ When your DS evolves (new components, changed tokens), run `/design-workflow sync` for an incremental update. Claude will:
72
+
73
+ 1. Re-extract the DS from Figma
74
+ 2. Diff against existing registries
75
+ 3. Show a report: added, modified, removed items
76
+ 4. Apply updates after confirmation (with breaking change analysis)
77
+
78
+ For a full re-extraction, run `/design-workflow setup` again.
@@ -142,3 +142,9 @@ var logoInstance = defaultVariant.createInstance();
142
142
  - Illustrations often have theme variants (dark/light/brand)
143
143
  - May be component sets (`type: "COMPONENT_SET"`)
144
144
  - Naming convention: `{category}/{name}` (e.g., `asset/crypto`, `utility/empty-state`)
145
+
146
+ ---
147
+
148
+ ## Transport Note
149
+
150
+ For official transport: remove the IIFE wrapper from extraction scripts, add `fileKey` and `description` to the `use_figma` call. See `references/transport-adapter.md` for details.
@@ -122,3 +122,9 @@ Group components by semantic category:
122
122
  - `indicators` — Avatars, Status, Progress
123
123
 
124
124
  Use whatever categories match the DS's own organization.
125
+
126
+ ---
127
+
128
+ ## Transport Note
129
+
130
+ For official transport: remove the IIFE wrapper from extraction scripts, add `fileKey` and `description` to the `use_figma` call. See `references/transport-adapter.md` for details.