@fragments-sdk/cli 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -53,10 +53,10 @@ import "./chunk-Z7EY4VHE.js";
53
53
 
54
54
  // src/bin.ts
55
55
  import { Command } from "commander";
56
- import pc22 from "picocolors";
56
+ import pc23 from "picocolors";
57
57
  import { readFileSync } from "fs";
58
58
  import { fileURLToPath } from "url";
59
- import { dirname as dirname4, join as join10 } from "path";
59
+ import { dirname as dirname4, join as join11 } from "path";
60
60
 
61
61
  // src/commands/validate.ts
62
62
  import pc from "picocolors";
@@ -1811,7 +1811,7 @@ ${BRAND.name} Dev Server
1811
1811
  }
1812
1812
  }
1813
1813
  }
1814
- const { createDevServer } = await import("./viewer-HZK4BSDK.js");
1814
+ const { createDevServer } = await import("./viewer-SBTJDMP7.js");
1815
1815
  console.log(pc7.dim("\nStarting dev server..."));
1816
1816
  const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
1817
1817
  try {
@@ -5363,9 +5363,384 @@ ${pc21.bold("Summary")}`);
5363
5363
  };
5364
5364
  }
5365
5365
 
5366
+ // src/commands/doctor.ts
5367
+ import { readFile as readFile8, access as access3 } from "fs/promises";
5368
+ import { join as join10, resolve as resolve8 } from "path";
5369
+ import pc22 from "picocolors";
5370
+ var VALID_NEUTRALS = ["stone", "ice", "earth", "sand", "fire"];
5371
+ var VALID_DENSITIES = ["compact", "default", "relaxed"];
5372
+ var VALID_RADII = ["sharp", "subtle", "default", "rounded", "pill"];
5373
+ async function checkPackageInstalled(root) {
5374
+ try {
5375
+ const pkgPath = join10(root, "package.json");
5376
+ const content = await readFile8(pkgPath, "utf-8");
5377
+ const pkg2 = JSON.parse(content);
5378
+ const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
5379
+ if (allDeps["@fragments-sdk/ui"]) {
5380
+ return {
5381
+ name: "Package installed",
5382
+ status: "pass",
5383
+ message: `@fragments-sdk/ui ${allDeps["@fragments-sdk/ui"]} found in dependencies`
5384
+ };
5385
+ }
5386
+ return {
5387
+ name: "Package installed",
5388
+ status: "fail",
5389
+ message: "@fragments-sdk/ui not found in package.json",
5390
+ fix: "npm install @fragments-sdk/ui"
5391
+ };
5392
+ } catch {
5393
+ return {
5394
+ name: "Package installed",
5395
+ status: "fail",
5396
+ message: "No package.json found"
5397
+ };
5398
+ }
5399
+ }
5400
+ async function checkStylesImport(root) {
5401
+ const entryPatterns = [
5402
+ "src/main.tsx",
5403
+ "src/main.ts",
5404
+ "src/index.tsx",
5405
+ "src/index.ts",
5406
+ "src/App.tsx",
5407
+ "src/App.ts",
5408
+ "app/layout.tsx",
5409
+ "app/layout.ts",
5410
+ "src/app/layout.tsx",
5411
+ "src/app/layout.ts",
5412
+ "app/root.tsx",
5413
+ "pages/_app.tsx",
5414
+ "pages/_app.ts"
5415
+ ];
5416
+ for (const pattern of entryPatterns) {
5417
+ try {
5418
+ const content = await readFile8(join10(root, pattern), "utf-8");
5419
+ if (content.includes("@fragments-sdk/ui/styles")) {
5420
+ return {
5421
+ name: "Styles import",
5422
+ status: "pass",
5423
+ message: `Found styles import in ${pattern}`
5424
+ };
5425
+ }
5426
+ if (content.includes("@fragments-sdk/ui/globals")) {
5427
+ return {
5428
+ name: "Styles import",
5429
+ status: "warn",
5430
+ message: `${pattern} uses deprecated '@fragments-sdk/ui/globals'. Use '@fragments-sdk/ui/styles' instead`,
5431
+ fix: `Replace '@fragments-sdk/ui/globals' with '@fragments-sdk/ui/styles' in ${pattern}`
5432
+ };
5433
+ }
5434
+ } catch {
5435
+ }
5436
+ }
5437
+ const scssPatterns = [
5438
+ "src/styles/globals.scss",
5439
+ "src/globals.scss",
5440
+ "styles/globals.scss",
5441
+ "app/globals.scss",
5442
+ "src/app/globals.scss",
5443
+ "app/styles/globals.scss"
5444
+ ];
5445
+ for (const pattern of scssPatterns) {
5446
+ try {
5447
+ const content = await readFile8(join10(root, pattern), "utf-8");
5448
+ if (content.includes("@fragments-sdk/ui/styles")) {
5449
+ return {
5450
+ name: "Styles import",
5451
+ status: "pass",
5452
+ message: `Found SCSS @use import in ${pattern}`
5453
+ };
5454
+ }
5455
+ } catch {
5456
+ }
5457
+ }
5458
+ return {
5459
+ name: "Styles import",
5460
+ status: "fail",
5461
+ message: "No @fragments-sdk/ui/styles import found in entry files",
5462
+ fix: "Add `import '@fragments-sdk/ui/styles'` to your app's entry file"
5463
+ };
5464
+ }
5465
+ async function checkThemeProvider(root) {
5466
+ const providerPatterns = [
5467
+ "src/main.tsx",
5468
+ "src/App.tsx",
5469
+ "src/providers.tsx",
5470
+ "app/layout.tsx",
5471
+ "app/providers.tsx",
5472
+ "src/app/layout.tsx",
5473
+ "src/app/providers.tsx",
5474
+ "app/root.tsx",
5475
+ "pages/_app.tsx"
5476
+ ];
5477
+ for (const pattern of providerPatterns) {
5478
+ try {
5479
+ const content = await readFile8(join10(root, pattern), "utf-8");
5480
+ if (content.includes("ThemeProvider")) {
5481
+ if (content.includes("defaultTheme=") || content.includes("defaultTheme =")) {
5482
+ return {
5483
+ name: "ThemeProvider",
5484
+ status: "warn",
5485
+ message: `${pattern} uses deprecated 'defaultTheme' prop. Use 'defaultMode' instead`,
5486
+ fix: `Replace 'defaultTheme' with 'defaultMode' in ${pattern}`
5487
+ };
5488
+ }
5489
+ return {
5490
+ name: "ThemeProvider",
5491
+ status: "pass",
5492
+ message: `ThemeProvider found in ${pattern}`
5493
+ };
5494
+ }
5495
+ } catch {
5496
+ }
5497
+ }
5498
+ return {
5499
+ name: "ThemeProvider",
5500
+ status: "warn",
5501
+ message: "ThemeProvider not found in common entry files (optional but recommended)",
5502
+ fix: 'Wrap your app with <ThemeProvider defaultMode="system">'
5503
+ };
5504
+ }
5505
+ async function checkScssSeeds(root) {
5506
+ const checks = [];
5507
+ const scssPatterns = [
5508
+ "src/styles/globals.scss",
5509
+ "src/globals.scss",
5510
+ "styles/globals.scss",
5511
+ "app/globals.scss",
5512
+ "src/app/globals.scss",
5513
+ "app/styles/globals.scss"
5514
+ ];
5515
+ for (const pattern of scssPatterns) {
5516
+ try {
5517
+ const content = await readFile8(join10(root, pattern), "utf-8");
5518
+ if (!content.includes("@fragments-sdk/ui/styles")) continue;
5519
+ const standalonePattern = /^\$fui-\w+:\s*.+;$/m;
5520
+ if (standalonePattern.test(content) && !content.includes("@use")) {
5521
+ checks.push({
5522
+ name: "SCSS syntax",
5523
+ status: "fail",
5524
+ message: `${pattern} uses standalone $fui- variables. Must use @use...with() syntax`,
5525
+ fix: "@use '@fragments-sdk/ui/styles' with ($fui-brand: #0066ff);"
5526
+ });
5527
+ }
5528
+ const neutralMatch = content.match(/\$fui-neutral:\s*"([^"]+)"/);
5529
+ if (neutralMatch && !VALID_NEUTRALS.includes(neutralMatch[1])) {
5530
+ checks.push({
5531
+ name: "SCSS seed: neutral",
5532
+ status: "fail",
5533
+ message: `Invalid $fui-neutral: "${neutralMatch[1]}" in ${pattern}`,
5534
+ fix: `Valid neutrals: ${VALID_NEUTRALS.join(", ")}`
5535
+ });
5536
+ }
5537
+ const densityMatch = content.match(/\$fui-density:\s*"([^"]+)"/);
5538
+ if (densityMatch && !VALID_DENSITIES.includes(densityMatch[1])) {
5539
+ checks.push({
5540
+ name: "SCSS seed: density",
5541
+ status: "fail",
5542
+ message: `Invalid $fui-density: "${densityMatch[1]}" in ${pattern}`,
5543
+ fix: `Valid densities: ${VALID_DENSITIES.join(", ")}`
5544
+ });
5545
+ }
5546
+ const radiusMatch = content.match(/\$fui-radius-style:\s*"([^"]+)"/);
5547
+ if (radiusMatch && !VALID_RADII.includes(radiusMatch[1])) {
5548
+ checks.push({
5549
+ name: "SCSS seed: radius-style",
5550
+ status: "fail",
5551
+ message: `Invalid $fui-radius-style: "${radiusMatch[1]}" in ${pattern}`,
5552
+ fix: `Valid radius styles: ${VALID_RADII.join(", ")}`
5553
+ });
5554
+ }
5555
+ const brandMatch = content.match(/\$fui-brand:\s*(#[0-9a-fA-F]+)/);
5556
+ if (brandMatch) {
5557
+ const hex = brandMatch[1];
5558
+ if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) {
5559
+ checks.push({
5560
+ name: "SCSS seed: brand",
5561
+ status: "fail",
5562
+ message: `Invalid $fui-brand color: "${hex}" in ${pattern}`,
5563
+ fix: "Must be a valid hex color (e.g., #0066ff)"
5564
+ });
5565
+ }
5566
+ }
5567
+ if (checks.length === 0) {
5568
+ checks.push({
5569
+ name: "SCSS seeds",
5570
+ status: "pass",
5571
+ message: `Seed values in ${pattern} are valid`
5572
+ });
5573
+ }
5574
+ return checks;
5575
+ } catch {
5576
+ }
5577
+ }
5578
+ checks.push({
5579
+ name: "SCSS seeds",
5580
+ status: "pass",
5581
+ message: "No custom SCSS seeds configured (using defaults)"
5582
+ });
5583
+ return checks;
5584
+ }
5585
+ async function checkPeerDeps(root) {
5586
+ const checks = [];
5587
+ try {
5588
+ const pkgPath = join10(root, "package.json");
5589
+ const content = await readFile8(pkgPath, "utf-8");
5590
+ const pkg2 = JSON.parse(content);
5591
+ const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
5592
+ if (!allDeps["react"]) {
5593
+ checks.push({
5594
+ name: "Peer dep: react",
5595
+ status: "fail",
5596
+ message: "react not found in dependencies (required)",
5597
+ fix: "npm install react react-dom"
5598
+ });
5599
+ } else {
5600
+ checks.push({
5601
+ name: "Peer dep: react",
5602
+ status: "pass",
5603
+ message: `react ${allDeps["react"]} installed`
5604
+ });
5605
+ }
5606
+ if (!allDeps["sass"]) {
5607
+ checks.push({
5608
+ name: "Peer dep: sass",
5609
+ status: "warn",
5610
+ message: "sass not installed (needed for custom SCSS theming)",
5611
+ fix: "npm install -D sass"
5612
+ });
5613
+ }
5614
+ const optionalPeers = [
5615
+ { pkg: "recharts", components: "Chart" },
5616
+ { pkg: "shiki", components: "CodeBlock" },
5617
+ { pkg: "react-day-picker", components: "DatePicker" },
5618
+ { pkg: "@tanstack/react-table", components: "DataTable" }
5619
+ ];
5620
+ for (const peer of optionalPeers) {
5621
+ if (allDeps[peer.pkg]) {
5622
+ checks.push({
5623
+ name: `Optional dep: ${peer.pkg}`,
5624
+ status: "pass",
5625
+ message: `${peer.pkg} installed (enables ${peer.components})`
5626
+ });
5627
+ }
5628
+ }
5629
+ } catch {
5630
+ checks.push({
5631
+ name: "Peer dependencies",
5632
+ status: "fail",
5633
+ message: "Could not read package.json"
5634
+ });
5635
+ }
5636
+ return checks;
5637
+ }
5638
+ async function checkMcpConfig(root) {
5639
+ const mcpConfigPaths = [
5640
+ ".mcp.json",
5641
+ ".cursor/mcp.json",
5642
+ ".vscode/mcp.json"
5643
+ ];
5644
+ for (const configPath of mcpConfigPaths) {
5645
+ try {
5646
+ const fullPath = join10(root, configPath);
5647
+ const content = await readFile8(fullPath, "utf-8");
5648
+ const config = JSON.parse(content);
5649
+ const servers = config.mcpServers || config.servers || {};
5650
+ const hasFragments = Object.values(servers).some((server) => {
5651
+ const s = server;
5652
+ return s.args?.some((arg) => arg.includes("@fragments-sdk/mcp")) || s.command?.includes("fragments");
5653
+ });
5654
+ if (hasFragments) {
5655
+ return {
5656
+ name: "MCP configuration",
5657
+ status: "pass",
5658
+ message: `Fragments MCP server configured in ${configPath}`
5659
+ };
5660
+ }
5661
+ } catch {
5662
+ }
5663
+ }
5664
+ return {
5665
+ name: "MCP configuration",
5666
+ status: "warn",
5667
+ message: "No Fragments MCP server configuration found (optional)",
5668
+ fix: "Run `fragments init` or add @fragments-sdk/mcp to your MCP config"
5669
+ };
5670
+ }
5671
+ async function checkTypeScript(root) {
5672
+ try {
5673
+ const tsconfigPath = join10(root, "tsconfig.json");
5674
+ await access3(tsconfigPath);
5675
+ return {
5676
+ name: "TypeScript",
5677
+ status: "pass",
5678
+ message: "tsconfig.json found"
5679
+ };
5680
+ } catch {
5681
+ return {
5682
+ name: "TypeScript",
5683
+ status: "warn",
5684
+ message: "No tsconfig.json found (TypeScript recommended but not required)"
5685
+ };
5686
+ }
5687
+ }
5688
+ async function doctor(options = {}) {
5689
+ const root = resolve8(options.root ?? process.cwd());
5690
+ const checks = [];
5691
+ if (!options.json) {
5692
+ console.log(pc22.cyan(`
5693
+ ${BRAND.name} Doctor
5694
+ `));
5695
+ console.log(pc22.dim(`Checking project at ${root}
5696
+ `));
5697
+ }
5698
+ checks.push(await checkPackageInstalled(root));
5699
+ checks.push(await checkStylesImport(root));
5700
+ checks.push(await checkThemeProvider(root));
5701
+ checks.push(...await checkScssSeeds(root));
5702
+ checks.push(...await checkPeerDeps(root));
5703
+ checks.push(await checkMcpConfig(root));
5704
+ checks.push(await checkTypeScript(root));
5705
+ const passed = checks.filter((c) => c.status === "pass").length;
5706
+ const warned = checks.filter((c) => c.status === "warn").length;
5707
+ const failed = checks.filter((c) => c.status === "fail").length;
5708
+ const result = {
5709
+ success: failed === 0,
5710
+ checks,
5711
+ passed,
5712
+ warned,
5713
+ failed
5714
+ };
5715
+ if (options.json) {
5716
+ console.log(JSON.stringify(result, null, 2));
5717
+ } else {
5718
+ for (const check of checks) {
5719
+ const icon = check.status === "pass" ? pc22.green("\u2713") : check.status === "warn" ? pc22.yellow("!") : pc22.red("\u2717");
5720
+ const msg = check.status === "pass" ? check.message : check.status === "warn" ? pc22.yellow(check.message) : pc22.red(check.message);
5721
+ console.log(` ${icon} ${pc22.bold(check.name)}: ${msg}`);
5722
+ if (check.fix && check.status !== "pass") {
5723
+ console.log(pc22.dim(` \u2192 ${check.fix}`));
5724
+ }
5725
+ }
5726
+ console.log();
5727
+ if (failed === 0 && warned === 0) {
5728
+ console.log(pc22.green(`\u2713 All ${passed} checks passed \u2014 your setup looks great!`));
5729
+ } else if (failed === 0) {
5730
+ console.log(pc22.green(`\u2713 ${passed} passed`) + pc22.yellow(`, ${warned} warning(s)`));
5731
+ } else {
5732
+ console.log(
5733
+ pc22.red(`\u2717 ${failed} failed`) + (warned > 0 ? pc22.yellow(`, ${warned} warning(s)`) : "") + pc22.dim(`, ${passed} passed`)
5734
+ );
5735
+ }
5736
+ console.log();
5737
+ }
5738
+ return result;
5739
+ }
5740
+
5366
5741
  // src/bin.ts
5367
5742
  var __dirname = dirname4(fileURLToPath(import.meta.url));
5368
- var pkg = JSON.parse(readFileSync(join10(__dirname, "../package.json"), "utf-8"));
5743
+ var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
5369
5744
  var program = new Command();
5370
5745
  program.name(BRAND.cliCommand).description(`${BRAND.name} - Design system documentation and compliance tool`).version(pkg.version);
5371
5746
  program.command("validate").description("Validate fragment files").option("-c, --config <path>", "Path to config file").option("--schema", "Validate fragment schema only").option("--coverage", "Validate coverage only").option("--snippets", "Validate snippet/render policy only").option("--snippet-mode <mode>", "Override snippet policy mode (warn|error)").option("--component-start <name>", "Start component name for alphabetical snippet batch validation").option("--component-limit <n>", "Component count for alphabetical snippet batch validation", (value) => Number.parseInt(value, 10)).action(async (options) => {
@@ -5375,7 +5750,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
5375
5750
  process.exit(1);
5376
5751
  }
5377
5752
  } catch (error) {
5378
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5753
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5379
5754
  process.exit(1);
5380
5755
  }
5381
5756
  });
@@ -5395,7 +5770,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
5395
5770
  process.exit(1);
5396
5771
  }
5397
5772
  } catch (error) {
5398
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5773
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5399
5774
  process.exit(1);
5400
5775
  }
5401
5776
  });
@@ -5414,7 +5789,7 @@ program.command("context").description("Generate AI-ready context for your desig
5414
5789
  process.exit(1);
5415
5790
  }
5416
5791
  } catch (error) {
5417
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5792
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5418
5793
  process.exit(1);
5419
5794
  }
5420
5795
  });
@@ -5441,7 +5816,7 @@ program.command("ai").description("Generate context optimized for AI assistants
5441
5816
  }
5442
5817
  }
5443
5818
  } catch (error) {
5444
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5819
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5445
5820
  process.exit(1);
5446
5821
  }
5447
5822
  });
@@ -5449,7 +5824,7 @@ program.command("list").description("List all discovered fragment files").option
5449
5824
  try {
5450
5825
  await list(options);
5451
5826
  } catch (error) {
5452
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5827
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5453
5828
  process.exit(1);
5454
5829
  }
5455
5830
  });
@@ -5457,7 +5832,7 @@ program.command("reset").description("Reset to initial state (delete all generat
5457
5832
  try {
5458
5833
  await reset(options);
5459
5834
  } catch (error) {
5460
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5835
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5461
5836
  process.exit(1);
5462
5837
  }
5463
5838
  });
@@ -5471,7 +5846,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
5471
5846
  variants: options.variants
5472
5847
  });
5473
5848
  } catch (error) {
5474
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5849
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5475
5850
  process.exit(1);
5476
5851
  }
5477
5852
  });
@@ -5486,7 +5861,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
5486
5861
  exclude: options.exclude
5487
5862
  });
5488
5863
  } catch (error) {
5489
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5864
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5490
5865
  process.exit(1);
5491
5866
  }
5492
5867
  });
@@ -5501,9 +5876,9 @@ program.command("dev").description("Start the development server with live compo
5501
5876
  skipBuild: options.skipBuild
5502
5877
  });
5503
5878
  } catch (error) {
5504
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5879
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5505
5880
  if (error instanceof Error && error.stack) {
5506
- console.error(pc22.dim(error.stack));
5881
+ console.error(pc23.dim(error.stack));
5507
5882
  }
5508
5883
  process.exit(1);
5509
5884
  }
@@ -5524,7 +5899,7 @@ program.command("screenshot").description("Capture screenshots of component vari
5524
5899
  process.exit(1);
5525
5900
  }
5526
5901
  } catch (error) {
5527
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5902
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5528
5903
  process.exit(1);
5529
5904
  }
5530
5905
  });
@@ -5543,7 +5918,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
5543
5918
  process.exit(1);
5544
5919
  }
5545
5920
  } catch (error) {
5546
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5921
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5547
5922
  process.exit(1);
5548
5923
  }
5549
5924
  });
@@ -5562,8 +5937,8 @@ program.command("compare").argument("[component]", "Component name to compare").
5562
5937
  process.exit(1);
5563
5938
  }
5564
5939
  } catch (error) {
5565
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5566
- console.log(pc22.dim(`
5940
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5941
+ console.log(pc23.dim(`
5567
5942
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5568
5943
  process.exit(1);
5569
5944
  }
@@ -5582,7 +5957,7 @@ program.command("analyze").description("Analyze design system and generate repor
5582
5957
  process.exit(1);
5583
5958
  }
5584
5959
  } catch (error) {
5585
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5960
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5586
5961
  process.exit(1);
5587
5962
  }
5588
5963
  });
@@ -5601,7 +5976,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
5601
5976
  if (options.ci) {
5602
5977
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
5603
5978
  } else {
5604
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5979
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5605
5980
  }
5606
5981
  process.exit(1);
5607
5982
  }
@@ -5618,7 +5993,7 @@ program.command("audit").description("Scan all fragments and show compliance met
5618
5993
  if (options.json) {
5619
5994
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
5620
5995
  } else {
5621
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5996
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5622
5997
  }
5623
5998
  process.exit(1);
5624
5999
  }
@@ -5640,7 +6015,7 @@ program.command("a11y").description("Run accessibility checks on all component v
5640
6015
  if (options.json) {
5641
6016
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
5642
6017
  } else {
5643
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6018
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5644
6019
  }
5645
6020
  process.exit(1);
5646
6021
  }
@@ -5663,7 +6038,7 @@ program.command("enhance").description("AI-powered documentation generation from
5663
6038
  if (options.format === "json") {
5664
6039
  console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
5665
6040
  } else {
5666
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6041
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5667
6042
  }
5668
6043
  process.exit(1);
5669
6044
  }
@@ -5684,7 +6059,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
5684
6059
  process.exit(1);
5685
6060
  }
5686
6061
  } catch (error) {
5687
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6062
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5688
6063
  process.exit(1);
5689
6064
  }
5690
6065
  });
@@ -5697,7 +6072,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
5697
6072
  format: options.format
5698
6073
  });
5699
6074
  } catch (error) {
5700
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6075
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5701
6076
  process.exit(1);
5702
6077
  }
5703
6078
  });
@@ -5709,7 +6084,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
5709
6084
  json: options.json
5710
6085
  });
5711
6086
  } catch (error) {
5712
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6087
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5713
6088
  process.exit(1);
5714
6089
  }
5715
6090
  });
@@ -5723,9 +6098,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
5723
6098
  port: options.port
5724
6099
  });
5725
6100
  } catch (error) {
5726
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6101
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5727
6102
  if (action === "update") {
5728
- console.log(pc22.dim(`
6103
+ console.log(pc23.dim(`
5729
6104
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5730
6105
  }
5731
6106
  process.exit(1);
@@ -5738,22 +6113,22 @@ program.command("view").description(`Generate a static HTML viewer for ${BRAND.o
5738
6113
  const path = await import("path");
5739
6114
  const inputPath = path.resolve(process.cwd(), options.input);
5740
6115
  const outputPath = path.resolve(process.cwd(), options.output);
5741
- console.log(pc22.cyan(`
6116
+ console.log(pc23.cyan(`
5742
6117
  ${BRAND.name} Viewer Generator
5743
6118
  `));
5744
6119
  try {
5745
6120
  await fs2.access(inputPath);
5746
6121
  } catch {
5747
- console.log(pc22.red(`Error: ${options.input} not found.`));
5748
- console.log(pc22.dim(`
5749
- Run ${pc22.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
6122
+ console.log(pc23.red(`Error: ${options.input} not found.`));
6123
+ console.log(pc23.dim(`
6124
+ Run ${pc23.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5750
6125
  `));
5751
6126
  process.exit(1);
5752
6127
  }
5753
- console.log(pc22.dim(`Reading: ${options.input}`));
6128
+ console.log(pc23.dim(`Reading: ${options.input}`));
5754
6129
  const html = await generateViewerFromJson(inputPath);
5755
6130
  await fs2.writeFile(outputPath, html);
5756
- console.log(pc22.green(`
6131
+ console.log(pc23.green(`
5757
6132
  \u2713 Generated: ${options.output}
5758
6133
  `));
5759
6134
  if (options.open) {
@@ -5762,7 +6137,7 @@ Run ${pc22.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5762
6137
  exec(`${openCmd} "${outputPath}"`);
5763
6138
  }
5764
6139
  } catch (error) {
5765
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6140
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5766
6141
  process.exit(1);
5767
6142
  }
5768
6143
  });
@@ -5775,27 +6150,27 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
5775
6150
  component: options.component
5776
6151
  });
5777
6152
  } catch (error) {
5778
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6153
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5779
6154
  process.exit(1);
5780
6155
  }
5781
6156
  });
5782
6157
  program.command("init").description("Initialize fragments in a project (interactive by default)").option("--force", "Overwrite existing config").option("-y, --yes", "Non-interactive mode - auto-detect and use defaults").action(async (options) => {
5783
6158
  try {
5784
- const { init } = await import("./init-KFYN37ZY.js");
6159
+ const { init } = await import("./init-KSAAS7X3.js");
5785
6160
  const result = await init({
5786
6161
  projectRoot: process.cwd(),
5787
6162
  force: options.force,
5788
6163
  yes: options.yes
5789
6164
  });
5790
6165
  if (!result.success) {
5791
- console.error(pc22.red("\nInit failed with errors:"));
6166
+ console.error(pc23.red("\nInit failed with errors:"));
5792
6167
  for (const error of result.errors) {
5793
- console.error(pc22.red(` - ${error}`));
6168
+ console.error(pc23.red(` - ${error}`));
5794
6169
  }
5795
6170
  process.exit(1);
5796
6171
  }
5797
6172
  } catch (error) {
5798
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6173
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5799
6174
  process.exit(1);
5800
6175
  }
5801
6176
  });
@@ -5814,7 +6189,7 @@ program.command("tokens").description("Discover and list design tokens from CSS/
5814
6189
  process.exit(1);
5815
6190
  }
5816
6191
  } catch (error) {
5817
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6192
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5818
6193
  process.exit(1);
5819
6194
  }
5820
6195
  });
@@ -5828,11 +6203,11 @@ program.command("generate").description("Generate fragment files from component
5828
6203
  componentPattern: options.pattern
5829
6204
  });
5830
6205
  if (!result.success) {
5831
- console.error(pc22.red("\nGenerate completed with errors"));
6206
+ console.error(pc23.red("\nGenerate completed with errors"));
5832
6207
  process.exit(1);
5833
6208
  }
5834
6209
  } catch (error) {
5835
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6210
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5836
6211
  process.exit(1);
5837
6212
  }
5838
6213
  });
@@ -5840,7 +6215,7 @@ program.command("graph").description("Query the component relationship graph").a
5840
6215
  try {
5841
6216
  await graph(component, options);
5842
6217
  } catch (error) {
5843
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6218
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5844
6219
  process.exit(1);
5845
6220
  }
5846
6221
  });
@@ -5858,7 +6233,7 @@ program.command("perf").description("Profile component bundle sizes and performa
5858
6233
  process.exit(1);
5859
6234
  }
5860
6235
  } catch (error) {
5861
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6236
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5862
6237
  process.exit(1);
5863
6238
  }
5864
6239
  });
@@ -5898,7 +6273,22 @@ program.command("test").description("Run interaction tests for fragments with pl
5898
6273
  });
5899
6274
  process.exit(exitCode);
5900
6275
  } catch (error) {
5901
- console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
6276
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
6277
+ process.exit(1);
6278
+ }
6279
+ });
6280
+ program.command("doctor").description("Diagnose design system configuration issues").option("--root <dir>", "Project root directory", process.cwd()).option("--json", "Output results as JSON").option("--fix", "Auto-fix issues where possible").action(async (options) => {
6281
+ try {
6282
+ const result = await doctor({
6283
+ root: options.root,
6284
+ json: options.json,
6285
+ fix: options.fix
6286
+ });
6287
+ if (!result.success) {
6288
+ process.exit(1);
6289
+ }
6290
+ } catch (error) {
6291
+ console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
5902
6292
  process.exit(1);
5903
6293
  }
5904
6294
  });