@fragments-sdk/cli 0.11.1 → 0.12.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.
Files changed (86) hide show
  1. package/dist/ai-client-I6MDWNYA.js +21 -0
  2. package/dist/bin.js +275 -368
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-PW7QTQA6.js → chunk-4OC7FTJB.js} +2 -2
  5. package/dist/{chunk-HRFUSSZI.js → chunk-AM4MRTMN.js} +2 -2
  6. package/dist/{chunk-5G3VZH43.js → chunk-GVDSFQ4E.js} +281 -351
  7. package/dist/chunk-GVDSFQ4E.js.map +1 -0
  8. package/dist/chunk-JJ2VRTBU.js +626 -0
  9. package/dist/chunk-JJ2VRTBU.js.map +1 -0
  10. package/dist/{chunk-D5PYOXEI.js → chunk-LVWFOLUZ.js} +148 -13
  11. package/dist/{chunk-D5PYOXEI.js.map → chunk-LVWFOLUZ.js.map} +1 -1
  12. package/dist/{chunk-WXSR2II7.js → chunk-OQKMEFOS.js} +58 -6
  13. package/dist/chunk-OQKMEFOS.js.map +1 -0
  14. package/dist/chunk-SXTKFDCR.js +104 -0
  15. package/dist/chunk-SXTKFDCR.js.map +1 -0
  16. package/dist/chunk-T5OMVL7E.js +443 -0
  17. package/dist/chunk-T5OMVL7E.js.map +1 -0
  18. package/dist/{chunk-ZM4ZQZWZ.js → chunk-TPWGL2XS.js} +39 -37
  19. package/dist/chunk-TPWGL2XS.js.map +1 -0
  20. package/dist/{chunk-OQO55NKV.js → chunk-WFS63PCW.js} +85 -11
  21. package/dist/chunk-WFS63PCW.js.map +1 -0
  22. package/dist/core/index.js +9 -1
  23. package/dist/{discovery-NEOY4MPN.js → discovery-ZJQSXF56.js} +3 -3
  24. package/dist/{generate-FBHSXR3D.js → generate-RJFS2JWA.js} +4 -4
  25. package/dist/index.js +7 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/init-ZSX3NRCZ.js +636 -0
  28. package/dist/init-ZSX3NRCZ.js.map +1 -0
  29. package/dist/mcp-bin.js +2 -2
  30. package/dist/{scan-CJF2DOQW.js → scan-3PMCJ4RB.js} +6 -6
  31. package/dist/scan-generate-SYU4PYZD.js +1115 -0
  32. package/dist/scan-generate-SYU4PYZD.js.map +1 -0
  33. package/dist/{service-TQYWY65E.js → service-VMGNJZ42.js} +3 -3
  34. package/dist/{snapshot-SV2JOFZH.js → snapshot-XOISO2IS.js} +2 -2
  35. package/dist/{static-viewer-NUBFPKWH.js → static-viewer-5GXH2MGE.js} +3 -3
  36. package/dist/static-viewer-5GXH2MGE.js.map +1 -0
  37. package/dist/{test-Z5LVO724.js → test-SI4NSHQX.js} +4 -4
  38. package/dist/{tokens-CE46OTMD.js → tokens-T6SIVUT5.js} +5 -5
  39. package/dist/{viewer-DLLJIMCK.js → viewer-7ZEAFBVN.js} +13 -13
  40. package/package.json +4 -4
  41. package/src/ai-client.ts +156 -0
  42. package/src/bin.ts +44 -2
  43. package/src/build.ts +95 -33
  44. package/src/commands/__tests__/drift-sync.test.ts +252 -0
  45. package/src/commands/__tests__/scan-generate.test.ts +497 -45
  46. package/src/commands/enhance.ts +11 -35
  47. package/src/commands/init.ts +288 -260
  48. package/src/commands/scan-generate.ts +740 -139
  49. package/src/commands/scan.ts +37 -32
  50. package/src/commands/setup.ts +143 -52
  51. package/src/commands/sync.ts +357 -0
  52. package/src/commands/validate.ts +43 -1
  53. package/src/core/component-extractor.test.ts +282 -0
  54. package/src/core/component-extractor.ts +1030 -0
  55. package/src/core/discovery.ts +93 -7
  56. package/src/service/enhance/props-extractor.ts +235 -13
  57. package/src/validators.ts +236 -0
  58. package/dist/chunk-5G3VZH43.js.map +0 -1
  59. package/dist/chunk-OQO55NKV.js.map +0 -1
  60. package/dist/chunk-WXSR2II7.js.map +0 -1
  61. package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
  62. package/dist/init-UFGK5TCN.js +0 -867
  63. package/dist/init-UFGK5TCN.js.map +0 -1
  64. package/dist/scan-generate-SJAN5MVI.js +0 -691
  65. package/dist/scan-generate-SJAN5MVI.js.map +0 -1
  66. package/src/ai.ts +0 -266
  67. package/src/commands/init-framework.ts +0 -414
  68. package/src/mcp/bin.ts +0 -36
  69. package/src/migrate/bin.ts +0 -114
  70. package/src/theme/index.ts +0 -77
  71. package/src/viewer/bin.ts +0 -86
  72. package/src/viewer/cli/health.ts +0 -256
  73. package/src/viewer/cli/index.ts +0 -33
  74. package/src/viewer/cli/scan.ts +0 -124
  75. package/src/viewer/cli/utils.ts +0 -174
  76. /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
  77. /package/dist/{chunk-PW7QTQA6.js.map → chunk-4OC7FTJB.js.map} +0 -0
  78. /package/dist/{chunk-HRFUSSZI.js.map → chunk-AM4MRTMN.js.map} +0 -0
  79. /package/dist/{scan-CJF2DOQW.js.map → discovery-ZJQSXF56.js.map} +0 -0
  80. /package/dist/{generate-FBHSXR3D.js.map → generate-RJFS2JWA.js.map} +0 -0
  81. /package/dist/{service-TQYWY65E.js.map → scan-3PMCJ4RB.js.map} +0 -0
  82. /package/dist/{static-viewer-NUBFPKWH.js.map → service-VMGNJZ42.js.map} +0 -0
  83. /package/dist/{snapshot-SV2JOFZH.js.map → snapshot-XOISO2IS.js.map} +0 -0
  84. /package/dist/{test-Z5LVO724.js.map → test-SI4NSHQX.js.map} +0 -0
  85. /package/dist/{tokens-CE46OTMD.js.map → tokens-T6SIVUT5.js.map} +0 -0
  86. /package/dist/{viewer-DLLJIMCK.js.map → viewer-7ZEAFBVN.js.map} +0 -0
@@ -1,414 +0,0 @@
1
- /**
2
- * Framework detection and auto-configuration for fragments init.
3
- *
4
- * Detects the consumer's framework (Next.js, Vite, Remix, Astro)
5
- * and generates appropriate configuration files.
6
- */
7
-
8
- import { readFile, writeFile, access } from "node:fs/promises";
9
- import { join } from "node:path";
10
- import pc from "picocolors";
11
-
12
- // ============================================
13
- // Types
14
- // ============================================
15
-
16
- export type Framework = "nextjs" | "vite" | "remix" | "astro" | "unknown";
17
-
18
- export interface FrameworkDetection {
19
- framework: Framework;
20
- /** Package that triggered the detection */
21
- detectedBy: string | null;
22
- }
23
-
24
- export interface FrameworkSetupOptions {
25
- /** Project root directory */
26
- projectRoot: string;
27
- /** Override auto-detected framework */
28
- framework?: Framework;
29
- /** Seed overrides for globals.scss generation */
30
- seeds?: {
31
- brand?: string;
32
- neutral?: string;
33
- density?: string;
34
- radiusStyle?: string;
35
- };
36
- }
37
-
38
- export interface FrameworkSetupResult {
39
- framework: Framework;
40
- filesCreated: string[];
41
- packagesToInstall: string[];
42
- configModified: string[];
43
- warnings: string[];
44
- }
45
-
46
- // ============================================
47
- // Framework Detection
48
- // ============================================
49
-
50
- /**
51
- * Detect framework from package.json dependencies
52
- */
53
- export async function detectFramework(
54
- projectRoot: string
55
- ): Promise<FrameworkDetection> {
56
- try {
57
- const pkgPath = join(projectRoot, "package.json");
58
- const pkgContent = await readFile(pkgPath, "utf-8");
59
- const pkg = JSON.parse(pkgContent);
60
-
61
- const allDeps = {
62
- ...pkg.dependencies,
63
- ...pkg.devDependencies,
64
- };
65
-
66
- // Check in order of specificity
67
- if (allDeps["next"]) {
68
- return { framework: "nextjs", detectedBy: "next" };
69
- }
70
- if (allDeps["@remix-run/react"]) {
71
- return { framework: "remix", detectedBy: "@remix-run/react" };
72
- }
73
- if (allDeps["astro"]) {
74
- return { framework: "astro", detectedBy: "astro" };
75
- }
76
- if (allDeps["vite"]) {
77
- return { framework: "vite", detectedBy: "vite" };
78
- }
79
-
80
- return { framework: "unknown", detectedBy: null };
81
- } catch {
82
- return { framework: "unknown", detectedBy: null };
83
- }
84
- }
85
-
86
- // ============================================
87
- // Globals SCSS Generation
88
- // ============================================
89
-
90
- function generateGlobalsSCSS(seeds?: FrameworkSetupOptions["seeds"]): string {
91
- const withClauses: string[] = [];
92
-
93
- if (seeds?.brand) {
94
- withClauses.push(` $fui-brand: ${seeds.brand}`);
95
- }
96
- if (seeds?.neutral) {
97
- withClauses.push(` $fui-neutral: "${seeds.neutral}"`);
98
- }
99
- if (seeds?.density) {
100
- withClauses.push(` $fui-density: "${seeds.density}"`);
101
- }
102
- if (seeds?.radiusStyle) {
103
- withClauses.push(` $fui-radius-style: "${seeds.radiusStyle}"`);
104
- }
105
-
106
- const useStatement =
107
- withClauses.length > 0
108
- ? `@use '@fragments-sdk/ui/styles' with (\n${withClauses.join(",\n")}\n);`
109
- : `@use '@fragments-sdk/ui/styles';`;
110
-
111
- return `// Fragments SDK Global Styles
112
- // Customize seed values to theme the entire design system.
113
- // See: https://usefragments.com/docs/theming
114
- ${useStatement}
115
- `;
116
- }
117
-
118
- // ============================================
119
- // Providers Component Generation
120
- // ============================================
121
-
122
- function generateProviders(): string {
123
- return `'use client';
124
-
125
- import { ThemeProvider } from '@fragments-sdk/ui';
126
-
127
- export function Providers({ children }: { children: React.ReactNode }) {
128
- return (
129
- <ThemeProvider defaultMode="system" attribute="data-theme">
130
- {children}
131
- </ThemeProvider>
132
- );
133
- }
134
- `;
135
- }
136
-
137
- // ============================================
138
- // Per-Framework Configuration
139
- // ============================================
140
-
141
- async function setupNextJS(
142
- projectRoot: string,
143
- options: FrameworkSetupOptions
144
- ): Promise<FrameworkSetupResult> {
145
- const result: FrameworkSetupResult = {
146
- framework: "nextjs",
147
- filesCreated: [],
148
- packagesToInstall: [],
149
- configModified: [],
150
- warnings: [],
151
- };
152
-
153
- // Check if sass is installed
154
- try {
155
- const pkgContent = await readFile(
156
- join(projectRoot, "package.json"),
157
- "utf-8"
158
- );
159
- const pkg = JSON.parse(pkgContent);
160
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
161
- if (!allDeps["sass"]) {
162
- result.packagesToInstall.push("sass");
163
- }
164
- } catch {
165
- // Proceed without checking
166
- }
167
-
168
- // Update next.config if transpilePackages is needed
169
- const nextConfigPaths = [
170
- "next.config.ts",
171
- "next.config.mjs",
172
- "next.config.js",
173
- ];
174
-
175
- for (const configName of nextConfigPaths) {
176
- const configPath = join(projectRoot, configName);
177
- try {
178
- await access(configPath);
179
- const content = await readFile(configPath, "utf-8");
180
-
181
- if (!content.includes("transpilePackages")) {
182
- // Add transpilePackages to the config
183
- if (content.includes("const nextConfig")) {
184
- const updated = content.replace(
185
- /const nextConfig\s*=\s*\{/,
186
- `const nextConfig = {\n transpilePackages: ['@fragments-sdk/ui'],`
187
- );
188
- await writeFile(configPath, updated, "utf-8");
189
- result.configModified.push(configName);
190
- } else {
191
- result.warnings.push(
192
- `Could not auto-modify ${configName}. Add transpilePackages: ['@fragments-sdk/ui'] manually.`
193
- );
194
- }
195
- }
196
- break;
197
- } catch {
198
- continue;
199
- }
200
- }
201
-
202
- // Generate globals.scss
203
- const globalsPath = join(projectRoot, "src", "styles", "globals.scss");
204
- try {
205
- await access(globalsPath);
206
- result.warnings.push(
207
- "src/styles/globals.scss already exists. Skipped generation."
208
- );
209
- } catch {
210
- await writeFile(globalsPath, generateGlobalsSCSS(options.seeds), "utf-8");
211
- result.filesCreated.push("src/styles/globals.scss");
212
- }
213
-
214
- // Generate providers.tsx
215
- const providersPath = join(projectRoot, "src", "providers.tsx");
216
- try {
217
- await access(providersPath);
218
- result.warnings.push("src/providers.tsx already exists. Skipped.");
219
- } catch {
220
- await writeFile(providersPath, generateProviders(), "utf-8");
221
- result.filesCreated.push("src/providers.tsx");
222
- }
223
-
224
- return result;
225
- }
226
-
227
- async function setupVite(
228
- projectRoot: string,
229
- options: FrameworkSetupOptions
230
- ): Promise<FrameworkSetupResult> {
231
- const result: FrameworkSetupResult = {
232
- framework: "vite",
233
- filesCreated: [],
234
- packagesToInstall: [],
235
- configModified: [],
236
- warnings: [],
237
- };
238
-
239
- // Check if sass is installed
240
- try {
241
- const pkgContent = await readFile(
242
- join(projectRoot, "package.json"),
243
- "utf-8"
244
- );
245
- const pkg = JSON.parse(pkgContent);
246
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
247
- if (!allDeps["sass"]) {
248
- result.packagesToInstall.push("sass");
249
- }
250
- } catch {
251
- // Proceed
252
- }
253
-
254
- // Generate globals.scss
255
- const globalsPath = join(projectRoot, "src", "styles", "globals.scss");
256
- try {
257
- await access(globalsPath);
258
- result.warnings.push(
259
- "src/styles/globals.scss already exists. Skipped generation."
260
- );
261
- } catch {
262
- await writeFile(globalsPath, generateGlobalsSCSS(options.seeds), "utf-8");
263
- result.filesCreated.push("src/styles/globals.scss");
264
- }
265
-
266
- // Generate providers.tsx
267
- const providersPath = join(projectRoot, "src", "providers.tsx");
268
- try {
269
- await access(providersPath);
270
- result.warnings.push("src/providers.tsx already exists. Skipped.");
271
- } catch {
272
- await writeFile(providersPath, generateProviders(), "utf-8");
273
- result.filesCreated.push("src/providers.tsx");
274
- }
275
-
276
- return result;
277
- }
278
-
279
- async function setupRemix(
280
- projectRoot: string,
281
- options: FrameworkSetupOptions
282
- ): Promise<FrameworkSetupResult> {
283
- const result: FrameworkSetupResult = {
284
- framework: "remix",
285
- filesCreated: [],
286
- packagesToInstall: [],
287
- configModified: [],
288
- warnings: [],
289
- };
290
-
291
- result.packagesToInstall.push("sass");
292
-
293
- // Generate globals.scss in app/styles
294
- const globalsPath = join(projectRoot, "app", "styles", "globals.scss");
295
- try {
296
- await access(globalsPath);
297
- result.warnings.push(
298
- "app/styles/globals.scss already exists. Skipped generation."
299
- );
300
- } catch {
301
- await writeFile(globalsPath, generateGlobalsSCSS(options.seeds), "utf-8");
302
- result.filesCreated.push("app/styles/globals.scss");
303
- }
304
-
305
- // Generate providers.tsx
306
- const providersPath = join(projectRoot, "app", "providers.tsx");
307
- try {
308
- await access(providersPath);
309
- result.warnings.push("app/providers.tsx already exists. Skipped.");
310
- } catch {
311
- await writeFile(providersPath, generateProviders(), "utf-8");
312
- result.filesCreated.push("app/providers.tsx");
313
- }
314
-
315
- result.warnings.push(
316
- 'Add @fragments-sdk/ui to serverDependenciesToBundle in remix.config if using source imports.'
317
- );
318
-
319
- return result;
320
- }
321
-
322
- async function setupAstro(
323
- projectRoot: string,
324
- options: FrameworkSetupOptions
325
- ): Promise<FrameworkSetupResult> {
326
- const result: FrameworkSetupResult = {
327
- framework: "astro",
328
- filesCreated: [],
329
- packagesToInstall: [],
330
- configModified: [],
331
- warnings: [],
332
- };
333
-
334
- result.packagesToInstall.push("sass");
335
-
336
- // Generate globals.scss
337
- const globalsPath = join(projectRoot, "src", "styles", "globals.scss");
338
- try {
339
- await access(globalsPath);
340
- result.warnings.push(
341
- "src/styles/globals.scss already exists. Skipped generation."
342
- );
343
- } catch {
344
- await writeFile(globalsPath, generateGlobalsSCSS(options.seeds), "utf-8");
345
- result.filesCreated.push("src/styles/globals.scss");
346
- }
347
-
348
- return result;
349
- }
350
-
351
- // ============================================
352
- // Main Setup Function
353
- // ============================================
354
-
355
- /**
356
- * Set up framework-specific configuration for @fragments-sdk/ui
357
- */
358
- export async function setupFramework(
359
- options: FrameworkSetupOptions
360
- ): Promise<FrameworkSetupResult> {
361
- const { projectRoot } = options;
362
-
363
- // Detect or use provided framework
364
- let framework = options.framework;
365
- if (!framework || framework === "unknown") {
366
- const detection = await detectFramework(projectRoot);
367
- framework = detection.framework;
368
-
369
- if (detection.detectedBy) {
370
- console.log(
371
- pc.green(` Detected ${frameworkLabel(framework)}`) +
372
- pc.dim(` (via ${detection.detectedBy})`)
373
- );
374
- }
375
- } else {
376
- console.log(pc.green(` Framework: ${frameworkLabel(framework)}`));
377
- }
378
-
379
- switch (framework) {
380
- case "nextjs":
381
- return setupNextJS(projectRoot, options);
382
- case "vite":
383
- return setupVite(projectRoot, options);
384
- case "remix":
385
- return setupRemix(projectRoot, options);
386
- case "astro":
387
- return setupAstro(projectRoot, options);
388
- default:
389
- return {
390
- framework: "unknown",
391
- filesCreated: [],
392
- packagesToInstall: ["sass"],
393
- configModified: [],
394
- warnings: [
395
- "Could not detect framework. Install sass and import @fragments-sdk/ui/styles manually.",
396
- ],
397
- };
398
- }
399
- }
400
-
401
- function frameworkLabel(framework: Framework): string {
402
- switch (framework) {
403
- case "nextjs":
404
- return "Next.js";
405
- case "vite":
406
- return "Vite";
407
- case "remix":
408
- return "Remix";
409
- case "astro":
410
- return "Astro";
411
- default:
412
- return "Unknown";
413
- }
414
- }
package/src/mcp/bin.ts DELETED
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- import { startMcpServer } from './server.js';
3
-
4
- // Parse command line arguments
5
- const args = process.argv.slice(2);
6
- let projectRoot = process.cwd();
7
- let viewerUrl: string | undefined;
8
-
9
- for (let i = 0; i < args.length; i++) {
10
- const arg = args[i];
11
-
12
- if (arg === '--project-root' || arg === '-p') {
13
- projectRoot = args[++i] ?? projectRoot;
14
- } else if (arg === '--viewer-url' || arg === '-u') {
15
- viewerUrl = args[++i];
16
- } else if (arg === '--help' || arg === '-h') {
17
- console.log(`
18
- Usage: fragments-mcp [options]
19
-
20
- Options:
21
- -p, --project-root <path> Project root directory (default: cwd)
22
- -u, --viewer-url <url> Viewer URL (default: http://localhost:6006)
23
- -h, --help Show this help message
24
- `);
25
- process.exit(0);
26
- }
27
- }
28
-
29
- // Start server
30
- startMcpServer({
31
- projectRoot,
32
- viewerUrl,
33
- }).catch((error) => {
34
- console.error('Failed to start MCP server:', error);
35
- process.exit(1);
36
- });
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * CLI entry point for migration tool.
4
- *
5
- * Can be run standalone or integrated with the main fragments CLI.
6
- */
7
-
8
- import { Command } from "commander";
9
- import pc from "picocolors";
10
- import { readFileSync } from "node:fs";
11
- import { fileURLToPath } from "node:url";
12
- import { dirname, join } from "node:path";
13
- import { BRAND } from "../core/index.js";
14
- import { migrate } from "./migrate.js";
15
-
16
- const __dirname = dirname(fileURLToPath(import.meta.url));
17
- const pkg = JSON.parse(readFileSync(join(__dirname, "../../package.json"), "utf-8")) as { version: string };
18
-
19
- const program = new Command();
20
-
21
- program
22
- .name("fragments-migrate")
23
- .description(`${BRAND.name} Storybook Migration Tool`)
24
- .version(pkg.version);
25
-
26
- program
27
- .command("migrate")
28
- .description("Migrate Storybook stories to Fragments")
29
- .argument("<source>", "Source directory or file containing .stories.tsx files")
30
- .option("-o, --output <dir>", "Output directory (default: same as source)")
31
- .option("--dry-run", "Show what would be generated without writing files")
32
- .option("--overwrite", "Overwrite existing fragment files")
33
- .option("--report", "Generate HTML migration report")
34
- .option("--report-path <path>", "Path for the migration report")
35
- .option("-v, --verbose", "Verbose output")
36
- .action(async (source, options) => {
37
- try {
38
- console.log(pc.cyan(`\n${BRAND.name} Migration Tool\n`));
39
- console.log(pc.dim("Discovering Storybook files...\n"));
40
-
41
- const report = await migrate({
42
- from: source,
43
- to: options.output,
44
- dryRun: options.dryRun,
45
- overwrite: options.overwrite,
46
- report: options.report,
47
- reportPath: options.reportPath,
48
- verbose: options.verbose,
49
- });
50
-
51
- // Print results
52
- if (report.totalStoryFiles === 0) {
53
- console.log(pc.yellow("No story files found.\n"));
54
- console.log(pc.dim("Looking for: *.stories.tsx, *.stories.ts, *.stories.jsx, *.stories.js"));
55
- return;
56
- }
57
-
58
- console.log(pc.dim(`Found ${report.totalStoryFiles} story file(s)\n`));
59
-
60
- // Print each conversion
61
- for (const result of report.results) {
62
- if (result.success) {
63
- console.log(`${pc.green("✓")} ${pc.bold(result.componentName)} → ${result.outputFile}`);
64
- console.log(pc.dim(` ${result.variantCount} variant(s), ${result.todos.length} TODO(s)`));
65
- } else {
66
- console.log(`${pc.red("✗")} ${result.sourceFile}`);
67
- for (const warning of result.warnings) {
68
- console.log(pc.dim(` ${warning}`));
69
- }
70
- }
71
- }
72
-
73
- console.log();
74
-
75
- // Summary
76
- if (report.successfulConversions > 0) {
77
- console.log(pc.green(`✓ Converted ${report.successfulConversions} component(s)`));
78
- }
79
- if (report.failedConversions > 0) {
80
- console.log(pc.red(`✗ Failed ${report.failedConversions} conversion(s)`));
81
- }
82
- console.log(pc.dim(` ${report.totalVariants} variant(s) total`));
83
- console.log(pc.dim(` ${report.totalTodos} TODO(s) need attention`));
84
-
85
- if (options.dryRun) {
86
- console.log(pc.yellow("\n[Dry run - no files were written]"));
87
- }
88
-
89
- if (options.report) {
90
- const reportPath = options.reportPath ?? `${source}/migration-report.html`;
91
- console.log(pc.cyan(`\n📊 Report generated: ${reportPath}`));
92
- }
93
-
94
- // Next steps
95
- console.log(pc.dim("\n───────────────────────────────────────"));
96
- console.log(pc.bold("\nNext steps:"));
97
- console.log(` 1. Review generated ${BRAND.fileExtension} files`);
98
- console.log(` 2. Fill in TODO comments (usage.when, usage.whenNot, etc.)`);
99
- console.log(` 3. Run ${pc.cyan(`${BRAND.cliCommand} build`)} to compile`);
100
- console.log(` 4. Run ${pc.cyan(`${BRAND.cliCommand} dev`)} to view your design system`);
101
- console.log();
102
- } catch (error) {
103
- console.error(pc.red("Error:"), error instanceof Error ? error.message : error);
104
- process.exit(1);
105
- }
106
- });
107
-
108
- // Also support direct execution without subcommand
109
- if (process.argv.length > 2 && !process.argv[2].startsWith("-") && process.argv[2] !== "migrate") {
110
- // Insert "migrate" as the command
111
- process.argv.splice(2, 0, "migrate");
112
- }
113
-
114
- program.parse();
@@ -1,77 +0,0 @@
1
- /**
2
- * Theme Customization Module
3
- *
4
- * Provides theme configuration, validation, serialization, and generation
5
- */
6
-
7
- // Types
8
- export type {
9
- ThemeConfig,
10
- ThemeColors,
11
- ThemeSurfaces,
12
- ThemeText,
13
- ThemeBorders,
14
- ThemeTypography,
15
- ThemeRadius,
16
- ThemeShadows,
17
- ThemeDarkMode,
18
- TokenOutputFormat,
19
- TokenGeneratorOptions,
20
- TokenGeneratorResult,
21
- PresetName,
22
- ContrastPair,
23
- ContrastWarning,
24
- ContrastValidationResult,
25
- } from "./types.js";
26
-
27
- // Schema validation
28
- export {
29
- themeConfigSchema,
30
- themeColorsSchema,
31
- themeSurfacesSchema,
32
- themeTextSchema,
33
- themeBordersSchema,
34
- themeTypographySchema,
35
- themeRadiusSchema,
36
- themeShadowsSchema,
37
- themeDarkModeSchema,
38
- validateThemeConfig,
39
- } from "./schema.js";
40
- export type { ThemeValidationResult } from "./schema.js";
41
-
42
- // Serialization
43
- export {
44
- encodeThemeToUrl,
45
- decodeThemeFromUrl,
46
- compressTheme,
47
- decompressTheme,
48
- } from "./serializer.js";
49
-
50
- // Generation
51
- export {
52
- generateScssTokens,
53
- generateCssTokens,
54
- generateTokenFiles,
55
- validateContrast,
56
- } from "./generator.js";
57
-
58
- // Contrast utilities
59
- export {
60
- parseColor,
61
- relativeLuminance,
62
- contrastRatio,
63
- meetsAA,
64
- meetsAAA,
65
- rgbToHex,
66
- suggestFix,
67
- } from "./contrast.js";
68
- export type { RGB } from "./contrast.js";
69
-
70
- // Presets
71
- export {
72
- DEFAULT_PRESET,
73
- PRESETS,
74
- getPreset,
75
- listPresets,
76
- isValidPresetName,
77
- } from "./presets.js";