@spaced-out/ui-design-system 0.5.20 → 0.5.22
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/CHANGELOG.md +20 -0
- package/lib/components/Checklist/Checklist.d.ts +2 -1
- package/lib/components/Checklist/Checklist.d.ts.map +1 -1
- package/lib/components/Checklist/Checklist.js +4 -3
- package/mcp/README.md +278 -58
- package/mcp/build-mcp-data.js +162 -8
- package/mcp/index.js +709 -1
- package/mcp/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.5.22](https://github.com/spaced-out/ui-design-system/compare/v0.5.21...v0.5.22) (2025-11-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* add context aware results and utils and types info ([#431](https://github.com/spaced-out/ui-design-system/issues/431)) ([743fecf](https://github.com/spaced-out/ui-design-system/commit/743fecf93625edd13800e345c408343eff773748))
|
|
11
|
+
|
|
12
|
+
### [0.5.21](https://github.com/spaced-out/ui-design-system/compare/v0.5.20...v0.5.21) (2025-11-12)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add figma section to mcp documentation in storybook ([#429](https://github.com/spaced-out/ui-design-system/issues/429)) ([7a45eaf](https://github.com/spaced-out/ui-design-system/commit/7a45eaf4504541009f450b2f43adb169be40c0e7))
|
|
18
|
+
* add mcp documentation to storybook ([#428](https://github.com/spaced-out/ui-design-system/issues/428)) ([4f9af69](https://github.com/spaced-out/ui-design-system/commit/4f9af692a9a110e3b00aab0e17946db52d459e0b))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* hide footer conditionally for checklist component ([#430](https://github.com/spaced-out/ui-design-system/issues/430)) ([2d76761](https://github.com/spaced-out/ui-design-system/commit/2d76761fabceda767300e812787d63cbf1522b17))
|
|
24
|
+
|
|
5
25
|
### [0.5.20](https://github.com/spaced-out/ui-design-system/compare/v0.5.19...v0.5.20) (2025-11-11)
|
|
6
26
|
|
|
7
27
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { ColorTypes } from '../../types/typography';
|
|
3
|
-
import type { IconType } from '../../components/Icon';
|
|
3
|
+
import type { IconSize, IconType } from '../../components/Icon';
|
|
4
4
|
type ClassNames = Readonly<{
|
|
5
5
|
header?: string;
|
|
6
6
|
wrapper?: string;
|
|
@@ -14,6 +14,7 @@ export interface ChecklistItem {
|
|
|
14
14
|
iconLeftName?: string;
|
|
15
15
|
iconLeftType?: IconType;
|
|
16
16
|
iconLeftColor?: ColorTypes;
|
|
17
|
+
iconLeftSize?: IconSize;
|
|
17
18
|
disabled?: boolean;
|
|
18
19
|
rightSlot?: React.ReactNode;
|
|
19
20
|
onExpand?: (item: ChecklistItem) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checklist.d.ts","sourceRoot":"","sources":["../../../src/components/Checklist/Checklist.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"Checklist.d.ts","sourceRoot":"","sources":["../../../src/components/Checklist/Checklist.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAS5D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAChC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,oBAAoB,kGAiB/B,CAAC;AAEH,eAAO,MAAM,SAAS,uFAyHrB,CAAC"}
|
|
@@ -113,7 +113,8 @@ const Checklist = exports.Checklist = /*#__PURE__*/React.forwardRef((_ref2, ref)
|
|
|
113
113
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
|
|
114
114
|
name: item.iconLeftName || '',
|
|
115
115
|
type: item.iconLeftType,
|
|
116
|
-
color: item.iconLeftColor || 'tertiary'
|
|
116
|
+
color: item.iconLeftColor || 'tertiary',
|
|
117
|
+
size: item.iconLeftSize || 'small'
|
|
117
118
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.BodyMedium, {
|
|
118
119
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_TruncatedTextWithTooltip.TruncatedTextWithTooltip, {
|
|
119
120
|
tooltip: {
|
|
@@ -136,9 +137,9 @@ const Checklist = exports.Checklist = /*#__PURE__*/React.forwardRef((_ref2, ref)
|
|
|
136
137
|
}) : null
|
|
137
138
|
})]
|
|
138
139
|
}))
|
|
139
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Card.CardFooter, {
|
|
140
|
+
}), footer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Card.CardFooter, {
|
|
140
141
|
children: footer
|
|
141
|
-
})]
|
|
142
|
+
}) : null]
|
|
142
143
|
})
|
|
143
144
|
})]
|
|
144
145
|
});
|
package/mcp/README.md
CHANGED
|
@@ -19,96 +19,73 @@ Unlike traditional MCP servers that require a local copy of the design system, t
|
|
|
19
19
|
|
|
20
20
|
### With Cursor
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
⚠️ **macOS Users**: Cursor may not find `npx` in its PATH. Use the full path instead.
|
|
23
|
+
|
|
24
|
+
1. Find your `npx` path in terminal:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
which npx
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
2. Add to your Cursor MCP settings with the **full path**:
|
|
23
31
|
|
|
24
32
|
```json
|
|
25
33
|
{
|
|
26
34
|
"mcpServers": {
|
|
27
35
|
"genesis-design-system": {
|
|
28
|
-
"command": "npx",
|
|
36
|
+
"command": "/opt/homebrew/bin/npx",
|
|
29
37
|
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
}
|
|
33
41
|
```
|
|
34
42
|
|
|
43
|
+
**Common npx locations:**
|
|
44
|
+
|
|
45
|
+
- Apple Silicon Mac (Homebrew): `/opt/homebrew/bin/npx`
|
|
46
|
+
- Intel Mac (Homebrew): `/usr/local/bin/npx`
|
|
47
|
+
- nvm users: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
48
|
+
|
|
49
|
+
**Windows/Linux users** can typically use `"command": "npx"` directly.
|
|
50
|
+
|
|
35
51
|
### With Claude Desktop
|
|
36
52
|
|
|
53
|
+
⚠️ **macOS Users**: Claude Desktop may not find `npx` in its PATH. Use the full path instead.
|
|
54
|
+
|
|
37
55
|
Add to your Claude config file:
|
|
38
56
|
|
|
39
57
|
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
40
58
|
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
41
59
|
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
42
60
|
|
|
61
|
+
1. Find your `npx` path in terminal:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
which npx
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. Use the **full path** in your config:
|
|
68
|
+
|
|
43
69
|
```json
|
|
44
70
|
{
|
|
45
71
|
"mcpServers": {
|
|
46
72
|
"genesis-design-system": {
|
|
47
|
-
"command": "npx",
|
|
73
|
+
"command": "/opt/homebrew/bin/npx",
|
|
48
74
|
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
49
75
|
}
|
|
50
76
|
}
|
|
51
77
|
}
|
|
52
78
|
```
|
|
53
79
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
## 💬 Usage Examples
|
|
57
|
-
|
|
58
|
-
Once configured, you can ask:
|
|
59
|
-
|
|
60
|
-
**Component Discovery:**
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
"List all components in Genesis"
|
|
64
|
-
"Search for dropdown components"
|
|
65
|
-
"Show me the Button component implementation"
|
|
66
|
-
"What types does the Icon component export?"
|
|
67
|
-
"Show me the Icon component with its exported types"
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Design Tokens:**
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
"Show me all color tokens"
|
|
74
|
-
"What spacing tokens are available?"
|
|
75
|
-
"List all shadow/elevation tokens"
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**Component Onboarding:**
|
|
80
|
+
**Common npx locations:**
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"What's the standard structure for a Genesis component?"
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**Design Token Imports:**
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
"How do I import design tokens in CSS Module files?"
|
|
90
|
-
"Show me the correct way to import color and spacing tokens"
|
|
91
|
-
"What token files are available and how do I import them?"
|
|
92
|
-
```
|
|
82
|
+
- Apple Silicon Mac (Homebrew): `/opt/homebrew/bin/npx`
|
|
83
|
+
- Intel Mac (Homebrew): `/usr/local/bin/npx`
|
|
84
|
+
- nvm users: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
93
85
|
|
|
94
|
-
**
|
|
86
|
+
**Windows/Linux users** can typically use `"command": "npx"` directly.
|
|
95
87
|
|
|
96
|
-
|
|
97
|
-
"Show me CSS Module styling guidelines for Genesis"
|
|
98
|
-
"What are the class naming conventions for CSS Modules?"
|
|
99
|
-
"How should I style child elements in CSS Modules?"
|
|
100
|
-
"What's the correct pattern for state-based styling in CSS?"
|
|
101
|
-
"Show me common CSS mistakes to avoid"
|
|
102
|
-
"How do I apply colors to child elements like text, icons, or buttons?"
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**Dependencies:**
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
"What components does Modal depend on?"
|
|
109
|
-
"Show me the dependencies of Dropdown"
|
|
110
|
-
"What hooks does the Table component use?"
|
|
111
|
-
```
|
|
88
|
+
Then restart Cursor or Claude Desktop.
|
|
112
89
|
|
|
113
90
|
## 🔧 Development
|
|
114
91
|
|
|
@@ -284,6 +261,153 @@ npm config set @spaced-out:registry https://your-private-registry.com
|
|
|
284
261
|
yarn config set registry https://your-private-registry.com
|
|
285
262
|
```
|
|
286
263
|
|
|
264
|
+
## 🐛 Troubleshooting
|
|
265
|
+
|
|
266
|
+
### "spawn npx ENOENT" Error (macOS/Windows)
|
|
267
|
+
|
|
268
|
+
**Symptoms:**
|
|
269
|
+
|
|
270
|
+
- Cursor or Claude Desktop logs show `spawn npx ENOENT` error
|
|
271
|
+
- MCP server fails to start with connection errors
|
|
272
|
+
- Error message: `Server transport closed unexpectedly`
|
|
273
|
+
|
|
274
|
+
**Cause:**
|
|
275
|
+
GUI applications on macOS and Windows don't inherit your terminal's PATH environment variables, so they cannot find the `npx` command.
|
|
276
|
+
|
|
277
|
+
**Solution:**
|
|
278
|
+
|
|
279
|
+
1. Find your `npx` path in terminal:
|
|
280
|
+
|
|
281
|
+
**macOS/Linux:**
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
which npx
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Windows (PowerShell):**
|
|
288
|
+
|
|
289
|
+
```powershell
|
|
290
|
+
where.exe npx
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
2. Use the **full path** in your MCP configuration instead of just `"command": "npx"`:
|
|
294
|
+
|
|
295
|
+
**Example (macOS):**
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"mcpServers": {
|
|
300
|
+
"genesis-design-system": {
|
|
301
|
+
"command": "/opt/homebrew/bin/npx",
|
|
302
|
+
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Example (Windows):**
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"mcpServers": {
|
|
313
|
+
"genesis-design-system": {
|
|
314
|
+
"command": "C:\\Program Files\\nodejs\\npx.cmd",
|
|
315
|
+
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Common npx locations:**
|
|
322
|
+
|
|
323
|
+
**macOS:**
|
|
324
|
+
|
|
325
|
+
- Homebrew (Apple Silicon): `/opt/homebrew/bin/npx`
|
|
326
|
+
- Homebrew (Intel): `/usr/local/bin/npx`
|
|
327
|
+
- nvm: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
328
|
+
|
|
329
|
+
**Windows:**
|
|
330
|
+
|
|
331
|
+
- Default Node.js: `C:\Program Files\nodejs\npx.cmd`
|
|
332
|
+
- nvm-windows: `C:\Users\YOUR_USERNAME\AppData\Roaming\nvm\vX.X.X\npx.cmd`
|
|
333
|
+
|
|
334
|
+
**Linux:**
|
|
335
|
+
|
|
336
|
+
- Most distributions: `/usr/bin/npx` or `/usr/local/bin/npx`
|
|
337
|
+
|
|
338
|
+
3. Restart your AI assistant (Cursor or Claude Desktop)
|
|
339
|
+
|
|
340
|
+
**Verify the fix:**
|
|
341
|
+
After restarting, check the application logs. You should see successful initialization:
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
✅ Loaded Genesis design system data
|
|
345
|
+
Version: X.X.X
|
|
346
|
+
Components: XX
|
|
347
|
+
Hooks: XX
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Instead of `ENOENT` errors.
|
|
351
|
+
|
|
352
|
+
### MCP Inspector (Advanced Debugging)
|
|
353
|
+
|
|
354
|
+
If you're still having issues, use the MCP Inspector to debug:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
npx @modelcontextprotocol/inspector
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Navigate to `http://127.0.0.1:6274` and configure:
|
|
361
|
+
|
|
362
|
+
- **Transport type:** Stdio
|
|
363
|
+
- **Command:** Your full npx path (e.g., `/opt/homebrew/bin/npx`)
|
|
364
|
+
- **Arguments:** `-y @spaced-out/genesis-mcp-server@latest`
|
|
365
|
+
|
|
366
|
+
Click **Connect** to test the connection. If it fails, check the terminal logs for detailed error messages.
|
|
367
|
+
|
|
368
|
+
### Test the Server Directly
|
|
369
|
+
|
|
370
|
+
Test if the server runs correctly in your terminal:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
npx -y @spaced-out/genesis-mcp-server@latest
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
You should see:
|
|
377
|
+
|
|
378
|
+
```
|
|
379
|
+
✅ Loaded Genesis design system data
|
|
380
|
+
Version: X.X.X
|
|
381
|
+
Components: XX
|
|
382
|
+
Hooks: XX
|
|
383
|
+
Built: YYYY-MM-DD
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
If this fails, there may be an issue with the published package.
|
|
387
|
+
|
|
388
|
+
### Package Not Found
|
|
389
|
+
|
|
390
|
+
**Error:** `npm ERR! 404 '@spaced-out/genesis-mcp-server@latest' is not in this registry`
|
|
391
|
+
|
|
392
|
+
**Solution:**
|
|
393
|
+
|
|
394
|
+
- Verify the package is published: `npm view @spaced-out/genesis-mcp-server`
|
|
395
|
+
- If using a private registry, ensure you're authenticated
|
|
396
|
+
- Check your npm registry configuration: `npm config get registry`
|
|
397
|
+
|
|
398
|
+
### Node.js Version
|
|
399
|
+
|
|
400
|
+
**Error:** `The engine "node" is incompatible with this module`
|
|
401
|
+
|
|
402
|
+
**Solution:**
|
|
403
|
+
This server requires Node.js >= 18.0.0. Update your Node.js installation:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
node --version # Check current version
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Use [nvm](https://github.com/nvm-sh/nvm) or download from [nodejs.org](https://nodejs.org/).
|
|
410
|
+
|
|
287
411
|
## 🤝 Contributing
|
|
288
412
|
|
|
289
413
|
When updating the design system:
|
|
@@ -293,9 +417,105 @@ When updating the design system:
|
|
|
293
417
|
3. New version is published to npm
|
|
294
418
|
4. Users get updates on next `npx` run (or immediately with `@latest`)
|
|
295
419
|
|
|
420
|
+
## 🎨 Integration with Figma MCP
|
|
421
|
+
|
|
422
|
+
The Genesis MCP server works seamlessly alongside the Figma MCP server, enabling a powerful design-to-code workflow. By using both servers together, you can bridge design and implementation.
|
|
423
|
+
|
|
424
|
+
### Why Use Both?
|
|
425
|
+
|
|
426
|
+
**Figma MCP** provides:
|
|
427
|
+
|
|
428
|
+
- Design screenshots and visual context
|
|
429
|
+
- Component properties and variants from Figma
|
|
430
|
+
- Design tokens and variables from Figma files
|
|
431
|
+
- Layout measurements and spacing
|
|
432
|
+
|
|
433
|
+
**Genesis MCP** provides:
|
|
434
|
+
|
|
435
|
+
- Actual React component implementations
|
|
436
|
+
- Design system tokens and guidelines
|
|
437
|
+
- TypeScript types and APIs
|
|
438
|
+
- CSS Module styling patterns
|
|
439
|
+
|
|
440
|
+
Together, they create a complete workflow: **Design in Figma → Implement with Genesis**
|
|
441
|
+
|
|
442
|
+
### Configuration Examples
|
|
443
|
+
|
|
444
|
+
You can run multiple MCP servers simultaneously:
|
|
445
|
+
|
|
446
|
+
**VS Code/Cursor:**
|
|
447
|
+
|
|
448
|
+
```json
|
|
449
|
+
{
|
|
450
|
+
"mcpServers": {
|
|
451
|
+
"genesis-design-system": {
|
|
452
|
+
"command": "/opt/homebrew/bin/npx",
|
|
453
|
+
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
454
|
+
},
|
|
455
|
+
"figma-desktop": {
|
|
456
|
+
"command": "/opt/homebrew/bin/npx",
|
|
457
|
+
"args": ["-y", "@modelcontextprotocol/server-figma"]
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Claude Desktop:**
|
|
464
|
+
|
|
465
|
+
```json
|
|
466
|
+
{
|
|
467
|
+
"mcpServers": {
|
|
468
|
+
"genesis-design-system": {
|
|
469
|
+
"command": "/opt/homebrew/bin/npx",
|
|
470
|
+
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
471
|
+
},
|
|
472
|
+
"figma-desktop": {
|
|
473
|
+
"command": "/opt/homebrew/bin/npx",
|
|
474
|
+
"args": ["-y", "@modelcontextprotocol/server-figma"]
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Workflow Examples
|
|
481
|
+
|
|
482
|
+
**Design-to-Code:**
|
|
483
|
+
|
|
484
|
+
```
|
|
485
|
+
"Show me the current Figma selection"
|
|
486
|
+
"Find the matching Genesis component for this design"
|
|
487
|
+
"Implement this Figma button using Genesis Button component"
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Token Mapping:**
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
"Compare Figma colors with Genesis color tokens"
|
|
494
|
+
"What Genesis spacing token matches this 16px gap?"
|
|
495
|
+
"Map this Figma shadow to Genesis elevation tokens"
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Validation:**
|
|
499
|
+
|
|
500
|
+
```
|
|
501
|
+
"Does Genesis have a component matching this Figma design?"
|
|
502
|
+
"Are these Figma colors available in Genesis palette?"
|
|
503
|
+
"What Genesis components would I need for this Figma screen?"
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Requirements
|
|
507
|
+
|
|
508
|
+
- **Figma MCP**: Figma Desktop app running with design files open
|
|
509
|
+
- **Genesis MCP**: Node.js >= 18.0.0
|
|
510
|
+
|
|
511
|
+
See [Figma MCP documentation](https://modelcontextprotocol.io/docs/tools/figma) for Figma setup details.
|
|
512
|
+
|
|
296
513
|
## 📚 Additional Resources
|
|
297
514
|
|
|
298
515
|
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
516
|
+
- [Figma MCP Documentation](https://modelcontextprotocol.io/docs/tools/figma)
|
|
517
|
+
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
|
|
518
|
+
- [Genesis Storybook MCP Guide](https://your-storybook-url.com/?path=/docs/model-context-protocol--docs)
|
|
299
519
|
|
|
300
520
|
## 📄 License
|
|
301
521
|
|
package/mcp/build-mcp-data.js
CHANGED
|
@@ -42,7 +42,34 @@ function getDirectories(path) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* Get all files recursively in a directory
|
|
46
|
+
*/
|
|
47
|
+
function getAllFilesRecursively(dirPath, filesList = [], baseDir = dirPath) {
|
|
48
|
+
try {
|
|
49
|
+
const files = readdirSync(dirPath);
|
|
50
|
+
|
|
51
|
+
files.forEach(file => {
|
|
52
|
+
if (file.startsWith('.')) return;
|
|
53
|
+
|
|
54
|
+
const filePath = join(dirPath, file);
|
|
55
|
+
const stat = statSync(filePath);
|
|
56
|
+
|
|
57
|
+
if (stat.isDirectory()) {
|
|
58
|
+
getAllFilesRecursively(filePath, filesList, baseDir);
|
|
59
|
+
} else {
|
|
60
|
+
const relativePath = filePath.replace(baseDir + '/', '');
|
|
61
|
+
filesList.push(relativePath);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
// Ignore errors for non-existent directories
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return filesList;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Extract all components with their files (including sub-components)
|
|
46
73
|
*/
|
|
47
74
|
function buildComponentsData() {
|
|
48
75
|
console.log('📦 Extracting components...');
|
|
@@ -59,24 +86,58 @@ function buildComponentsData() {
|
|
|
59
86
|
for (const componentName of componentDirs) {
|
|
60
87
|
const componentDir = join(componentsPath, componentName);
|
|
61
88
|
|
|
89
|
+
// Get all files in the component directory
|
|
90
|
+
const allFiles = getAllFilesRecursively(componentDir);
|
|
91
|
+
|
|
92
|
+
// Extract main component files
|
|
62
93
|
const mainTsx = join(componentDir, `${componentName}.tsx`);
|
|
63
94
|
const mainTs = join(componentDir, `${componentName}.ts`);
|
|
95
|
+
const mainContent = safeReadFile(mainTsx) || safeReadFile(mainTs);
|
|
64
96
|
|
|
97
|
+
// Extract story files
|
|
65
98
|
const storyTsx = join(componentDir, `${componentName}.stories.tsx`);
|
|
66
99
|
const storyTs = join(componentDir, `${componentName}.stories.ts`);
|
|
100
|
+
const storyContent = safeReadFile(storyTsx) || safeReadFile(storyTs);
|
|
67
101
|
|
|
102
|
+
// Extract CSS file
|
|
68
103
|
const cssFile = join(componentDir, `${componentName}.module.css`);
|
|
104
|
+
const cssContent = safeReadFile(cssFile);
|
|
69
105
|
|
|
106
|
+
// Extract index file
|
|
70
107
|
const indexFile = join(componentDir, 'index.ts');
|
|
71
|
-
|
|
72
|
-
const mainContent = safeReadFile(mainTsx) || safeReadFile(mainTs);
|
|
73
|
-
const storyContent = safeReadFile(storyTsx) || safeReadFile(storyTs);
|
|
74
|
-
const cssContent = safeReadFile(cssFile);
|
|
75
108
|
const indexContent = safeReadFile(indexFile);
|
|
76
109
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
// Extract all additional TypeScript/TSX files (sub-components)
|
|
111
|
+
const additionalFiles = {};
|
|
112
|
+
for (const file of allFiles) {
|
|
113
|
+
// Skip main files we already extracted
|
|
114
|
+
if (
|
|
115
|
+
file === `${componentName}.tsx` ||
|
|
116
|
+
file === `${componentName}.ts` ||
|
|
117
|
+
file === `${componentName}.stories.tsx` ||
|
|
118
|
+
file === `${componentName}.stories.ts` ||
|
|
119
|
+
file === `${componentName}.module.css` ||
|
|
120
|
+
file === 'index.ts' ||
|
|
121
|
+
file.endsWith('.module.css') ||
|
|
122
|
+
file.endsWith('.stories.tsx') ||
|
|
123
|
+
file.endsWith('.stories.ts') ||
|
|
124
|
+
file.endsWith('.stories.module.css')
|
|
125
|
+
) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Only include .tsx and .ts files (sub-components)
|
|
130
|
+
if (file.endsWith('.tsx') || file.endsWith('.ts')) {
|
|
131
|
+
const fullPath = join(componentDir, file);
|
|
132
|
+
const content = safeReadFile(fullPath);
|
|
133
|
+
if (content) {
|
|
134
|
+
additionalFiles[file] = {
|
|
135
|
+
path: file,
|
|
136
|
+
content: content
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
80
141
|
|
|
81
142
|
components[componentName] = {
|
|
82
143
|
name: componentName,
|
|
@@ -86,6 +147,7 @@ function buildComponentsData() {
|
|
|
86
147
|
story: storyContent ? { path: `${componentName}.stories.tsx`, content: storyContent } : null,
|
|
87
148
|
css: cssContent ? { path: `${componentName}.module.css`, content: cssContent } : null,
|
|
88
149
|
index: indexContent ? { path: 'index.ts', content: indexContent } : null,
|
|
150
|
+
additional: additionalFiles,
|
|
89
151
|
},
|
|
90
152
|
allFiles,
|
|
91
153
|
};
|
|
@@ -190,6 +252,94 @@ function buildTokensData() {
|
|
|
190
252
|
return tokens;
|
|
191
253
|
}
|
|
192
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Extract all utils
|
|
257
|
+
*/
|
|
258
|
+
function buildUtilsData() {
|
|
259
|
+
console.log('🔧 Extracting utils...');
|
|
260
|
+
const utilsPath = join(DESIGN_SYSTEM_PATH, 'src/utils');
|
|
261
|
+
const utils = {};
|
|
262
|
+
|
|
263
|
+
if (!existsSync(utilsPath)) {
|
|
264
|
+
console.warn('⚠️ Utils path not found');
|
|
265
|
+
return utils;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const utilDirs = getDirectories(utilsPath);
|
|
269
|
+
|
|
270
|
+
for (const utilName of utilDirs) {
|
|
271
|
+
const utilDir = join(utilsPath, utilName);
|
|
272
|
+
|
|
273
|
+
// Get all files in the util directory
|
|
274
|
+
const allFiles = getAllFilesRecursively(utilDir);
|
|
275
|
+
|
|
276
|
+
// Read all TypeScript files
|
|
277
|
+
const files = {};
|
|
278
|
+
for (const file of allFiles) {
|
|
279
|
+
if ((file.endsWith('.ts') || file.endsWith('.tsx')) && !file.endsWith('.d.ts')) {
|
|
280
|
+
const fullPath = join(utilDir, file);
|
|
281
|
+
const content = safeReadFile(fullPath);
|
|
282
|
+
if (content) {
|
|
283
|
+
files[file] = {
|
|
284
|
+
path: file,
|
|
285
|
+
content: content
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
utils[utilName] = {
|
|
292
|
+
name: utilName,
|
|
293
|
+
path: `src/utils/${utilName}`,
|
|
294
|
+
files: files,
|
|
295
|
+
allFiles: allFiles,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
console.log(` ✅ Extracted ${Object.keys(utils).length} util modules`);
|
|
300
|
+
return utils;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Extract all types
|
|
305
|
+
*/
|
|
306
|
+
function buildTypesData() {
|
|
307
|
+
console.log('📐 Extracting types...');
|
|
308
|
+
const typesPath = join(DESIGN_SYSTEM_PATH, 'src/types');
|
|
309
|
+
const types = {};
|
|
310
|
+
|
|
311
|
+
if (!existsSync(typesPath)) {
|
|
312
|
+
console.warn('⚠️ Types path not found');
|
|
313
|
+
return types;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const files = readdirSync(typesPath).filter(f =>
|
|
318
|
+
!f.startsWith('.') &&
|
|
319
|
+
(f.endsWith('.ts') || f.endsWith('.tsx')) &&
|
|
320
|
+
!f.endsWith('.d.ts')
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
for (const file of files) {
|
|
324
|
+
const filePath = join(typesPath, file);
|
|
325
|
+
const content = safeReadFile(filePath);
|
|
326
|
+
if (content) {
|
|
327
|
+
const typeName = file.replace(/\.(ts|tsx)$/, '');
|
|
328
|
+
types[typeName] = {
|
|
329
|
+
name: typeName,
|
|
330
|
+
path: `src/types/${file}`,
|
|
331
|
+
content: content,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} catch (error) {
|
|
336
|
+
console.warn(` ⚠️ Error reading types:`, error.message);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
console.log(` ✅ Extracted ${Object.keys(types).length} type files`);
|
|
340
|
+
return types;
|
|
341
|
+
}
|
|
342
|
+
|
|
193
343
|
/**
|
|
194
344
|
* Get package version
|
|
195
345
|
*/
|
|
@@ -217,6 +367,8 @@ function build() {
|
|
|
217
367
|
components: buildComponentsData(),
|
|
218
368
|
hooks: buildHooksData(),
|
|
219
369
|
tokens: buildTokensData(),
|
|
370
|
+
utils: buildUtilsData(),
|
|
371
|
+
types: buildTypesData(),
|
|
220
372
|
};
|
|
221
373
|
|
|
222
374
|
// Create output directory if it doesn't exist
|
|
@@ -232,6 +384,8 @@ function build() {
|
|
|
232
384
|
console.log(` - Components: ${Object.keys(data.components).length}`);
|
|
233
385
|
console.log(` - Hooks: ${Object.keys(data.hooks).length}`);
|
|
234
386
|
console.log(` - Token categories: ${Object.keys(data.tokens).length}`);
|
|
387
|
+
console.log(` - Utils: ${Object.keys(data.utils).length}`);
|
|
388
|
+
console.log(` - Types: ${Object.keys(data.types).length}`);
|
|
235
389
|
console.log(` - Version: ${data.metadata.version}`);
|
|
236
390
|
console.log(` - Output: ${OUTPUT_FILE}`);
|
|
237
391
|
console.log(` - Size: ${(Buffer.byteLength(JSON.stringify(data)) / 1024 / 1024).toFixed(2)} MB\n`);
|