@noemuch/bridge-ds 2.3.0 → 2.5.1
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/.claude-plugin/plugin.json +31 -0
- package/.cursor-plugin/plugin.json +26 -0
- package/.mcp.json +12 -0
- package/CHANGELOG.md +93 -0
- package/CLAUDE.md +84 -0
- package/README.md +25 -10
- package/lib/cli.js +107 -134
- package/lib/mcp-setup.js +32 -28
- package/lib/scaffold.js +6 -3
- package/package.json +10 -3
- package/skills/design-workflow/SKILL.md +70 -17
- package/skills/design-workflow/references/actions/design.md +63 -12
- package/skills/design-workflow/references/actions/done.md +21 -3
- package/skills/design-workflow/references/actions/learn.md +147 -0
- package/skills/design-workflow/references/actions/quick.md +80 -0
- package/skills/design-workflow/references/actions/review.md +14 -3
- package/skills/design-workflow/references/actions/spec.md +24 -0
- package/skills/design-workflow/references/actions/sync.md +176 -0
- package/skills/design-workflow/references/figma-api-rules.md +112 -0
- package/skills/design-workflow/references/knowledge-base/README.md +18 -1
- package/skills/design-workflow/references/knowledge-base/schemas/assets.md +6 -0
- package/skills/design-workflow/references/knowledge-base/schemas/components.md +6 -0
- package/skills/design-workflow/references/knowledge-base/schemas/learnings.md +250 -0
- package/skills/design-workflow/references/knowledge-base/schemas/text-styles.md +6 -0
- package/skills/design-workflow/references/knowledge-base/schemas/validation.md +6 -0
- package/skills/design-workflow/references/knowledge-base/schemas/variables.md +6 -0
- package/skills/design-workflow/references/onboarding.md +51 -9
- package/skills/design-workflow/references/quality-gates.md +51 -2
- package/skills/design-workflow/references/templates/screen-template.md +12 -0
- package/skills/design-workflow/references/templates/spec-template.md +12 -0
- package/skills/design-workflow/references/transport-adapter.md +210 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bridge-ds",
|
|
3
|
+
"displayName": "Bridge Design System",
|
|
4
|
+
"version": "2.5.1",
|
|
5
|
+
"description": "AI-powered design generation in Figma — spec-first, DS-native, with a learning loop that improves over time. Extracts your real design system, writes validated specs, and generates production-ready Figma designs using actual DS components and tokens.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "noemuch",
|
|
8
|
+
"url": "https://github.com/noemuch"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/noemuch/bridge",
|
|
11
|
+
"repository": "https://github.com/noemuch/bridge",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"figma",
|
|
15
|
+
"design-system",
|
|
16
|
+
"design-tokens",
|
|
17
|
+
"mcp",
|
|
18
|
+
"ai-design",
|
|
19
|
+
"figma-plugin-api",
|
|
20
|
+
"spec-first",
|
|
21
|
+
"design-generation"
|
|
22
|
+
],
|
|
23
|
+
"skills": {
|
|
24
|
+
"design-workflow": "./skills/design-workflow/SKILL.md"
|
|
25
|
+
},
|
|
26
|
+
"commands": {
|
|
27
|
+
"design-workflow": "./commands/design-workflow.md"
|
|
28
|
+
},
|
|
29
|
+
"instructions": "./CLAUDE.md",
|
|
30
|
+
"mcpServers": "./.mcp.json"
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bridge-ds",
|
|
3
|
+
"displayName": "Bridge Design System",
|
|
4
|
+
"version": "2.5.1",
|
|
5
|
+
"description": "AI-powered design generation in Figma — spec-first, DS-native, with a learning loop.",
|
|
6
|
+
"author": "noemuch",
|
|
7
|
+
"homepage": "https://github.com/noemuch/bridge",
|
|
8
|
+
"repository": "https://github.com/noemuch/bridge",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": ["figma", "design-system", "mcp", "ai-design"],
|
|
11
|
+
"skills": {
|
|
12
|
+
"design-workflow": "./skills/design-workflow/SKILL.md"
|
|
13
|
+
},
|
|
14
|
+
"commands": {
|
|
15
|
+
"design-workflow": "./commands/design-workflow.md"
|
|
16
|
+
},
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"figma-console": {
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["-y", "figma-console-mcp@latest"],
|
|
21
|
+
"env": {
|
|
22
|
+
"FIGMA_ACCESS_TOKEN": ""
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
package/.mcp.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"figma-console": {
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": ["-y", "figma-console-mcp@latest"],
|
|
6
|
+
"env": {
|
|
7
|
+
"FIGMA_ACCESS_TOKEN": ""
|
|
8
|
+
},
|
|
9
|
+
"description": "Figma Console MCP — gives Claude native access to Figma Desktop via Plugin API. Required for design generation."
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Bridge DS are documented here.
|
|
4
|
+
|
|
5
|
+
## [2.5.1] — 2026-03-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Rule 24**: Never screenshot a page or empty node — create a frame first
|
|
9
|
+
- **Rule 25**: Input/Select components — swap to `state=filled` for real values
|
|
10
|
+
- **Rule 26**: Validate registry keys before writing scripts — copy-paste from registries, never type manually
|
|
11
|
+
- `quick.md`: References Rules 24-26 in generation steps
|
|
12
|
+
|
|
13
|
+
## [2.5.0] — 2026-03-25
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Dual MCP transport**: Support for both figma-console-mcp (preferred) and official Figma MCP server (fallback). Auto-detection picks the best available transport.
|
|
17
|
+
- **Express mode**: `/design-workflow quick` skips formal spec, generates from brief description with 2 questions max. Same DS quality guarantees.
|
|
18
|
+
- **Plugin packaging**: `.claude-plugin/plugin.json` and `.cursor-plugin/plugin.json` for marketplace distribution.
|
|
19
|
+
- **Transport adapter**: `transport-adapter.md` — central reference for tool mapping, script adaptation, and composite DS extraction.
|
|
20
|
+
- **Rule 23**: Transport-aware scripting in `figma-api-rules.md` (IIFE vs top-level await, official transport constraints).
|
|
21
|
+
- **KB path resolution**: `./bridge-ds/` (plugin mode) or `.claude/skills/` (npm scaffold mode).
|
|
22
|
+
- **`.mcp.json`**: MCP server dependency declaration for plugin installs.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- `mcp-setup.js`: Returns `{ console, official }` instead of boolean.
|
|
26
|
+
- `cli.js`: Reports both transports during init, offers dual setup instructions.
|
|
27
|
+
- `onboarding.md`: Dual transport detection + composite DS extraction for official transport.
|
|
28
|
+
- `quality-gates.md`: Quick mode section with relaxed gates (pattern matching best-effort, no formal spec/review).
|
|
29
|
+
- 6 schema files updated with transport notes.
|
|
30
|
+
- `package.json`: Bumped to v2.5.0, added plugin manifests to `files`.
|
|
31
|
+
|
|
32
|
+
## [2.4.1] — 2026-03-20
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- **review.md**: Sections F (Component API Quality) and G (Learning Opportunity) were in wrong order
|
|
36
|
+
- **CLI help**: Added missing `drop`, `learn`, `sync`, `status` slash commands
|
|
37
|
+
- **README.md**: Added missing `learn` and `sync` commands to table; updated workflow diagram with learning loop
|
|
38
|
+
- **design.md**: Fixed incorrect absolute path to knowledge base (now relative `references/knowledge-base/`)
|
|
39
|
+
- **done.md**: Added `Learnings: {n} persisted` to output template
|
|
40
|
+
- **scaffold.js**: Added `learnings.json` to `.gitignore` entries; `update()` now preserves `learnings.json`
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **Templates**: "Known Preferences" section in both `screen-template.md` and `spec-template.md`
|
|
44
|
+
- **CHANGELOG.md**: This file
|
|
45
|
+
|
|
46
|
+
## [2.4.0] — 2026-03-19
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
- Learning loop: `learn` action diffs Figma corrections against generation snapshot, extracts reusable preferences
|
|
50
|
+
- Incremental DS sync: `sync` action updates registries without full re-setup
|
|
51
|
+
- `status` action shows current workflow state and suggests next step
|
|
52
|
+
- `drop` action abandons work with preserved learnings
|
|
53
|
+
- Snapshot capture after design generation for learn diffing
|
|
54
|
+
|
|
55
|
+
## [2.3.0] — 2026-03-18
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- Screen generation with reference inspection and clone-first strategy
|
|
59
|
+
- Auto-enrichment of specs from knowledge base
|
|
60
|
+
- Visual reference pattern matching (blocking gate)
|
|
61
|
+
|
|
62
|
+
## [2.2.0] — 2026-03-17
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
- `update` command to preserve knowledge base on upgrades
|
|
66
|
+
- Interactive MCP setup during `init`
|
|
67
|
+
|
|
68
|
+
## [2.1.0] — 2026-03-16
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- Registry schemas and validation for setup
|
|
72
|
+
- Validation gate before design generation
|
|
73
|
+
|
|
74
|
+
## [2.0.1] — 2026-03-15
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
- Strengthened pre-script audit
|
|
78
|
+
- Added Rule 20 (setTextStyleIdAsync)
|
|
79
|
+
|
|
80
|
+
## [2.0.0] — 2026-03-14
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
- Complete rewrite: MCP-powered design workflow via figma-console-mcp
|
|
84
|
+
- Spec-first architecture with atomic generation
|
|
85
|
+
- Knowledge base system (registries, guides, patterns)
|
|
86
|
+
- DS-native generation (zero hardcoded values)
|
|
87
|
+
|
|
88
|
+
## [1.0.0] — 2026-03-12
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
- Initial release: Bridge for Claude Code
|
|
92
|
+
- CLI with `init` command
|
|
93
|
+
- Design workflow skill scaffold
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Bridge DS — Claude Code Instructions
|
|
2
|
+
|
|
3
|
+
Bridge DS is an AI-powered design workflow that generates Figma designs using your real design system. It supports two MCP transports: [figma-console-mcp](https://github.com/southleft/figma-console-mcp) (preferred) and the official Figma MCP server (fallback).
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Claude Code ──MCP──> figma-console-mcp ──WebSocket──> Figma Desktop (local, preferred)
|
|
9
|
+
Claude Code ──MCP──> Figma MCP Server ──Cloud──> Figma Cloud (official, fallback)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
All Figma operations use MCP tools — no custom server, no HTTP calls, no curl. See `skills/design-workflow/references/transport-adapter.md` for transport detection and tool mapping.
|
|
13
|
+
|
|
14
|
+
## Key MCP Tools
|
|
15
|
+
|
|
16
|
+
Tools vary by transport. See `references/transport-adapter.md` for the full mapping.
|
|
17
|
+
|
|
18
|
+
| Operation | Console transport | Official transport |
|
|
19
|
+
|-----------|------------------|--------------------|
|
|
20
|
+
| Execute Plugin API code | `figma_execute` | `use_figma` |
|
|
21
|
+
| Take screenshot | `figma_take_screenshot` | `get_screenshot` |
|
|
22
|
+
| Full DS extraction | `figma_get_design_system_kit` | Composite (see transport-adapter.md) |
|
|
23
|
+
| Get variables | `figma_get_variables` | `get_variable_defs` |
|
|
24
|
+
| Get styles | `figma_get_styles` | `search_design_system` |
|
|
25
|
+
| Search components | `figma_search_components` | `search_design_system` |
|
|
26
|
+
| Connection check | `figma_get_status` | `whoami` |
|
|
27
|
+
|
|
28
|
+
## Script Structure
|
|
29
|
+
|
|
30
|
+
Script format depends on the active transport. See `references/transport-adapter.md` Section C for full rules.
|
|
31
|
+
|
|
32
|
+
**Console transport (figma_execute) — IIFE wrapper mandatory:**
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
return (async function() {
|
|
36
|
+
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
|
|
37
|
+
// ... Plugin API code ...
|
|
38
|
+
return { success: true };
|
|
39
|
+
})();
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Official transport (use_figma) — top-level await, no IIFE:**
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
|
|
46
|
+
// ... Plugin API code ...
|
|
47
|
+
return { success: true };
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Called as: `use_figma({ fileKey: "...", description: "...", code: "..." })`
|
|
51
|
+
|
|
52
|
+
## Critical Figma API Rules
|
|
53
|
+
|
|
54
|
+
Full rules: `skills/design-workflow/references/figma-api-rules.md`
|
|
55
|
+
|
|
56
|
+
**Top 5 (most common bugs):**
|
|
57
|
+
|
|
58
|
+
1. **FILL after appendChild** — Set `layoutSizingHorizontal = "FILL"` AFTER `parent.appendChild(child)`, never before
|
|
59
|
+
2. **resize() overrides sizing** — Call `resize()` FIRST, then set `primaryAxisSizingMode`
|
|
60
|
+
3. **Colors via setBoundVariableForPaint** — Not `setBoundVariable` (different API for fills/strokes)
|
|
61
|
+
4. **textAutoResize after width** — Set characters → append → FILL → then `textAutoResize = "HEIGHT"`
|
|
62
|
+
5. **DS component reuse** — NEVER recreate existing components as raw frames. Always import via `importComponentByKeyAsync`
|
|
63
|
+
|
|
64
|
+
## Helpers
|
|
65
|
+
|
|
66
|
+
Helpers (`mf`, `appendFill`, `bindPadding`, `bindRadius`) and the standard script boilerplate are defined in `skills/design-workflow/references/figma-api-rules.md` (Standard Script Boilerplate section). Always copy them from there.
|
|
67
|
+
|
|
68
|
+
## Design Workflow
|
|
69
|
+
|
|
70
|
+
The `/design-workflow` skill handles everything:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
/design-workflow setup → Extract DS + build knowledge base
|
|
74
|
+
/design-workflow spec → Write component or screen specification
|
|
75
|
+
/design-workflow design → Generate in Figma (atomic, verified)
|
|
76
|
+
/design-workflow review → Validate against spec + tokens
|
|
77
|
+
/design-workflow done → Archive and ship
|
|
78
|
+
/design-workflow drop → Abandon with preserved learnings
|
|
79
|
+
/design-workflow learn → Diff design vs corrections, extract learnings
|
|
80
|
+
/design-workflow sync → Incremental DS sync (no full re-setup)
|
|
81
|
+
/design-workflow status → Show current state, suggest next
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Read `skills/design-workflow/SKILL.md` for the full workflow definition.
|
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@ Bridge turns [Claude Code](https://claude.ai/download) into a designer that know
|
|
|
8
8
|
You describe what you want
|
|
9
9
|
→ Claude consults the knowledge base (your DS, documented)
|
|
10
10
|
→ Claude writes the spec (exact components, tokens, layout)
|
|
11
|
-
→ Claude generates in Figma
|
|
11
|
+
→ Claude generates in Figma (real DS components, bound variables)
|
|
12
12
|
→ You review in Figma
|
|
13
|
+
→ Claude learns from your corrections (and improves next time)
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
## How it works
|
|
@@ -19,21 +20,23 @@ Bridge is two things:
|
|
|
19
20
|
1. **A CLI** (`bridge-ds init`) that scaffolds your project with the design workflow skill
|
|
20
21
|
2. **A Claude Code skill** (`/design-workflow`) that handles the intelligence — spec writing, DS knowledge, Figma generation
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
Bridge supports two MCP transports:
|
|
23
24
|
|
|
24
25
|
```
|
|
25
|
-
Claude Code ──MCP──> figma-console-mcp ──WebSocket──> Figma Desktop
|
|
26
|
-
|
|
27
|
-
real components,
|
|
28
|
-
bound variables)
|
|
26
|
+
Claude Code ──MCP──> figma-console-mcp ──WebSocket──> Figma Desktop (preferred)
|
|
27
|
+
Claude Code ──MCP──> Figma MCP Server ──Cloud──> Figma Cloud (official, fallback)
|
|
29
28
|
```
|
|
30
29
|
|
|
30
|
+
Auto-detection picks the best available transport. See [transport-adapter.md](skills/design-workflow/references/transport-adapter.md) for details.
|
|
31
|
+
|
|
31
32
|
## Prerequisites
|
|
32
33
|
|
|
33
34
|
- [Claude Code](https://claude.ai/download) installed
|
|
34
35
|
- [Node.js 18+](https://nodejs.org)
|
|
35
|
-
- [Figma Desktop](https://www.figma.com/downloads/) (not the web app)
|
|
36
36
|
- A Figma file with a published design system library
|
|
37
|
+
- One of:
|
|
38
|
+
- [figma-console-mcp](https://github.com/southleft/figma-console-mcp) + [Figma Desktop](https://www.figma.com/downloads/) (recommended, full capabilities)
|
|
39
|
+
- Official Figma MCP server (simpler setup, cloud-based)
|
|
37
40
|
|
|
38
41
|
## Quick Start
|
|
39
42
|
|
|
@@ -97,11 +100,16 @@ Claude consults the knowledge base, identifies the right pattern, components, an
|
|
|
97
100
|
## The Workflow
|
|
98
101
|
|
|
99
102
|
```
|
|
100
|
-
setup (once) → spec → design → review
|
|
101
|
-
↑ |
|
|
102
|
-
└── iterate ─────────┘
|
|
103
|
+
setup (once) → spec → design → review ──→ done
|
|
104
|
+
↑ | |
|
|
105
|
+
└── iterate ─────────┘ learn ←┘
|
|
106
|
+
(diff corrections,
|
|
107
|
+
extract preferences)
|
|
103
108
|
```
|
|
104
109
|
|
|
110
|
+
### Express mode
|
|
111
|
+
For quick iterations, skip the formal spec: `/design-workflow quick "a settings page"`. 2 questions max, inline mini-spec, same DS quality guarantees.
|
|
112
|
+
|
|
105
113
|
### Spec-first
|
|
106
114
|
No design without a validated specification. Claude knows exactly which components, tokens, and layout patterns to use because it has your DS documented.
|
|
107
115
|
|
|
@@ -137,11 +145,18 @@ knowledge-base/
|
|
|
137
145
|
| `/design-workflow setup` | Extract DS + build knowledge base |
|
|
138
146
|
| `/design-workflow spec {name}` | Write a component or screen spec |
|
|
139
147
|
| `/design-workflow design` | Generate in Figma from active spec |
|
|
148
|
+
| `/design-workflow quick {description}` | Express generation — skip spec, generate directly |
|
|
140
149
|
| `/design-workflow review` | Validate design against spec + tokens |
|
|
141
150
|
| `/design-workflow done` | Archive spec and ship |
|
|
142
151
|
| `/design-workflow drop` | Abandon with preserved learnings |
|
|
152
|
+
| `/design-workflow learn` | Diff corrections, extract learnings |
|
|
153
|
+
| `/design-workflow sync` | Incremental DS sync (no full re-setup) |
|
|
143
154
|
| `/design-workflow status` | Show current state, suggest next action |
|
|
144
155
|
|
|
156
|
+
## Author
|
|
157
|
+
|
|
158
|
+
Built by [Noé Chagué](https://www.linkedin.com/in/noechague/) — Design System @ [Finary](https://finary.com)
|
|
159
|
+
|
|
145
160
|
## License
|
|
146
161
|
|
|
147
162
|
MIT
|
package/lib/cli.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
2
4
|
const { scaffold, update } = require('./scaffold');
|
|
3
|
-
const { checkMcp
|
|
5
|
+
const { checkMcp } = require('./mcp-setup');
|
|
4
6
|
|
|
5
|
-
// ──
|
|
7
|
+
// ── Formatting ───────────────────────────────────────────
|
|
6
8
|
const C = {
|
|
7
9
|
reset: '\x1b[0m',
|
|
8
10
|
bold: '\x1b[1m',
|
|
@@ -12,162 +14,145 @@ const C = {
|
|
|
12
14
|
red: '\x1b[38;2;244;67;54m',
|
|
13
15
|
yellow: '\x1b[38;2;255;193;7m',
|
|
14
16
|
gray: '\x1b[38;2;158;158;158m',
|
|
15
|
-
white: '\x1b[38;2;255;255;255m',
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
function print(msg = '') { process.stdout.write(msg + '\n'); }
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// ── Spinner ───────────────────────────────────────────────
|
|
28
|
-
const FRAMES = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
|
|
29
|
-
class Spinner {
|
|
30
|
-
constructor(msg) { this.msg = msg; this.i = 0; this.id = null; }
|
|
31
|
-
start() {
|
|
32
|
-
this.id = setInterval(() => {
|
|
33
|
-
process.stdout.write(`\r${C.orange} ${FRAMES[this.i++ % FRAMES.length]}${C.reset} ${this.msg}`);
|
|
34
|
-
}, 80);
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
|
-
stop(result) {
|
|
38
|
-
clearInterval(this.id);
|
|
39
|
-
process.stdout.write('\r' + ' '.repeat(this.msg.length + 10) + '\r');
|
|
40
|
-
if (result) success(result);
|
|
41
|
-
}
|
|
20
|
+
function ok(msg) { print(` ${C.green}✓${C.reset} ${msg}`); }
|
|
21
|
+
function fail(msg) { print(` ${C.red}✗${C.reset} ${msg}`); }
|
|
22
|
+
function warn(msg) { print(` ${C.yellow}!${C.reset} ${msg}`); }
|
|
23
|
+
function dim(msg) { print(` ${C.dim}${msg}${C.reset}`); }
|
|
24
|
+
|
|
25
|
+
function brand() {
|
|
26
|
+
const pkg = require('../package.json');
|
|
27
|
+
print(`\n ${C.orange}${C.bold}Bridge DS${C.reset} ${C.dim}v${pkg.version}${C.reset}\n`);
|
|
42
28
|
}
|
|
43
29
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
print('');
|
|
30
|
+
function ask(question) {
|
|
31
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
rl.question(` ${question} `, (answer) => {
|
|
34
|
+
rl.close();
|
|
35
|
+
resolve(answer.trim());
|
|
36
|
+
});
|
|
37
|
+
});
|
|
53
38
|
}
|
|
54
39
|
|
|
55
|
-
// ── Commands
|
|
40
|
+
// ── Commands ─────────────────────────────────────────────
|
|
56
41
|
|
|
57
42
|
async function cmdInit() {
|
|
58
|
-
|
|
59
|
-
header('Initializing Bridge DS');
|
|
43
|
+
brand();
|
|
60
44
|
|
|
61
45
|
const cwd = process.cwd();
|
|
62
|
-
const totalSteps = 4;
|
|
63
46
|
|
|
64
|
-
//
|
|
65
|
-
step(1, totalSteps, 'Checking prerequisites');
|
|
47
|
+
// 1. Prerequisites
|
|
66
48
|
const nodeVersion = process.version.replace('v', '').split('.').map(Number);
|
|
67
49
|
if (nodeVersion[0] < 18) {
|
|
68
|
-
|
|
50
|
+
fail(`Node.js 18+ required (found ${process.version})`);
|
|
69
51
|
process.exit(1);
|
|
70
52
|
}
|
|
71
|
-
|
|
53
|
+
ok(`Node.js ${process.version}`);
|
|
72
54
|
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
// 2. Figma MCP transport
|
|
56
|
+
const mcp = checkMcp();
|
|
57
|
+
let mcpReady = mcp.console || mcp.official;
|
|
58
|
+
|
|
59
|
+
if (mcp.console) {
|
|
60
|
+
ok('figma-console-mcp detected (preferred transport)');
|
|
61
|
+
}
|
|
62
|
+
if (mcp.official) {
|
|
63
|
+
ok('Official Figma MCP detected' + (mcp.console ? ' (fallback)' : ''));
|
|
64
|
+
if (!mcp.console) {
|
|
65
|
+
dim('figma-console-mcp is recommended for full capabilities but official MCP works too');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!mcpReady) {
|
|
70
|
+
warn('No Figma MCP transport configured');
|
|
71
|
+
print('');
|
|
72
|
+
dim('Bridge supports two transports:');
|
|
73
|
+
dim(' A) figma-console-mcp (recommended, full Plugin API access)');
|
|
74
|
+
dim(' B) Official Figma MCP (cloud-based, cross-library search)');
|
|
81
75
|
print('');
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
print(`${C.dim} -- npx -y figma-console-mcp@latest${C.reset}`);
|
|
76
|
+
dim('For option A, you need a Personal Access Token from Figma:');
|
|
77
|
+
dim('https://www.figma.com/developers/api#access-tokens');
|
|
85
78
|
print('');
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
|
|
80
|
+
const token = await ask(`${C.bold}Figma token${C.reset} (figd_...) for figma-console-mcp, or Enter to skip:`);
|
|
81
|
+
|
|
82
|
+
if (token && token.startsWith('figd_')) {
|
|
83
|
+
try {
|
|
84
|
+
execSync(
|
|
85
|
+
`claude mcp add figma-console -s user -e FIGMA_ACCESS_TOKEN=${token} -- npx -y figma-console-mcp@latest`,
|
|
86
|
+
{ stdio: 'pipe' }
|
|
87
|
+
);
|
|
88
|
+
ok('figma-console-mcp configured');
|
|
89
|
+
mcpReady = true;
|
|
90
|
+
} catch (e) {
|
|
91
|
+
fail('Could not configure MCP automatically');
|
|
92
|
+
dim('Run manually:');
|
|
93
|
+
dim(`claude mcp add figma-console -s user -e FIGMA_ACCESS_TOKEN=${token} -- npx -y figma-console-mcp@latest`);
|
|
94
|
+
}
|
|
95
|
+
} else if (token) {
|
|
96
|
+
warn('Token should start with figd_ — skipping MCP setup');
|
|
97
|
+
dim('You can configure it later:');
|
|
98
|
+
dim('claude mcp add figma-console -s user -e FIGMA_ACCESS_TOKEN=<token> -- npx -y figma-console-mcp@latest');
|
|
99
|
+
} else {
|
|
100
|
+
dim('Skipped. You can configure either transport later.');
|
|
101
|
+
dim('Console: claude mcp add figma-console -s user -e FIGMA_ACCESS_TOKEN=<token> -- npx -y figma-console-mcp@latest');
|
|
102
|
+
dim('Official: Configure via Claude settings or Figma MCP integration.');
|
|
103
|
+
}
|
|
88
104
|
}
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
step(3, totalSteps, 'Scaffolding project files');
|
|
92
|
-
const spinner = new Spinner('Copying skills, commands, templates...').start();
|
|
93
|
-
const result = scaffold(cwd);
|
|
94
|
-
spinner.stop('Project files created');
|
|
106
|
+
print('');
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
108
|
+
// 3. Scaffold
|
|
109
|
+
const result = scaffold(cwd);
|
|
110
|
+
ok(`${result.created.length} files scaffolded`);
|
|
99
111
|
|
|
100
|
-
//
|
|
101
|
-
step(4, totalSteps, 'Done!');
|
|
112
|
+
// 4. Summary
|
|
102
113
|
print('');
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
print(`${C.orange}${C.bold} │ 2. Run: /design-workflow setup │${C.reset}`);
|
|
109
|
-
print(`${C.orange}${C.bold} │ → Extracts & documents your DS │${C.reset}`);
|
|
110
|
-
print(`${C.orange}${C.bold} │ 3. Run: /design-workflow spec ... │${C.reset}`);
|
|
111
|
-
print(`${C.orange}${C.bold} │ → Start designing! │${C.reset}`);
|
|
112
|
-
print(`${C.orange}${C.bold} └──────────────────────────────────────┘${C.reset}`);
|
|
114
|
+
if (mcpReady) {
|
|
115
|
+
ok(`${C.bold}Ready!${C.reset} Open Claude Code and run: ${C.orange}/design-workflow setup${C.reset}`);
|
|
116
|
+
} else {
|
|
117
|
+
warn(`${C.bold}Almost ready.${C.reset} Configure figma-console-mcp, then run: ${C.orange}/design-workflow setup${C.reset}`);
|
|
118
|
+
}
|
|
113
119
|
print('');
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
async function cmdUpdate() {
|
|
117
|
-
|
|
118
|
-
header('Updating Bridge DS skill files');
|
|
123
|
+
brand();
|
|
119
124
|
|
|
120
125
|
const cwd = process.cwd();
|
|
121
|
-
|
|
122
|
-
step(1, 2, 'Updating skill files');
|
|
123
|
-
const spinner = new Spinner('Updating SKILL.md, actions, rules, schemas, templates...').start();
|
|
124
126
|
const result = update(cwd);
|
|
125
127
|
|
|
126
128
|
if (result.error) {
|
|
127
|
-
|
|
128
|
-
error(result.error);
|
|
129
|
+
fail(result.error);
|
|
129
130
|
process.exit(1);
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
for (const f of result.updated) {
|
|
135
|
-
muted(f);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
step(2, 2, 'Done!');
|
|
139
|
-
print('');
|
|
140
|
-
success('Skill files updated. Your knowledge base (registries, guides) was preserved.');
|
|
141
|
-
info('No need to re-run /design-workflow setup.');
|
|
133
|
+
ok(`${result.updated.length} files updated`);
|
|
134
|
+
dim('Knowledge base preserved (registries, guides, screenshots)');
|
|
142
135
|
print('');
|
|
143
136
|
}
|
|
144
137
|
|
|
145
138
|
function cmdHelp() {
|
|
146
|
-
|
|
147
|
-
print(
|
|
148
|
-
print(
|
|
149
|
-
print(` ${C.orange}
|
|
150
|
-
print(`
|
|
151
|
-
print('');
|
|
152
|
-
print(` ${C.orange}update${C.reset} Update skill files to latest version`);
|
|
153
|
-
print(` Preserves your knowledge base (registries, guides)`);
|
|
154
|
-
print('');
|
|
155
|
-
print(` ${C.orange}help${C.reset} Show this help message`);
|
|
139
|
+
brand();
|
|
140
|
+
print(` ${C.bold}Commands${C.reset}`);
|
|
141
|
+
print(` ${C.orange}init${C.reset} Set up Bridge DS in the current project`);
|
|
142
|
+
print(` ${C.orange}update${C.reset} Update skill files (preserves knowledge base)`);
|
|
143
|
+
print(` ${C.orange}help${C.reset} Show this help`);
|
|
156
144
|
print(` ${C.orange}version${C.reset} Show version`);
|
|
157
145
|
print('');
|
|
158
|
-
print(
|
|
159
|
-
print(
|
|
160
|
-
print(` ${C.dim}
|
|
161
|
-
print(` ${C.dim}
|
|
162
|
-
print(` ${C.dim}
|
|
163
|
-
print(
|
|
164
|
-
print(
|
|
165
|
-
print(
|
|
166
|
-
print(` ${C.dim}/design-workflow
|
|
167
|
-
print(` ${C.dim}/design-workflow
|
|
168
|
-
print(` ${C.dim}/design-workflow design${C.reset} # Generate in Figma`);
|
|
169
|
-
print(` ${C.dim}/design-workflow review${C.reset} # Validate against spec`);
|
|
170
|
-
print(` ${C.dim}/design-workflow done${C.reset} # Archive & ship`);
|
|
146
|
+
print(` ${C.bold}After init${C.reset}`);
|
|
147
|
+
print(` ${C.dim}/design-workflow setup${C.reset} Extract your design system`);
|
|
148
|
+
print(` ${C.dim}/design-workflow spec${C.reset} Spec a component or screen`);
|
|
149
|
+
print(` ${C.dim}/design-workflow design${C.reset} Generate in Figma`);
|
|
150
|
+
print(` ${C.dim}/design-workflow review${C.reset} Validate against spec`);
|
|
151
|
+
print(` ${C.dim}/design-workflow done${C.reset} Archive & ship`);
|
|
152
|
+
print(` ${C.dim}/design-workflow drop${C.reset} Abandon with preserved learnings`);
|
|
153
|
+
print(` ${C.dim}/design-workflow learn${C.reset} Diff corrections, extract learnings`);
|
|
154
|
+
print(` ${C.dim}/design-workflow sync${C.reset} Incremental DS sync`);
|
|
155
|
+
print(` ${C.dim}/design-workflow status${C.reset} Show current state, suggest next`);
|
|
171
156
|
print('');
|
|
172
157
|
}
|
|
173
158
|
|
|
@@ -176,30 +161,18 @@ function cmdVersion() {
|
|
|
176
161
|
print(`bridge-ds v${pkg.version}`);
|
|
177
162
|
}
|
|
178
163
|
|
|
179
|
-
// ── Router
|
|
164
|
+
// ── Router ───────────────────────────────────────────────
|
|
180
165
|
|
|
181
166
|
async function run(args) {
|
|
182
167
|
const cmd = args[0] || 'help';
|
|
183
168
|
|
|
184
169
|
switch (cmd) {
|
|
185
|
-
case 'init':
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
case '
|
|
189
|
-
await cmdUpdate();
|
|
190
|
-
break;
|
|
191
|
-
case 'help':
|
|
192
|
-
case '--help':
|
|
193
|
-
case '-h':
|
|
194
|
-
cmdHelp();
|
|
195
|
-
break;
|
|
196
|
-
case 'version':
|
|
197
|
-
case '--version':
|
|
198
|
-
case '-v':
|
|
199
|
-
cmdVersion();
|
|
200
|
-
break;
|
|
170
|
+
case 'init': return cmdInit();
|
|
171
|
+
case 'update': return cmdUpdate();
|
|
172
|
+
case 'help': case '--help': case '-h': return cmdHelp();
|
|
173
|
+
case 'version': case '--version': case '-v': return cmdVersion();
|
|
201
174
|
default:
|
|
202
|
-
|
|
175
|
+
fail(`Unknown command: ${cmd}`);
|
|
203
176
|
cmdHelp();
|
|
204
177
|
process.exit(1);
|
|
205
178
|
}
|