@noemuch/bridge-ds 2.2.0 → 2.3.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/package.json +1 -1
- package/skills/design-workflow/references/actions/design.md +47 -1
- package/skills/design-workflow/references/actions/spec.md +34 -0
- package/skills/design-workflow/references/figma-api-rules.md +53 -0
- package/skills/design-workflow/references/templates/screen-template.md +25 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noemuch/bridge-ds",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "AI-powered design generation in Figma — 100% design system compliant. Connects Claude Code to Figma via MCP for spec-first, token-bound, component-native design.",
|
|
5
5
|
"main": "lib/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -69,7 +69,53 @@ Key rules applied: {bullet list}
|
|
|
69
69
|
|
|
70
70
|
**GATE: If no pattern matches**, ask the user which existing pattern is closest.
|
|
71
71
|
|
|
72
|
-
### 1c.
|
|
72
|
+
### 1c. Reference Inspection (BLOCKING for screens with reference)
|
|
73
|
+
|
|
74
|
+
**If the spec has a "Reference Screen" section with a Figma URL/node ID, this step is MANDATORY.**
|
|
75
|
+
|
|
76
|
+
1. **Screenshot the reference** via `figma_take_screenshot({ node_id, file_key })`
|
|
77
|
+
2. **Inspect the reference structure** via `figma_execute` — extract the node tree:
|
|
78
|
+
```js
|
|
79
|
+
return (async function() {
|
|
80
|
+
var ref = await figma.getNodeByIdAsync("REFERENCE_NODE_ID");
|
|
81
|
+
if (!ref) return { error: "Node not found" };
|
|
82
|
+
var children = [];
|
|
83
|
+
for (var i = 0; i < ref.children.length; i++) {
|
|
84
|
+
var c = ref.children[i];
|
|
85
|
+
children.push({
|
|
86
|
+
name: c.name, type: c.type, id: c.id,
|
|
87
|
+
width: Math.round(c.width), height: Math.round(c.height),
|
|
88
|
+
isComponent: c.type === "INSTANCE" || c.type === "COMPONENT",
|
|
89
|
+
componentName: c.type === "INSTANCE" ? c.mainComponent.name : undefined
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return { name: ref.name, width: Math.round(ref.width), height: Math.round(ref.height), children: children };
|
|
93
|
+
})();
|
|
94
|
+
```
|
|
95
|
+
3. **Document findings** before proceeding:
|
|
96
|
+
```
|
|
97
|
+
Reference inspection:
|
|
98
|
+
- Shell structure: {sidebar Xpx | content FILL | buffer Xpx}
|
|
99
|
+
- DS components found: {list with node IDs}
|
|
100
|
+
- Local/unpublished elements: {list with node IDs — these need cloning}
|
|
101
|
+
- Logo variant: {exact name}
|
|
102
|
+
- Key differences from spec: {what content changes}
|
|
103
|
+
```
|
|
104
|
+
4. **Update generation strategy:**
|
|
105
|
+
- Elements found in reference → plan to **clone** (faster, guaranteed match)
|
|
106
|
+
- Elements in DS registry but not in reference → plan to **import**
|
|
107
|
+
- Update the pre-script audit to reflect clone vs import per element
|
|
108
|
+
|
|
109
|
+
**GATE:** Do not generate until reference inspection is complete and strategy is documented.
|
|
110
|
+
|
|
111
|
+
**If no reference provided (building from scratch):** Skip this step but warn the user:
|
|
112
|
+
```
|
|
113
|
+
No reference screen provided. Building layout from scratch.
|
|
114
|
+
This may require more iterations. For better results, provide a Figma URL
|
|
115
|
+
of an existing screen with a similar layout shell.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 1d. Canvas dimensions
|
|
73
119
|
|
|
74
120
|
- **Web**: 1440px wide
|
|
75
121
|
- **Mobile**: 390px wide
|
|
@@ -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):
|
|
@@ -95,6 +106,29 @@ For each UI pattern described in the spec, check if it exists in `registries/com
|
|
|
95
106
|
- A navigation pattern not covered by existing nav components
|
|
96
107
|
- A data display pattern not covered by existing list/table components
|
|
97
108
|
|
|
109
|
+
### 3c. Auto-enrich DS Components Used (screen mode)
|
|
110
|
+
|
|
111
|
+
For every component listed in "DS Components Used", resolve the exact registry key:
|
|
112
|
+
|
|
113
|
+
1. Search `registries/components.json` by name → fill the `Key` column with the exact key
|
|
114
|
+
2. Search `registries/icons.json`, `registries/logos.json` if applicable
|
|
115
|
+
3. For each element, determine the **strategy**:
|
|
116
|
+
- Found in registry → `import`
|
|
117
|
+
- Not in registry but exists in reference screen → `clone` (note the reference node ID)
|
|
118
|
+
- Not in registry and no reference → flag as "New DS Component Required"
|
|
119
|
+
|
|
120
|
+
**Example enriched table:**
|
|
121
|
+
```
|
|
122
|
+
| Component | Variant | Key / Source | Strategy |
|
|
123
|
+
|-----------|---------|-------------|----------|
|
|
124
|
+
| Button | primary, large | components.json → key: abc123 | import |
|
|
125
|
+
| Logo | finary-one | logos.json → key: 78defbf4 | import |
|
|
126
|
+
| SideStepper | 5 steps | components.json → key: 1668b598 | clone (reference 9569:40240) |
|
|
127
|
+
| ProductBackground | finaryOne | NOT IN REGISTRY | clone (reference 9569:40233) |
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This removes ambiguity at design time and prevents wrong component selection.
|
|
131
|
+
|
|
98
132
|
### 4. Validate
|
|
99
133
|
|
|
100
134
|
**Token architecture:**
|
|
@@ -446,6 +446,59 @@ 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
|
+
|
|
449
502
|
## Standard Script Boilerplate
|
|
450
503
|
|
|
451
504
|
```js
|
|
@@ -8,6 +8,23 @@
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
## Reference Screen (REQUIRED)
|
|
12
|
+
|
|
13
|
+
> A screen that already exists in Figma with the same layout shell (sidebar + content, topbar + main, etc.).
|
|
14
|
+
> Claude will clone the shell from this reference and replace the content.
|
|
15
|
+
> **Without a reference, generation is significantly less reliable.**
|
|
16
|
+
|
|
17
|
+
| | |
|
|
18
|
+
|---|---|
|
|
19
|
+
| **Reference URL** | {Figma URL of an existing screen with the same shell/layout} |
|
|
20
|
+
| **Reference node ID** | {nodeId extracted from URL} |
|
|
21
|
+
| **Shell elements to clone** | {list: e.g., "sidebar frame, product background, stepper, footer"} |
|
|
22
|
+
| **What changes vs reference** | {what content/sections differ from the reference} |
|
|
23
|
+
|
|
24
|
+
> If no existing screen uses this layout: write "None — new layout, building from scratch" and document the shell structure in detail in Layout Structure below.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
11
28
|
## Visual Reference
|
|
12
29
|
|
|
13
30
|
> Identifies which design pattern this screen follows.
|
|
@@ -67,10 +84,15 @@
|
|
|
67
84
|
|
|
68
85
|
> Look up component keys in `knowledge-base/registries/components.json`.
|
|
69
86
|
> Use `knowledge-base/guides/components/overview.md` decision tree to choose the right component.
|
|
87
|
+
> Mark each element as `import` (from DS library) or `clone` (from reference screen).
|
|
88
|
+
|
|
89
|
+
| Component | Variant/Size | Key / Source | Strategy | Location |
|
|
90
|
+
|-----------|-------------|-------------|----------|----------|
|
|
91
|
+
| `{Name}` | {variant} | {registry key or "reference node {id}"} | import / clone | {section} |
|
|
70
92
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
93
|
+
**Strategy guide:**
|
|
94
|
+
- `import` — Component exists in DS library → use `importComponentByKeyAsync(key)`
|
|
95
|
+
- `clone` — Component is local/unpublished or pre-configured in reference → clone from reference node
|
|
74
96
|
|
|
75
97
|
---
|
|
76
98
|
|