@atelier-ui/create-workspace 0.0.11 → 0.0.12
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 +3 -3
- package/src/generators/preset/files/styles/tokens.css +277 -0
- package/src/generators/preset/files/tools/scripts/preflight.mjs +323 -0
- package/src/generators/preset/preset.js +89 -20
- package/src/generators/preset/preset.js.map +1 -1
- package/src/generators/preset/schema.d.ts +1 -0
- package/src/generators/preset/schema.json +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atelier-ui/create-workspace",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Nx preset for Atelier UI workshop workspaces",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nx",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"types": "./src/index.d.ts",
|
|
22
22
|
"generators": "./generators.json",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@nx/devkit": "22.6.
|
|
24
|
+
"@nx/devkit": "22.6.5",
|
|
25
25
|
"tslib": "^2.3.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@nx/angular": ">=22.0.0"
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens for the LLM-optimized Angular component library.
|
|
3
|
+
* Import this stylesheet once at the application root to activate the token layer.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* @import '@atelier-ui/angular/styles/tokens.css';
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
:root {
|
|
10
|
+
/* Typography */
|
|
11
|
+
--ui-font-family: 'Montserrat', 'Inter', ui-sans-serif, system-ui, -apple-system,
|
|
12
|
+
BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
13
|
+
--ui-font-size-xs: 0.75rem;
|
|
14
|
+
--ui-font-size-sm: 0.875rem;
|
|
15
|
+
--ui-font-size-md: 1rem;
|
|
16
|
+
--ui-font-size-lg: 1.125rem;
|
|
17
|
+
--ui-font-size-xl: 1.25rem;
|
|
18
|
+
--ui-font-size-2xl: 1.5rem;
|
|
19
|
+
--ui-letter-spacing-tight: -0.01em;
|
|
20
|
+
--ui-letter-spacing-normal: 0;
|
|
21
|
+
--ui-letter-spacing-wide: 0.01em;
|
|
22
|
+
--ui-font-weight-normal: 400;
|
|
23
|
+
--ui-font-weight-medium: 500;
|
|
24
|
+
--ui-font-weight-semibold: 600;
|
|
25
|
+
--ui-line-height-tight: 1.25;
|
|
26
|
+
--ui-line-height-normal: 1.5;
|
|
27
|
+
|
|
28
|
+
/* Colors — Primary */
|
|
29
|
+
--ui-color-primary: #00bebe;
|
|
30
|
+
--ui-color-primary-hover: #009696;
|
|
31
|
+
--ui-color-primary-active: #007070;
|
|
32
|
+
--ui-color-primary-light: rgba(0, 190, 190, 0.08);
|
|
33
|
+
|
|
34
|
+
/* Colors — Secondary */
|
|
35
|
+
--ui-color-secondary: #64748b;
|
|
36
|
+
--ui-color-secondary-hover: #475569;
|
|
37
|
+
--ui-color-secondary-active: #334155;
|
|
38
|
+
|
|
39
|
+
/* Colors — Semantic */
|
|
40
|
+
--ui-color-danger: #ef4444;
|
|
41
|
+
--ui-color-danger-hover: #dc2626;
|
|
42
|
+
--ui-color-danger-active: #b91c1c;
|
|
43
|
+
--ui-color-success: #22c55e;
|
|
44
|
+
--ui-color-warning: #f59e0b;
|
|
45
|
+
--ui-color-info: #06b6d4;
|
|
46
|
+
|
|
47
|
+
/* Colors — Surfaces */
|
|
48
|
+
--ui-color-surface: #ffffff;
|
|
49
|
+
--ui-color-surface-raised: #fafafa;
|
|
50
|
+
--ui-color-surface-sunken: #f5f5f5;
|
|
51
|
+
|
|
52
|
+
/* Colors — Borders */
|
|
53
|
+
--ui-color-border: #e5e7eb;
|
|
54
|
+
--ui-color-border-hover: #d1d5db;
|
|
55
|
+
|
|
56
|
+
/* Colors — Text */
|
|
57
|
+
--ui-color-text: #0f172a;
|
|
58
|
+
--ui-color-text-muted: #64748b;
|
|
59
|
+
--ui-color-text-on-primary: #0f172a;
|
|
60
|
+
--ui-color-text-on-secondary: #ffffff;
|
|
61
|
+
--ui-color-text-on-danger: #ffffff;
|
|
62
|
+
--ui-color-text-on-success: #ffffff;
|
|
63
|
+
--ui-color-on-primary: #0f172a;
|
|
64
|
+
|
|
65
|
+
/* Colors — Brand palette */
|
|
66
|
+
--ui-color-brand-corporate: #00bebe;
|
|
67
|
+
--ui-color-brand-agile: #00d296;
|
|
68
|
+
--ui-color-brand-architecture: #009696;
|
|
69
|
+
--ui-color-brand-development: #00b4ff;
|
|
70
|
+
--ui-color-brand-petrol: #005064;
|
|
71
|
+
--ui-color-brand-ai: #b5e61c;
|
|
72
|
+
--ui-color-brand-light-blue: #00ebff;
|
|
73
|
+
--ui-color-brand-light-green: #a0fa50;
|
|
74
|
+
--ui-opacity-disabled: 0.5;
|
|
75
|
+
|
|
76
|
+
/* Border radius */
|
|
77
|
+
--ui-radius-sm: 0.375rem;
|
|
78
|
+
--ui-radius-md: 0.5rem;
|
|
79
|
+
--ui-radius-lg: 0.75rem;
|
|
80
|
+
--ui-radius-xl: 1rem;
|
|
81
|
+
--ui-radius-full: 9999px;
|
|
82
|
+
|
|
83
|
+
/* Spacing */
|
|
84
|
+
--ui-spacing-1: 0.25rem;
|
|
85
|
+
--ui-spacing-2: 0.5rem;
|
|
86
|
+
--ui-spacing-3: 0.75rem;
|
|
87
|
+
--ui-spacing-4: 1rem;
|
|
88
|
+
--ui-spacing-5: 1.25rem;
|
|
89
|
+
--ui-spacing-6: 1.5rem;
|
|
90
|
+
--ui-spacing-8: 2rem;
|
|
91
|
+
--ui-spacing-10: 2.5rem;
|
|
92
|
+
--ui-spacing-12: 3rem;
|
|
93
|
+
--ui-spacing-16: 4rem;
|
|
94
|
+
|
|
95
|
+
/* Shadows — dual-layer (ambient + key light) */
|
|
96
|
+
--ui-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
|
97
|
+
--ui-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.06),
|
|
98
|
+
0 1px 2px -1px rgba(0, 0, 0, 0.06);
|
|
99
|
+
--ui-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07),
|
|
100
|
+
0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
101
|
+
--ui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08),
|
|
102
|
+
0 4px 6px -4px rgba(0, 0, 0, 0.04);
|
|
103
|
+
--ui-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08),
|
|
104
|
+
0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
|
105
|
+
|
|
106
|
+
/* Motion — custom easings for polished feel */
|
|
107
|
+
--ui-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
108
|
+
--ui-ease-in-out: cubic-bezier(0.45, 0, 0.55, 1);
|
|
109
|
+
--ui-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
110
|
+
|
|
111
|
+
--ui-duration-fast: 150ms;
|
|
112
|
+
--ui-duration-normal: 200ms;
|
|
113
|
+
--ui-duration-slow: 300ms;
|
|
114
|
+
|
|
115
|
+
--ui-transition-fast: var(--ui-duration-fast) var(--ui-ease-out);
|
|
116
|
+
--ui-transition-normal: var(--ui-duration-normal) var(--ui-ease-out);
|
|
117
|
+
--ui-transition-slow: var(--ui-duration-slow) var(--ui-ease-out);
|
|
118
|
+
|
|
119
|
+
/* Focus ring — double-ring for light & dark background compatibility */
|
|
120
|
+
--ui-focus-ring: 0 0 0 2px var(--ui-color-surface),
|
|
121
|
+
0 0 0 4px var(--ui-color-primary);
|
|
122
|
+
|
|
123
|
+
/* Form controls */
|
|
124
|
+
--ui-color-input-bg: var(--ui-color-surface-sunken);
|
|
125
|
+
--ui-color-input-bg-focus: var(--ui-color-surface);
|
|
126
|
+
--ui-color-input-border: #d1d5db;
|
|
127
|
+
--ui-color-input-border-hover: #9ca3af;
|
|
128
|
+
--ui-color-input-border-focus: var(--ui-color-primary);
|
|
129
|
+
--ui-color-input-border-invalid: var(--ui-color-danger);
|
|
130
|
+
--ui-color-placeholder: #9ca3af;
|
|
131
|
+
--ui-color-error-text: var(--ui-color-danger);
|
|
132
|
+
|
|
133
|
+
/* Z-index scale */
|
|
134
|
+
--ui-z-base: 0;
|
|
135
|
+
--ui-z-dropdown: 100;
|
|
136
|
+
--ui-z-overlay: 200;
|
|
137
|
+
--ui-z-modal: 300;
|
|
138
|
+
--ui-z-toast: 400;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (prefers-color-scheme: dark) {
|
|
142
|
+
:root {
|
|
143
|
+
--ui-color-primary: #00d0d0;
|
|
144
|
+
--ui-color-primary-hover: #00bebe;
|
|
145
|
+
--ui-color-primary-active: #009696;
|
|
146
|
+
--ui-color-primary-light: rgba(0, 190, 190, 0.15);
|
|
147
|
+
|
|
148
|
+
--ui-color-secondary: #94a3b8;
|
|
149
|
+
--ui-color-secondary-hover: #cbd5e1;
|
|
150
|
+
--ui-color-secondary-active: #e2e8f0;
|
|
151
|
+
|
|
152
|
+
--ui-color-danger: #f87171;
|
|
153
|
+
--ui-color-danger-hover: #fca5a5;
|
|
154
|
+
--ui-color-danger-active: #fecaca;
|
|
155
|
+
|
|
156
|
+
--ui-color-success: #4ade80;
|
|
157
|
+
--ui-color-warning: #fbbf24;
|
|
158
|
+
--ui-color-info: #22d3ee;
|
|
159
|
+
|
|
160
|
+
--ui-color-surface: #28283c;
|
|
161
|
+
--ui-color-surface-raised: #2f2f45;
|
|
162
|
+
--ui-color-surface-sunken: #22222f;
|
|
163
|
+
|
|
164
|
+
--ui-color-border: #3a3a4f;
|
|
165
|
+
--ui-color-border-hover: #4a4a63;
|
|
166
|
+
|
|
167
|
+
--ui-color-text: #f1f5f9;
|
|
168
|
+
--ui-color-text-muted: #94a3b8;
|
|
169
|
+
--ui-color-on-primary: #0f172a;
|
|
170
|
+
--ui-color-text-on-secondary: #0f172a;
|
|
171
|
+
|
|
172
|
+
--ui-opacity-disabled: 0.65;
|
|
173
|
+
|
|
174
|
+
--ui-color-input-border: #4a4a63;
|
|
175
|
+
--ui-color-input-border-hover: #686880;
|
|
176
|
+
--ui-color-placeholder: #686880;
|
|
177
|
+
|
|
178
|
+
--ui-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
|
|
179
|
+
--ui-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3),
|
|
180
|
+
0 1px 2px -1px rgba(0, 0, 0, 0.3);
|
|
181
|
+
--ui-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.35),
|
|
182
|
+
0 2px 4px -2px rgba(0, 0, 0, 0.25);
|
|
183
|
+
--ui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4),
|
|
184
|
+
0 4px 6px -4px rgba(0, 0, 0, 0.2);
|
|
185
|
+
--ui-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.4),
|
|
186
|
+
0 8px 10px -6px rgba(0, 0, 0, 0.2);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
[data-theme="dark"] {
|
|
191
|
+
--ui-color-primary: #00d0d0;
|
|
192
|
+
--ui-color-primary-hover: #00bebe;
|
|
193
|
+
--ui-color-primary-active: #009696;
|
|
194
|
+
--ui-color-primary-light: rgba(0, 190, 190, 0.15);
|
|
195
|
+
|
|
196
|
+
--ui-color-secondary: #94a3b8;
|
|
197
|
+
--ui-color-secondary-hover: #cbd5e1;
|
|
198
|
+
--ui-color-secondary-active: #e2e8f0;
|
|
199
|
+
|
|
200
|
+
--ui-color-danger: #f87171;
|
|
201
|
+
--ui-color-danger-hover: #fca5a5;
|
|
202
|
+
--ui-color-danger-active: #fecaca;
|
|
203
|
+
|
|
204
|
+
--ui-color-success: #4ade80;
|
|
205
|
+
--ui-color-warning: #fbbf24;
|
|
206
|
+
--ui-color-info: #22d3ee;
|
|
207
|
+
|
|
208
|
+
--ui-color-surface: #28283c;
|
|
209
|
+
--ui-color-surface-raised: #2f2f45;
|
|
210
|
+
--ui-color-surface-sunken: #22222f;
|
|
211
|
+
|
|
212
|
+
--ui-color-border: #3a3a4f;
|
|
213
|
+
--ui-color-border-hover: #4a4a63;
|
|
214
|
+
|
|
215
|
+
--ui-color-text: #f1f5f9;
|
|
216
|
+
--ui-color-text-muted: #94a3b8;
|
|
217
|
+
--ui-color-on-primary: #0f172a;
|
|
218
|
+
--ui-color-text-on-secondary: #0f172a;
|
|
219
|
+
|
|
220
|
+
--ui-opacity-disabled: 0.65;
|
|
221
|
+
|
|
222
|
+
--ui-color-input-border: #4a4a63;
|
|
223
|
+
--ui-color-input-border-hover: #686880;
|
|
224
|
+
--ui-color-placeholder: #686880;
|
|
225
|
+
|
|
226
|
+
--ui-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
|
|
227
|
+
--ui-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3),
|
|
228
|
+
0 1px 2px -1px rgba(0, 0, 0, 0.3);
|
|
229
|
+
--ui-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.35),
|
|
230
|
+
0 2px 4px -2px rgba(0, 0, 0, 0.25);
|
|
231
|
+
--ui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4),
|
|
232
|
+
0 4px 6px -4px rgba(0, 0, 0, 0.2);
|
|
233
|
+
--ui-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.4),
|
|
234
|
+
0 8px 10px -6px rgba(0, 0, 0, 0.2);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* Explicit light theme — declared last so it wins over prefers-color-scheme: dark */
|
|
238
|
+
[data-theme="light"] {
|
|
239
|
+
--ui-color-primary: #00bebe;
|
|
240
|
+
--ui-color-primary-hover: #009696;
|
|
241
|
+
--ui-color-primary-active: #007070;
|
|
242
|
+
--ui-color-primary-light: rgba(0, 190, 190, 0.08);
|
|
243
|
+
--ui-color-secondary: #64748b;
|
|
244
|
+
--ui-color-secondary-hover: #475569;
|
|
245
|
+
--ui-color-secondary-active: #334155;
|
|
246
|
+
--ui-color-danger: #ef4444;
|
|
247
|
+
--ui-color-danger-hover: #dc2626;
|
|
248
|
+
--ui-color-danger-active: #b91c1c;
|
|
249
|
+
--ui-color-success: #22c55e;
|
|
250
|
+
--ui-color-warning: #f59e0b;
|
|
251
|
+
--ui-color-info: #06b6d4;
|
|
252
|
+
--ui-color-surface: #ffffff;
|
|
253
|
+
--ui-color-surface-raised: #fafafa;
|
|
254
|
+
--ui-color-surface-sunken: #f5f5f5;
|
|
255
|
+
--ui-color-border: #e5e7eb;
|
|
256
|
+
--ui-color-border-hover: #d1d5db;
|
|
257
|
+
--ui-color-text: #0f172a;
|
|
258
|
+
--ui-color-text-muted: #64748b;
|
|
259
|
+
--ui-color-on-primary: #0f172a;
|
|
260
|
+
--ui-color-input-border: #d1d5db;
|
|
261
|
+
--ui-color-input-border-hover: #9ca3af;
|
|
262
|
+
--ui-color-placeholder: #9ca3af;
|
|
263
|
+
--ui-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
|
264
|
+
--ui-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.06), 0 1px 2px -1px rgba(0, 0, 0, 0.06);
|
|
265
|
+
--ui-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
266
|
+
--ui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
|
|
267
|
+
--ui-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@media (prefers-reduced-motion: reduce) {
|
|
271
|
+
:root {
|
|
272
|
+
--ui-duration-fast: 0ms;
|
|
273
|
+
--ui-duration-normal: 0ms;
|
|
274
|
+
--ui-duration-slow: 0ms;
|
|
275
|
+
--ui-ease-spring: ease;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* preflight.mjs
|
|
4
|
+
*
|
|
5
|
+
* Pre-workshop self-check. Verifies the local environment is ready for the
|
|
6
|
+
* Atelier UI workshop (Figma + Claude Code + Storybook MCP).
|
|
7
|
+
*
|
|
8
|
+
* Run via: node tools/scripts/preflight.mjs
|
|
9
|
+
* (or npm run preflight)
|
|
10
|
+
*
|
|
11
|
+
* Exits non-zero if any hard check fails. Warnings do not block.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
15
|
+
import { createServer } from 'node:net';
|
|
16
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { dirname, join, resolve } from 'node:path';
|
|
20
|
+
|
|
21
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const __dirname = dirname(__filename);
|
|
23
|
+
const ROOT = resolve(__dirname, '../..');
|
|
24
|
+
|
|
25
|
+
// ── Styling ──────────────────────────────────────────────────────────
|
|
26
|
+
const supportsColor = process.stdout.isTTY && process.env.NO_COLOR === undefined;
|
|
27
|
+
const c = (code, s) => (supportsColor ? `\x1b[${code}m${s}\x1b[0m` : s);
|
|
28
|
+
const red = (s) => c('31', s);
|
|
29
|
+
const green = (s) => c('32', s);
|
|
30
|
+
const yellow = (s) => c('33', s);
|
|
31
|
+
const dim = (s) => c('2', s);
|
|
32
|
+
const bold = (s) => c('1', s);
|
|
33
|
+
|
|
34
|
+
const OK = green('✓');
|
|
35
|
+
const FAIL = red('✗');
|
|
36
|
+
const WARN = yellow('⚠');
|
|
37
|
+
|
|
38
|
+
// ── Result accumulator ───────────────────────────────────────────────
|
|
39
|
+
const results = [];
|
|
40
|
+
function record(level, label, detail, fix) {
|
|
41
|
+
results.push({ level, label, detail, fix });
|
|
42
|
+
const icon = level === 'ok' ? OK : level === 'fail' ? FAIL : WARN;
|
|
43
|
+
const labelStr = level === 'fail' ? bold(label) : label;
|
|
44
|
+
console.log(` ${icon} ${labelStr}${detail ? dim(` — ${detail}`) : ''}`);
|
|
45
|
+
if (fix && level !== 'ok') {
|
|
46
|
+
console.log(` ${dim('→')} ${fix}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const ok = (label, detail) => record('ok', label, detail);
|
|
50
|
+
const fail = (label, detail, fix) => record('fail', label, detail, fix);
|
|
51
|
+
const warn = (label, detail, fix) => record('warn', label, detail, fix);
|
|
52
|
+
|
|
53
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
54
|
+
function which(cmd) {
|
|
55
|
+
const finder = process.platform === 'win32' ? 'where' : 'which';
|
|
56
|
+
const res = spawnSync(finder, [cmd], { encoding: 'utf8' });
|
|
57
|
+
if (res.status === 0 && res.stdout.trim()) return res.stdout.trim().split('\n')[0];
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function parseMajorMinor(version) {
|
|
62
|
+
const match = /(\d+)\.(\d+)\.?(\d+)?/.exec(version);
|
|
63
|
+
if (!match) return null;
|
|
64
|
+
return { major: +match[1], minor: +match[2], patch: +(match[3] ?? 0) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isAtLeast(actual, required) {
|
|
68
|
+
if (!actual) return false;
|
|
69
|
+
if (actual.major !== required.major) return actual.major > required.major;
|
|
70
|
+
if (actual.minor !== required.minor) return actual.minor > required.minor;
|
|
71
|
+
return actual.patch >= required.patch;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function httpReachable(url, timeoutMs = 5000) {
|
|
75
|
+
const controller = new AbortController();
|
|
76
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetch(url, { method: 'GET', signal: controller.signal });
|
|
79
|
+
return { ok: true, status: res.status };
|
|
80
|
+
} catch (err) {
|
|
81
|
+
return { ok: false, error: err?.name === 'AbortError' ? 'timeout' : String(err?.message ?? err) };
|
|
82
|
+
} finally {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function portFree(port) {
|
|
88
|
+
return new Promise((resolveP) => {
|
|
89
|
+
const server = createServer();
|
|
90
|
+
server.once('error', () => resolveP(false));
|
|
91
|
+
server.once('listening', () => {
|
|
92
|
+
server.close(() => resolveP(true));
|
|
93
|
+
});
|
|
94
|
+
server.listen(port, '127.0.0.1');
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function loadMcpEndpoints() {
|
|
99
|
+
const mcpPath = resolve(ROOT, '.mcp.json');
|
|
100
|
+
if (!existsSync(mcpPath)) return [];
|
|
101
|
+
try {
|
|
102
|
+
const config = JSON.parse(readFileSync(mcpPath, 'utf8'));
|
|
103
|
+
const servers = config.mcpServers ?? {};
|
|
104
|
+
return Object.entries(servers)
|
|
105
|
+
.filter(([, v]) => v?.type === 'http' && typeof v?.url === 'string')
|
|
106
|
+
.map(([name, v]) => ({ name, url: v.url }));
|
|
107
|
+
} catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Checks ───────────────────────────────────────────────────────────
|
|
113
|
+
function checkNode() {
|
|
114
|
+
const required = { major: 20, minor: 11, patch: 0 };
|
|
115
|
+
const actual = parseMajorMinor(process.version);
|
|
116
|
+
if (isAtLeast(actual, required)) {
|
|
117
|
+
ok('Node.js', process.version);
|
|
118
|
+
} else {
|
|
119
|
+
fail(
|
|
120
|
+
'Node.js',
|
|
121
|
+
`found ${process.version}, need >= 20.11.0`,
|
|
122
|
+
'Install via https://nodejs.org or use `nvm install 20 && nvm use 20`',
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function checkNpm() {
|
|
128
|
+
const required = { major: 10, minor: 0, patch: 0 };
|
|
129
|
+
const path = which('npm');
|
|
130
|
+
if (!path) {
|
|
131
|
+
fail('npm', 'not found on PATH', 'npm ships with Node.js — reinstall Node if missing');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const version = execSync('npm --version', { encoding: 'utf8' }).trim();
|
|
136
|
+
const actual = parseMajorMinor(version);
|
|
137
|
+
if (isAtLeast(actual, required)) {
|
|
138
|
+
ok('npm', `v${version}`);
|
|
139
|
+
} else {
|
|
140
|
+
warn('npm', `found v${version}, recommend >= 10.0.0`, 'Run `npm install -g npm@latest`');
|
|
141
|
+
}
|
|
142
|
+
} catch (err) {
|
|
143
|
+
fail('npm', String(err?.message ?? err), 'Reinstall Node.js');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function checkGit() {
|
|
148
|
+
const path = which('git');
|
|
149
|
+
if (!path) {
|
|
150
|
+
fail('git', 'not found on PATH', 'Install from https://git-scm.com or `brew install git`');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const version = execSync('git --version', { encoding: 'utf8' }).trim();
|
|
155
|
+
ok('git', version);
|
|
156
|
+
} catch {
|
|
157
|
+
warn('git', 'installed but version check failed', 'Verify install with `git --version`');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function checkClaudeCli() {
|
|
162
|
+
const path = which('claude');
|
|
163
|
+
if (!path) {
|
|
164
|
+
fail(
|
|
165
|
+
'Claude Code CLI',
|
|
166
|
+
'not found on PATH',
|
|
167
|
+
'Install: https://docs.claude.com/en/docs/claude-code/setup',
|
|
168
|
+
);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const version = execSync('claude --version', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
173
|
+
ok('Claude Code CLI', version);
|
|
174
|
+
} catch {
|
|
175
|
+
warn('Claude Code CLI', 'installed but `claude --version` failed', 'Try `claude doctor`');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function checkFigmaSetup() {
|
|
180
|
+
// 1. Desktop Bridge plugin manifest — the primary channel.
|
|
181
|
+
const manifestPath = join(homedir(), '.figma-console-mcp', 'plugin', 'manifest.json');
|
|
182
|
+
if (existsSync(manifestPath)) {
|
|
183
|
+
ok('Figma Desktop Bridge plugin', `manifest at ${manifestPath}`);
|
|
184
|
+
} else {
|
|
185
|
+
warn(
|
|
186
|
+
'Figma Desktop Bridge plugin',
|
|
187
|
+
'manifest not found',
|
|
188
|
+
'Run `npx -y figma-console-mcp@latest --help` once, then Figma → Plugins → Development → Import plugin from manifest…',
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 2. Bridge WebSocket port range — at least one port must be usable.
|
|
193
|
+
const bridgePorts = [9223, 9224, 9225, 9226, 9227, 9228, 9229, 9230, 9231, 9232];
|
|
194
|
+
let freeCount = 0;
|
|
195
|
+
for (const p of bridgePorts) {
|
|
196
|
+
if (await portFree(p)) freeCount += 1;
|
|
197
|
+
}
|
|
198
|
+
if (freeCount === bridgePorts.length) {
|
|
199
|
+
ok('Bridge port range 9223–9232', 'all free (MCP will bind on first launch)');
|
|
200
|
+
} else if (freeCount > 0) {
|
|
201
|
+
ok('Bridge port range 9223–9232', `${freeCount}/10 free (bridge connection OK)`);
|
|
202
|
+
} else {
|
|
203
|
+
warn(
|
|
204
|
+
'Bridge port range 9223–9232',
|
|
205
|
+
'entire range in use',
|
|
206
|
+
'Close unrelated processes holding these ports, or see /troubleshooting#figma-bridge-port-conflict',
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 3. REST token — optional, only affects metadata reads.
|
|
211
|
+
const token = process.env.FIGMA_ACCESS_TOKEN;
|
|
212
|
+
if (!token) {
|
|
213
|
+
warn(
|
|
214
|
+
'FIGMA_ACCESS_TOKEN (optional)',
|
|
215
|
+
'not set — REST reads disabled, plugin tools still work',
|
|
216
|
+
'See https://atelier.pieper.io/figma-token if you need metadata reads',
|
|
217
|
+
);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (token.length < 20) {
|
|
221
|
+
warn(
|
|
222
|
+
'FIGMA_ACCESS_TOKEN',
|
|
223
|
+
'set but suspiciously short',
|
|
224
|
+
'Regenerate at https://www.figma.com/developers/api#access-tokens',
|
|
225
|
+
);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
ok('FIGMA_ACCESS_TOKEN', `set (${token.length} chars, REST reads enabled)`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function checkMcpEndpoints() {
|
|
232
|
+
const endpoints = loadMcpEndpoints();
|
|
233
|
+
if (endpoints.length === 0) {
|
|
234
|
+
warn(
|
|
235
|
+
'MCP endpoints',
|
|
236
|
+
'none configured in .mcp.json',
|
|
237
|
+
'Scaffold a workspace with `npx create-atelier-ui-workspace`',
|
|
238
|
+
);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
for (const { name, url } of endpoints) {
|
|
242
|
+
const res = await httpReachable(url);
|
|
243
|
+
if (res.ok && res.status < 500) {
|
|
244
|
+
ok(`MCP: ${name}`, `${url} (HTTP ${res.status})`);
|
|
245
|
+
} else if (res.ok) {
|
|
246
|
+
warn(`MCP: ${name}`, `${url} (HTTP ${res.status})`, 'Server reachable but returned 5xx — retry later');
|
|
247
|
+
} else {
|
|
248
|
+
fail(
|
|
249
|
+
`MCP: ${name}`,
|
|
250
|
+
`${url} unreachable (${res.error})`,
|
|
251
|
+
'Check your network or proxy settings',
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function checkPorts() {
|
|
258
|
+
const ports = [4200, 4201, 4202, 6006];
|
|
259
|
+
for (const p of ports) {
|
|
260
|
+
const free = await portFree(p);
|
|
261
|
+
if (free) ok(`Port ${p}`, 'free');
|
|
262
|
+
else warn(`Port ${p}`, 'in use', `Run \`lsof -ti :${p} | xargs kill\` (macOS/Linux)`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── Main ─────────────────────────────────────────────────────────────
|
|
267
|
+
function header(title) {
|
|
268
|
+
console.log('');
|
|
269
|
+
console.log(bold(title));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function main() {
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log(bold('Atelier UI Preflight'));
|
|
275
|
+
console.log(dim('Checking your environment for the workshop…'));
|
|
276
|
+
|
|
277
|
+
header('Runtime');
|
|
278
|
+
checkNode();
|
|
279
|
+
checkNpm();
|
|
280
|
+
checkGit();
|
|
281
|
+
|
|
282
|
+
header('Claude Code');
|
|
283
|
+
checkClaudeCli();
|
|
284
|
+
|
|
285
|
+
header('Figma');
|
|
286
|
+
await checkFigmaSetup();
|
|
287
|
+
|
|
288
|
+
header('MCP reachability');
|
|
289
|
+
await checkMcpEndpoints();
|
|
290
|
+
|
|
291
|
+
header('Local ports');
|
|
292
|
+
await checkPorts();
|
|
293
|
+
|
|
294
|
+
// Summary
|
|
295
|
+
const failures = results.filter((r) => r.level === 'fail').length;
|
|
296
|
+
const warnings = results.filter((r) => r.level === 'warn').length;
|
|
297
|
+
const passes = results.filter((r) => r.level === 'ok').length;
|
|
298
|
+
|
|
299
|
+
console.log('');
|
|
300
|
+
if (failures === 0) {
|
|
301
|
+
console.log(
|
|
302
|
+
green(`All hard checks passed`) + dim(` · ${passes} ok, ${warnings} warning(s)`),
|
|
303
|
+
);
|
|
304
|
+
if (warnings > 0) {
|
|
305
|
+
console.log(dim('Warnings are non-blocking — see https://atelier.pieper.io/troubleshooting'));
|
|
306
|
+
}
|
|
307
|
+
console.log('');
|
|
308
|
+
process.exit(0);
|
|
309
|
+
} else {
|
|
310
|
+
console.log(
|
|
311
|
+
red(`${failures} check(s) failed`) + dim(` · ${passes} ok, ${warnings} warning(s)`),
|
|
312
|
+
);
|
|
313
|
+
console.log(dim('Fix the items above, then re-run `npm run preflight`.'));
|
|
314
|
+
console.log(dim('Full troubleshooting guide: https://atelier.pieper.io/troubleshooting'));
|
|
315
|
+
console.log('');
|
|
316
|
+
process.exit(1);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
main().catch((err) => {
|
|
321
|
+
console.error(red('Preflight crashed:'), err);
|
|
322
|
+
process.exit(2);
|
|
323
|
+
});
|
|
@@ -3,7 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.presetGenerator = presetGenerator;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const devkit_1 = require("@nx/devkit");
|
|
6
|
-
const
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
function readTemplate(relativePath) {
|
|
9
|
+
return (0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, 'files', relativePath), 'utf-8');
|
|
10
|
+
}
|
|
11
|
+
const SITE_URL = 'https://atelier.pieper.io';
|
|
7
12
|
function presetGenerator(tree, options) {
|
|
8
13
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
9
14
|
var _a, _b;
|
|
@@ -18,7 +23,6 @@ function presetGenerator(tree, options) {
|
|
|
18
23
|
const appName = `workshop-${framework}`;
|
|
19
24
|
if (framework === 'angular') {
|
|
20
25
|
yield (0, devkit_1.ensurePackage)('@nx/angular', devkit_1.NX_VERSION);
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
22
26
|
const { applicationGenerator: angularAppGenerator } = require('@nx/angular/generators');
|
|
23
27
|
yield angularAppGenerator(tree, {
|
|
24
28
|
name: appName,
|
|
@@ -61,10 +65,15 @@ function presetGenerator(tree, options) {
|
|
|
61
65
|
});
|
|
62
66
|
deps['@atelier-ui/vue'] = 'latest';
|
|
63
67
|
}
|
|
64
|
-
//
|
|
68
|
+
// Copy design tokens into the scaffolded app so attendees can edit them
|
|
69
|
+
// directly. They're not imported from the @atelier-ui/<fw> npm package
|
|
70
|
+
// because (a) those published packages don't ship tokens.css, and (b) a
|
|
71
|
+
// workshop attendee editing colors in node_modules is a bad experience.
|
|
72
|
+
tree.write(`${appName}/src/styles/tokens.css`, readTemplate('styles/tokens.css'));
|
|
73
|
+
// Prepend the tokens import to the app's global stylesheet
|
|
65
74
|
const stylesPath = `${appName}/src/styles.css`;
|
|
66
75
|
const existing = tree.exists(stylesPath) ? ((_b = tree.read(stylesPath, 'utf-8')) !== null && _b !== void 0 ? _b : '') : '';
|
|
67
|
-
tree.write(stylesPath, `@import '
|
|
76
|
+
tree.write(stylesPath, `@import './styles/tokens.css';\n\n${existing}`);
|
|
68
77
|
}
|
|
69
78
|
// Write CLAUDE.md with framework-specific guidance
|
|
70
79
|
const frameworkSections = frameworks
|
|
@@ -93,47 +102,95 @@ function presetGenerator(tree, options) {
|
|
|
93
102
|
return '';
|
|
94
103
|
})
|
|
95
104
|
.join('\n\n');
|
|
105
|
+
const mcpSection = frameworks
|
|
106
|
+
.map((f) => `### \`storybook-${f}\` MCP
|
|
107
|
+
Before using any component:
|
|
108
|
+
1. Call \`list-all-documentation\` to get valid component IDs
|
|
109
|
+
2. Call \`get-documentation\` with the ID — never invent props
|
|
110
|
+
3. Call \`get-documentation-for-story\` for a specific variant
|
|
111
|
+
4. Do not use a component that is not in the docs`)
|
|
112
|
+
.join('\n\n');
|
|
96
113
|
tree.write('CLAUDE.md', `# Atelier UI Workshop
|
|
97
114
|
|
|
98
|
-
This workspace
|
|
115
|
+
This workspace uses Atelier UI for all UI components.
|
|
116
|
+
Full API reference: ${SITE_URL}/llms-full.txt
|
|
99
117
|
|
|
100
|
-
## MCP
|
|
118
|
+
## MCP Servers
|
|
101
119
|
|
|
102
|
-
The
|
|
120
|
+
The servers are pre-configured in \`.mcp.json\` and connect automatically.
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
|---|---|
|
|
106
|
-
| \`get_component_docs(component)\` | Before using any component — returns exact props, types, defaults |
|
|
107
|
-
| \`list_components()\` | To see all 22 available components grouped by category |
|
|
108
|
-
| \`search_components(query)\` | When you know the intent ("form input") but not the component name |
|
|
109
|
-
| \`get_stories(component)\` | To see real usage examples and variants |
|
|
110
|
-
| \`get_theming_guide()\` | Before customising colors, spacing, or dark mode |
|
|
111
|
-
|
|
112
|
-
**Rule:** call the MCP server first, then write code. Never guess prop names.
|
|
122
|
+
${mcpSection}
|
|
113
123
|
|
|
114
124
|
## Component Libraries
|
|
115
125
|
|
|
116
126
|
${frameworkSections}
|
|
117
127
|
|
|
118
|
-
##
|
|
128
|
+
## Design Tokens
|
|
129
|
+
|
|
130
|
+
All colors, spacing, and radii use CSS custom properties. Never use
|
|
131
|
+
hardcoded hex values or pixel sizes — always reference a token.
|
|
119
132
|
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
Key tokens:
|
|
134
|
+
- Colors: --ui-color-primary, --ui-color-text, --ui-color-surface-raised, --ui-color-border
|
|
135
|
+
- Spacing: --ui-spacing-4 (1rem), --ui-spacing-6 (1.5rem), --ui-spacing-8 (2rem)
|
|
136
|
+
- Radius: --ui-radius-sm (0.375rem), --ui-radius-md (0.5rem), --ui-radius-lg (0.75rem)
|
|
137
|
+
|
|
138
|
+
## Rules
|
|
139
|
+
- Prefer component props over custom CSS
|
|
140
|
+
- When custom styling is needed, use --ui-color-* and --ui-spacing-* tokens
|
|
141
|
+
- Do not install other UI component libraries alongside Atelier UI
|
|
142
|
+
- Do not add inline hex colors or hardcoded spacing values
|
|
122
143
|
|
|
123
144
|
## Apps
|
|
124
145
|
|
|
125
146
|
${frameworks.map((f) => `- \`workshop-${f}\` — run with \`npx nx serve workshop-${f}\``).join('\n')}
|
|
126
147
|
|
|
148
|
+
## Troubleshooting
|
|
149
|
+
|
|
150
|
+
Run the preflight self-check to verify your environment:
|
|
151
|
+
|
|
152
|
+
\`\`\`bash
|
|
153
|
+
npm run preflight
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
It checks Node, Claude CLI, \`FIGMA_ACCESS_TOKEN\`, MCP endpoint reachability, and port availability.
|
|
157
|
+
Full troubleshooting guide: ${SITE_URL}/troubleshooting
|
|
158
|
+
${options.figmaMcp
|
|
159
|
+
? `
|
|
160
|
+
## Figma Setup
|
|
161
|
+
|
|
162
|
+
The \`figma-console\` MCP is enabled in \`.mcp.json\`. It needs the Figma Desktop Bridge
|
|
163
|
+
plugin installed in the Figma desktop app before the server can respond.
|
|
164
|
+
|
|
165
|
+
Setup guide: ${SITE_URL}/figma-token
|
|
166
|
+
|
|
167
|
+
A \`FIGMA_ACCESS_TOKEN\` is optional — only required for REST-backed reads (screenshots,
|
|
168
|
+
file exports). The Desktop Bridge covers creation and inspection without a token.
|
|
169
|
+
`
|
|
170
|
+
: ''}
|
|
127
171
|
## Reference
|
|
128
172
|
|
|
129
|
-
- Component browser +
|
|
173
|
+
- Component browser + docs: ${SITE_URL}
|
|
130
174
|
- MCP Playground (inspect tool responses): ${SITE_URL}/mcp
|
|
175
|
+
- CLAUDE.md template: ${SITE_URL}/claude-md
|
|
131
176
|
`);
|
|
132
177
|
// Install selected @atelier-ui/* packages
|
|
133
178
|
const installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, deps, {});
|
|
134
179
|
// Remove the preset package itself — create-nx-workspace adds it automatically
|
|
135
180
|
// but it's a build-time tool and should not be in the workspace's dependencies
|
|
136
181
|
const removePresetTask = (0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@atelier-ui/create-workspace'], []);
|
|
182
|
+
// Write preflight script into the scaffolded workspace
|
|
183
|
+
tree.write('tools/scripts/preflight.mjs', readTemplate('tools/scripts/preflight.mjs'));
|
|
184
|
+
// Add `preflight` npm script to the generated workspace's package.json.
|
|
185
|
+
// create-nx-workspace guarantees package.json exists before the preset runs,
|
|
186
|
+
// so we write unconditionally — a missing package.json here should fail loudly,
|
|
187
|
+
// not silently drop the npm script the workshop docs tell attendees to run.
|
|
188
|
+
(0, devkit_1.updateJson)(tree, 'package.json', (pkg) => {
|
|
189
|
+
var _a;
|
|
190
|
+
pkg.scripts = (_a = pkg.scripts) !== null && _a !== void 0 ? _a : {};
|
|
191
|
+
pkg.scripts.preflight = 'node tools/scripts/preflight.mjs';
|
|
192
|
+
return pkg;
|
|
193
|
+
});
|
|
137
194
|
// Write .claude/settings.json with MCP servers for selected frameworks
|
|
138
195
|
const mcpServers = {
|
|
139
196
|
'nx-mcp': {
|
|
@@ -148,6 +205,18 @@ ${frameworks.map((f) => `- \`workshop-${f}\` — run with \`npx nx serve worksho
|
|
|
148
205
|
url: `${SITE_URL}/storybook-${framework}/mcp`,
|
|
149
206
|
};
|
|
150
207
|
}
|
|
208
|
+
if (options.figmaMcp) {
|
|
209
|
+
// Desktop Bridge plugin (installed separately). FIGMA_ACCESS_TOKEN is
|
|
210
|
+
// optional — only needed for REST-backed reads. See ${SITE_URL}/figma-token.
|
|
211
|
+
mcpServers['figma-console'] = {
|
|
212
|
+
command: 'npx',
|
|
213
|
+
args: ['-y', 'figma-console-mcp@latest'],
|
|
214
|
+
env: {
|
|
215
|
+
FIGMA_ACCESS_TOKEN: '${FIGMA_ACCESS_TOKEN:-}',
|
|
216
|
+
ENABLE_MCP_APPS: 'true',
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
151
220
|
(0, devkit_1.writeJson)(tree, '.mcp.json', { mcpServers });
|
|
152
221
|
// Write README
|
|
153
222
|
tree.write('README.md', `# Atelier UI Workshop
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preset.js","sourceRoot":"","sources":["../../../../../../libs/create-workspace/src/generators/preset/preset.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"preset.js","sourceRoot":"","sources":["../../../../../../libs/create-workspace/src/generators/preset/preset.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
"type": "string",
|
|
17
17
|
"description": "Comma-separated list of frameworks to scaffold: angular,react,vue",
|
|
18
18
|
"default": "angular"
|
|
19
|
+
},
|
|
20
|
+
"figmaMcp": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "Add the figma-console-mcp server (Figma Desktop Bridge) to .mcp.json",
|
|
23
|
+
"default": false
|
|
19
24
|
}
|
|
20
25
|
},
|
|
21
26
|
"required": ["name"]
|