@fragments-sdk/cli 0.6.0 → 0.7.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.
Files changed (49) hide show
  1. package/dist/bin.js +294 -50
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-D35RGPAG.js → chunk-7OPWMLOE.js} +435 -19
  4. package/dist/chunk-7OPWMLOE.js.map +1 -0
  5. package/dist/{chunk-SSLQXHNX.js → chunk-CVXKXVOY.js} +1 -1
  6. package/dist/{chunk-SSLQXHNX.js.map → chunk-CVXKXVOY.js.map} +1 -1
  7. package/dist/{chunk-Q7GOHVOK.js → chunk-TJ34N7C7.js} +39 -2
  8. package/dist/{chunk-Q7GOHVOK.js.map → chunk-TJ34N7C7.js.map} +1 -1
  9. package/dist/{chunk-F7ITZPDJ.js → chunk-XHUDJNN3.js} +2 -2
  10. package/dist/{core-SKRPJQZG.js → core-W2HYIQW6.js} +2 -2
  11. package/dist/{generate-7AF7WRVK.js → generate-LMTISDIJ.js} +3 -3
  12. package/dist/index.js +3 -3
  13. package/dist/{init-WKGDPYI4.js → init-7CHRKQ7P.js} +3 -3
  14. package/dist/mcp-bin.js +2 -2
  15. package/dist/{scan-K6JNMCGM.js → scan-WY23TJCP.js} +4 -4
  16. package/dist/{service-F3E4JJM7.js → service-T2L7VLTE.js} +2 -2
  17. package/dist/{static-viewer-4LQZ5AGA.js → static-viewer-GBR7YNF3.js} +2 -2
  18. package/dist/{test-CJDNJTPZ.js → test-OJRXNDO2.js} +2 -2
  19. package/dist/{tokens-JAJABYXP.js → tokens-3BWDESVM.js} +3 -3
  20. package/dist/{viewer-R3Q6WAMJ.js → viewer-SUFOISZM.js} +12 -12
  21. package/package.json +2 -2
  22. package/src/bin.ts +23 -0
  23. package/src/build.ts +43 -0
  24. package/src/commands/graph.ts +274 -0
  25. package/src/core/composition.ts +64 -1
  26. package/src/core/graph-extractor.test.ts +542 -0
  27. package/src/core/graph-extractor.ts +601 -0
  28. package/src/core/importAnalyzer.ts +5 -0
  29. package/src/viewer/components/App.tsx +128 -30
  30. package/src/viewer/components/Icons.tsx +53 -1
  31. package/src/viewer/components/Layout.tsx +7 -3
  32. package/src/viewer/components/LeftSidebar.tsx +65 -87
  33. package/src/viewer/components/PreviewFrameHost.tsx +30 -1
  34. package/src/viewer/components/PreviewToolbar.tsx +57 -10
  35. package/src/viewer/components/ViewportSelector.tsx +56 -45
  36. package/src/viewer/constants/ui.ts +4 -4
  37. package/src/viewer/preview-frame.html +22 -13
  38. package/src/viewer/styles/globals.css +42 -81
  39. package/dist/chunk-D35RGPAG.js.map +0 -1
  40. /package/dist/{chunk-F7ITZPDJ.js.map → chunk-XHUDJNN3.js.map} +0 -0
  41. /package/dist/{core-SKRPJQZG.js.map → core-W2HYIQW6.js.map} +0 -0
  42. /package/dist/{generate-7AF7WRVK.js.map → generate-LMTISDIJ.js.map} +0 -0
  43. /package/dist/{init-WKGDPYI4.js.map → init-7CHRKQ7P.js.map} +0 -0
  44. /package/dist/{scan-K6JNMCGM.js.map → scan-WY23TJCP.js.map} +0 -0
  45. /package/dist/{service-F3E4JJM7.js.map → service-T2L7VLTE.js.map} +0 -0
  46. /package/dist/{static-viewer-4LQZ5AGA.js.map → static-viewer-GBR7YNF3.js.map} +0 -0
  47. /package/dist/{test-CJDNJTPZ.js.map → test-OJRXNDO2.js.map} +0 -0
  48. /package/dist/{tokens-JAJABYXP.js.map → tokens-3BWDESVM.js.map} +0 -0
  49. /package/dist/{viewer-R3Q6WAMJ.js.map → viewer-SUFOISZM.js.map} +0 -0
package/dist/bin.js CHANGED
@@ -9,10 +9,10 @@ import {
9
9
  validateAll,
10
10
  validateCoverage,
11
11
  validateSchema
12
- } from "./chunk-D35RGPAG.js";
12
+ } from "./chunk-7OPWMLOE.js";
13
13
  import {
14
14
  scan
15
- } from "./chunk-F7ITZPDJ.js";
15
+ } from "./chunk-XHUDJNN3.js";
16
16
  import {
17
17
  FigmaClient,
18
18
  StorageManager,
@@ -33,17 +33,17 @@ import {
33
33
  discoverSegmentFiles,
34
34
  loadConfig,
35
35
  loadSegmentFile
36
- } from "./chunk-SSLQXHNX.js";
36
+ } from "./chunk-CVXKXVOY.js";
37
37
  import {
38
38
  generateContext
39
- } from "./chunk-Q7GOHVOK.js";
39
+ } from "./chunk-TJ34N7C7.js";
40
40
  import {
41
41
  BRAND
42
42
  } from "./chunk-6JBGU74P.js";
43
43
 
44
44
  // src/bin.ts
45
45
  import { Command } from "commander";
46
- import pc20 from "picocolors";
46
+ import pc21 from "picocolors";
47
47
  import { readFileSync } from "fs";
48
48
  import { fileURLToPath } from "url";
49
49
  import { dirname as dirname4, join as join10 } from "path";
@@ -1785,7 +1785,7 @@ ${BRAND.name} Dev Server
1785
1785
  }
1786
1786
  }
1787
1787
  }
1788
- const { createDevServer } = await import("./viewer-R3Q6WAMJ.js");
1788
+ const { createDevServer } = await import("./viewer-SUFOISZM.js");
1789
1789
  console.log(pc7.dim("\nStarting dev server..."));
1790
1790
  const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
1791
1791
  try {
@@ -4944,6 +4944,242 @@ ${whenNotItems}
4944
4944
  }
4945
4945
  }
4946
4946
 
4947
+ // src/commands/graph.ts
4948
+ import pc20 from "picocolors";
4949
+ import { readFile as readFile6 } from "fs/promises";
4950
+ import { resolve as resolve6 } from "path";
4951
+ import {
4952
+ ComponentGraphEngine,
4953
+ deserializeGraph
4954
+ } from "@fragments-sdk/context/graph";
4955
+ async function graph(component, options) {
4956
+ const { config, configDir } = await loadConfig(options.config);
4957
+ const outputPath = resolve6(configDir, config.outFile ?? BRAND.outFile);
4958
+ let data;
4959
+ try {
4960
+ const content = await readFile6(outputPath, "utf-8");
4961
+ data = JSON.parse(content);
4962
+ } catch {
4963
+ console.error(
4964
+ pc20.red(`Error: Could not load ${BRAND.outFile}. Run \`${BRAND.cliCommand} build\` first.`)
4965
+ );
4966
+ process.exit(1);
4967
+ }
4968
+ if (!data.graph) {
4969
+ console.error(
4970
+ pc20.red(`Error: No graph data in ${BRAND.outFile}. Rebuild with the latest CLI.`)
4971
+ );
4972
+ process.exit(1);
4973
+ }
4974
+ const graph2 = deserializeGraph(data.graph);
4975
+ const blocks = data.blocks ? Object.fromEntries(
4976
+ Object.entries(data.blocks).map(([k, v]) => [k, { components: v.components }])
4977
+ ) : void 0;
4978
+ const engine = new ComponentGraphEngine(graph2, blocks);
4979
+ const mode = options.mode ?? (component ? "dependencies" : "health");
4980
+ const format = options.format ?? "table";
4981
+ const edgeTypes = options.edgeTypes ? options.edgeTypes.split(",") : void 0;
4982
+ const needsComponent = ["dependencies", "dependents", "impact", "path", "composition", "alternatives"];
4983
+ if (needsComponent.includes(mode) && !component) {
4984
+ console.error(pc20.red(`Error: "${mode}" mode requires a component name.`));
4985
+ process.exit(1);
4986
+ }
4987
+ if (component && !engine.hasNode(component)) {
4988
+ console.error(pc20.red(`Error: Component "${component}" not found in graph.`));
4989
+ process.exit(1);
4990
+ }
4991
+ switch (mode) {
4992
+ case "health": {
4993
+ const health = engine.getHealth();
4994
+ if (format === "json") {
4995
+ console.log(JSON.stringify(health, null, 2));
4996
+ return;
4997
+ }
4998
+ console.log(pc20.bold("\nComponent Graph Health\n"));
4999
+ console.log(` ${pc20.cyan("Nodes:")} ${health.nodeCount}`);
5000
+ console.log(` ${pc20.cyan("Edges:")} ${health.edgeCount}`);
5001
+ console.log(` ${pc20.cyan("Avg degree:")} ${health.averageDegree}`);
5002
+ console.log(` ${pc20.cyan("Islands:")} ${health.connectedComponents.length}`);
5003
+ console.log(` ${pc20.cyan("Coverage:")} ${health.compositionCoverage}% in blocks`);
5004
+ console.log(` ${pc20.cyan("Orphans:")} ${health.orphans.length > 0 ? health.orphans.join(", ") : pc20.green("none")}`);
5005
+ if (health.hubs.length > 0) {
5006
+ console.log(`
5007
+ ${pc20.bold("Top hubs:")}`);
5008
+ for (const hub of health.hubs.slice(0, 5)) {
5009
+ console.log(` ${pc20.yellow(hub.name)} \u2014 ${hub.degree} connections`);
5010
+ }
5011
+ }
5012
+ console.log();
5013
+ break;
5014
+ }
5015
+ case "dependencies": {
5016
+ const deps = engine.dependencies(component, edgeTypes);
5017
+ if (format === "json") {
5018
+ console.log(JSON.stringify({ component, dependencies: deps }, null, 2));
5019
+ return;
5020
+ }
5021
+ console.log(pc20.bold(`
5022
+ Dependencies of ${component}
5023
+ `));
5024
+ if (deps.length === 0) {
5025
+ console.log(" No outgoing dependencies.");
5026
+ } else {
5027
+ for (const dep of deps) {
5028
+ console.log(` ${pc20.yellow(dep.target)} ${pc20.dim(`(${dep.type})`)}${dep.note ? ` \u2014 ${dep.note}` : ""}`);
5029
+ }
5030
+ }
5031
+ console.log();
5032
+ break;
5033
+ }
5034
+ case "dependents": {
5035
+ const deps = engine.dependents(component, edgeTypes);
5036
+ if (format === "json") {
5037
+ console.log(JSON.stringify({ component, dependents: deps }, null, 2));
5038
+ return;
5039
+ }
5040
+ console.log(pc20.bold(`
5041
+ Dependents of ${component}
5042
+ `));
5043
+ if (deps.length === 0) {
5044
+ console.log(" No incoming dependents.");
5045
+ } else {
5046
+ for (const dep of deps) {
5047
+ console.log(` ${pc20.yellow(dep.source)} ${pc20.dim(`(${dep.type})`)}${dep.note ? ` \u2014 ${dep.note}` : ""}`);
5048
+ }
5049
+ }
5050
+ console.log();
5051
+ break;
5052
+ }
5053
+ case "impact": {
5054
+ const result = engine.impact(component, options.depth ?? 3);
5055
+ if (format === "json") {
5056
+ console.log(JSON.stringify(result, null, 2));
5057
+ return;
5058
+ }
5059
+ console.log(pc20.bold(`
5060
+ Impact analysis: ${component}
5061
+ `));
5062
+ console.log(` ${pc20.red(`${result.totalAffected}`)} affected components, ${pc20.red(`${result.affectedBlocks.length}`)} affected blocks
5063
+ `);
5064
+ if (result.affected.length > 0) {
5065
+ console.log(` ${pc20.bold("Affected components:")}`);
5066
+ for (const entry of result.affected) {
5067
+ const indent = " ".repeat(entry.depth + 1);
5068
+ console.log(`${indent}${pc20.yellow(entry.component)} ${pc20.dim(`(depth ${entry.depth}, via ${entry.edgeType})`)}`);
5069
+ }
5070
+ }
5071
+ if (result.affectedBlocks.length > 0) {
5072
+ console.log(`
5073
+ ${pc20.bold("Affected blocks:")} ${result.affectedBlocks.join(", ")}`);
5074
+ }
5075
+ console.log();
5076
+ break;
5077
+ }
5078
+ case "path": {
5079
+ if (!options.target) {
5080
+ console.error(pc20.red("Error: --target is required for path mode."));
5081
+ process.exit(1);
5082
+ }
5083
+ const result = engine.path(component, options.target);
5084
+ if (format === "json") {
5085
+ console.log(JSON.stringify(result, null, 2));
5086
+ return;
5087
+ }
5088
+ console.log(pc20.bold(`
5089
+ Path: ${component} \u2192 ${options.target}
5090
+ `));
5091
+ if (!result.found) {
5092
+ console.log(` ${pc20.red("No path found.")}`);
5093
+ } else {
5094
+ console.log(` ${result.path.map((n) => pc20.yellow(n)).join(pc20.dim(" \u2192 "))}`);
5095
+ if (result.edges.length > 0) {
5096
+ console.log(` ${pc20.dim(`(${result.edges.map((e) => e.type).join(" \u2192 ")})`)}`);
5097
+ }
5098
+ }
5099
+ console.log();
5100
+ break;
5101
+ }
5102
+ case "composition": {
5103
+ const tree = engine.composition(component);
5104
+ if (format === "json") {
5105
+ console.log(JSON.stringify(tree, null, 2));
5106
+ return;
5107
+ }
5108
+ console.log(pc20.bold(`
5109
+ Composition: ${component}
5110
+ `));
5111
+ console.log(` ${pc20.cyan("Pattern:")} ${tree.compositionPattern ?? "unknown"}`);
5112
+ if (tree.parent) {
5113
+ console.log(` ${pc20.cyan("Parent:")} ${tree.parent}`);
5114
+ }
5115
+ if (tree.subComponents.length > 0) {
5116
+ console.log(` ${pc20.cyan("Sub-components:")}`);
5117
+ for (const sub of tree.subComponents) {
5118
+ const isRequired = tree.requiredChildren.includes(sub);
5119
+ console.log(` ${pc20.yellow(sub)}${isRequired ? pc20.red(" (required)") : ""}`);
5120
+ }
5121
+ }
5122
+ if (tree.siblings.length > 0) {
5123
+ console.log(` ${pc20.cyan("Siblings:")} ${tree.siblings.join(", ")}`);
5124
+ }
5125
+ if (tree.blocks.length > 0) {
5126
+ console.log(` ${pc20.cyan("In blocks:")} ${tree.blocks.join(", ")}`);
5127
+ }
5128
+ console.log();
5129
+ break;
5130
+ }
5131
+ case "alternatives": {
5132
+ const alts = engine.alternatives(component);
5133
+ if (format === "json") {
5134
+ console.log(JSON.stringify({ component, alternatives: alts }, null, 2));
5135
+ return;
5136
+ }
5137
+ console.log(pc20.bold(`
5138
+ Alternatives for ${component}
5139
+ `));
5140
+ if (alts.length === 0) {
5141
+ console.log(" No known alternatives.");
5142
+ } else {
5143
+ for (const alt of alts) {
5144
+ console.log(` ${pc20.yellow(alt.component)}${alt.note ? ` \u2014 ${alt.note}` : ""}`);
5145
+ }
5146
+ }
5147
+ console.log();
5148
+ break;
5149
+ }
5150
+ case "islands": {
5151
+ const islands = engine.islands();
5152
+ if (format === "json") {
5153
+ console.log(JSON.stringify({ islands }, null, 2));
5154
+ return;
5155
+ }
5156
+ console.log(pc20.bold(`
5157
+ Connected Islands (${islands.length})
5158
+ `));
5159
+ for (let i = 0; i < islands.length; i++) {
5160
+ console.log(` ${pc20.cyan(`Island ${i + 1}`)} (${islands[i].length} components): ${islands[i].join(", ")}`);
5161
+ }
5162
+ console.log();
5163
+ break;
5164
+ }
5165
+ default:
5166
+ console.error(pc20.red(`Unknown mode: "${mode}". Valid: health, dependencies, dependents, impact, path, composition, alternatives, islands`));
5167
+ process.exit(1);
5168
+ }
5169
+ if (format === "dot") {
5170
+ const lines = ["digraph ComponentGraph {", " rankdir=LR;", " node [shape=box, style=rounded];"];
5171
+ for (const node of graph2.nodes) {
5172
+ lines.push(` "${node.name}" [label="${node.name}\\n(${node.category})"];`);
5173
+ }
5174
+ for (const edge of graph2.edges) {
5175
+ const style = edge.type === "alternative-to" ? "dashed" : "solid";
5176
+ lines.push(` "${edge.source}" -> "${edge.target}" [label="${edge.type}", style=${style}];`);
5177
+ }
5178
+ lines.push("}");
5179
+ console.log(lines.join("\n"));
5180
+ }
5181
+ }
5182
+
4947
5183
  // src/bin.ts
4948
5184
  var __dirname = dirname4(fileURLToPath(import.meta.url));
4949
5185
  var pkg = JSON.parse(readFileSync(join10(__dirname, "../package.json"), "utf-8"));
@@ -4956,7 +5192,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
4956
5192
  process.exit(1);
4957
5193
  }
4958
5194
  } catch (error) {
4959
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5195
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
4960
5196
  process.exit(1);
4961
5197
  }
4962
5198
  });
@@ -4976,7 +5212,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
4976
5212
  process.exit(1);
4977
5213
  }
4978
5214
  } catch (error) {
4979
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5215
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
4980
5216
  process.exit(1);
4981
5217
  }
4982
5218
  });
@@ -4995,7 +5231,7 @@ program.command("context").description("Generate AI-ready context for your desig
4995
5231
  process.exit(1);
4996
5232
  }
4997
5233
  } catch (error) {
4998
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5234
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
4999
5235
  process.exit(1);
5000
5236
  }
5001
5237
  });
@@ -5022,7 +5258,7 @@ program.command("ai").description("Generate context optimized for AI assistants
5022
5258
  }
5023
5259
  }
5024
5260
  } catch (error) {
5025
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5261
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5026
5262
  process.exit(1);
5027
5263
  }
5028
5264
  });
@@ -5030,7 +5266,7 @@ program.command("list").description("List all discovered fragment files").option
5030
5266
  try {
5031
5267
  await list(options);
5032
5268
  } catch (error) {
5033
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5269
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5034
5270
  process.exit(1);
5035
5271
  }
5036
5272
  });
@@ -5038,7 +5274,7 @@ program.command("reset").description("Reset to initial state (delete all generat
5038
5274
  try {
5039
5275
  await reset(options);
5040
5276
  } catch (error) {
5041
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5277
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5042
5278
  process.exit(1);
5043
5279
  }
5044
5280
  });
@@ -5052,7 +5288,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
5052
5288
  variants: options.variants
5053
5289
  });
5054
5290
  } catch (error) {
5055
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5291
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5056
5292
  process.exit(1);
5057
5293
  }
5058
5294
  });
@@ -5067,7 +5303,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
5067
5303
  exclude: options.exclude
5068
5304
  });
5069
5305
  } catch (error) {
5070
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5306
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5071
5307
  process.exit(1);
5072
5308
  }
5073
5309
  });
@@ -5082,9 +5318,9 @@ program.command("dev").description("Start the development server with live compo
5082
5318
  skipBuild: options.skipBuild
5083
5319
  });
5084
5320
  } catch (error) {
5085
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5321
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5086
5322
  if (error instanceof Error && error.stack) {
5087
- console.error(pc20.dim(error.stack));
5323
+ console.error(pc21.dim(error.stack));
5088
5324
  }
5089
5325
  process.exit(1);
5090
5326
  }
@@ -5105,7 +5341,7 @@ program.command("screenshot").description("Capture screenshots of component vari
5105
5341
  process.exit(1);
5106
5342
  }
5107
5343
  } catch (error) {
5108
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5344
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5109
5345
  process.exit(1);
5110
5346
  }
5111
5347
  });
@@ -5124,7 +5360,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
5124
5360
  process.exit(1);
5125
5361
  }
5126
5362
  } catch (error) {
5127
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5363
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5128
5364
  process.exit(1);
5129
5365
  }
5130
5366
  });
@@ -5143,8 +5379,8 @@ program.command("compare").argument("[component]", "Component name to compare").
5143
5379
  process.exit(1);
5144
5380
  }
5145
5381
  } catch (error) {
5146
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5147
- console.log(pc20.dim(`
5382
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5383
+ console.log(pc21.dim(`
5148
5384
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5149
5385
  process.exit(1);
5150
5386
  }
@@ -5163,7 +5399,7 @@ program.command("analyze").description("Analyze design system and generate repor
5163
5399
  process.exit(1);
5164
5400
  }
5165
5401
  } catch (error) {
5166
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5402
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5167
5403
  process.exit(1);
5168
5404
  }
5169
5405
  });
@@ -5182,7 +5418,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
5182
5418
  if (options.ci) {
5183
5419
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
5184
5420
  } else {
5185
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5421
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5186
5422
  }
5187
5423
  process.exit(1);
5188
5424
  }
@@ -5199,7 +5435,7 @@ program.command("audit").description("Scan all fragments and show compliance met
5199
5435
  if (options.json) {
5200
5436
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
5201
5437
  } else {
5202
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5438
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5203
5439
  }
5204
5440
  process.exit(1);
5205
5441
  }
@@ -5221,7 +5457,7 @@ program.command("a11y").description("Run accessibility checks on all component v
5221
5457
  if (options.json) {
5222
5458
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
5223
5459
  } else {
5224
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5460
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5225
5461
  }
5226
5462
  process.exit(1);
5227
5463
  }
@@ -5244,7 +5480,7 @@ program.command("enhance").description("AI-powered documentation generation from
5244
5480
  if (options.format === "json") {
5245
5481
  console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
5246
5482
  } else {
5247
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5483
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5248
5484
  }
5249
5485
  process.exit(1);
5250
5486
  }
@@ -5265,7 +5501,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
5265
5501
  process.exit(1);
5266
5502
  }
5267
5503
  } catch (error) {
5268
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5504
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5269
5505
  process.exit(1);
5270
5506
  }
5271
5507
  });
@@ -5278,7 +5514,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
5278
5514
  format: options.format
5279
5515
  });
5280
5516
  } catch (error) {
5281
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5517
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5282
5518
  process.exit(1);
5283
5519
  }
5284
5520
  });
@@ -5290,7 +5526,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
5290
5526
  json: options.json
5291
5527
  });
5292
5528
  } catch (error) {
5293
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5529
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5294
5530
  process.exit(1);
5295
5531
  }
5296
5532
  });
@@ -5304,9 +5540,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
5304
5540
  port: options.port
5305
5541
  });
5306
5542
  } catch (error) {
5307
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5543
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5308
5544
  if (action === "update") {
5309
- console.log(pc20.dim(`
5545
+ console.log(pc21.dim(`
5310
5546
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5311
5547
  }
5312
5548
  process.exit(1);
@@ -5314,27 +5550,27 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5314
5550
  });
5315
5551
  program.command("view").description(`Generate a static HTML viewer for ${BRAND.outFile}`).option("-i, --input <path>", `Path to ${BRAND.outFile}`, BRAND.outFile).option("-o, --output <path>", "Output HTML file path", BRAND.viewerHtmlFile).option("--open", "Open in browser after generation").action(async (options) => {
5316
5552
  try {
5317
- const { generateViewerFromJson } = await import("./static-viewer-4LQZ5AGA.js");
5553
+ const { generateViewerFromJson } = await import("./static-viewer-GBR7YNF3.js");
5318
5554
  const fs2 = await import("fs/promises");
5319
5555
  const path = await import("path");
5320
5556
  const inputPath = path.resolve(process.cwd(), options.input);
5321
5557
  const outputPath = path.resolve(process.cwd(), options.output);
5322
- console.log(pc20.cyan(`
5558
+ console.log(pc21.cyan(`
5323
5559
  ${BRAND.name} Viewer Generator
5324
5560
  `));
5325
5561
  try {
5326
5562
  await fs2.access(inputPath);
5327
5563
  } catch {
5328
- console.log(pc20.red(`Error: ${options.input} not found.`));
5329
- console.log(pc20.dim(`
5330
- Run ${pc20.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5564
+ console.log(pc21.red(`Error: ${options.input} not found.`));
5565
+ console.log(pc21.dim(`
5566
+ Run ${pc21.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5331
5567
  `));
5332
5568
  process.exit(1);
5333
5569
  }
5334
- console.log(pc20.dim(`Reading: ${options.input}`));
5570
+ console.log(pc21.dim(`Reading: ${options.input}`));
5335
5571
  const html = await generateViewerFromJson(inputPath);
5336
5572
  await fs2.writeFile(outputPath, html);
5337
- console.log(pc20.green(`
5573
+ console.log(pc21.green(`
5338
5574
  \u2713 Generated: ${options.output}
5339
5575
  `));
5340
5576
  if (options.open) {
@@ -5343,7 +5579,7 @@ Run ${pc20.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5343
5579
  exec(`${openCmd} "${outputPath}"`);
5344
5580
  }
5345
5581
  } catch (error) {
5346
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5582
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5347
5583
  process.exit(1);
5348
5584
  }
5349
5585
  });
@@ -5356,33 +5592,33 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
5356
5592
  component: options.component
5357
5593
  });
5358
5594
  } catch (error) {
5359
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5595
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5360
5596
  process.exit(1);
5361
5597
  }
5362
5598
  });
5363
5599
  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) => {
5364
5600
  try {
5365
- const { init } = await import("./init-WKGDPYI4.js");
5601
+ const { init } = await import("./init-7CHRKQ7P.js");
5366
5602
  const result = await init({
5367
5603
  projectRoot: process.cwd(),
5368
5604
  force: options.force,
5369
5605
  yes: options.yes
5370
5606
  });
5371
5607
  if (!result.success) {
5372
- console.error(pc20.red("\nInit failed with errors:"));
5608
+ console.error(pc21.red("\nInit failed with errors:"));
5373
5609
  for (const error of result.errors) {
5374
- console.error(pc20.red(` - ${error}`));
5610
+ console.error(pc21.red(` - ${error}`));
5375
5611
  }
5376
5612
  process.exit(1);
5377
5613
  }
5378
5614
  } catch (error) {
5379
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5615
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5380
5616
  process.exit(1);
5381
5617
  }
5382
5618
  });
5383
5619
  program.command("tokens").description("Discover and list design tokens from CSS/SCSS files").option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--categories", "Group tokens by category").option("--theme <theme>", "Filter by theme name").option("--category <category>", "Filter by category (color, spacing, typography, etc.)").option("--verbose", "Show all tokens (no truncation)").action(async (options) => {
5384
5620
  try {
5385
- const { tokens } = await import("./tokens-JAJABYXP.js");
5621
+ const { tokens } = await import("./tokens-3BWDESVM.js");
5386
5622
  const result = await tokens({
5387
5623
  config: options.config,
5388
5624
  json: options.json,
@@ -5395,13 +5631,13 @@ program.command("tokens").description("Discover and list design tokens from CSS/
5395
5631
  process.exit(1);
5396
5632
  }
5397
5633
  } catch (error) {
5398
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5634
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5399
5635
  process.exit(1);
5400
5636
  }
5401
5637
  });
5402
5638
  program.command("generate").description("Generate fragment files from component source code").argument("[component]", "Specific component name to generate (optional)").option("--force", "Overwrite existing fragment files").option("--pattern <glob>", "Pattern for component files", "src/components/**/*.tsx").action(async (component, options) => {
5403
5639
  try {
5404
- const { generate } = await import("./generate-7AF7WRVK.js");
5640
+ const { generate } = await import("./generate-LMTISDIJ.js");
5405
5641
  const result = await generate({
5406
5642
  projectRoot: process.cwd(),
5407
5643
  component,
@@ -5409,18 +5645,26 @@ program.command("generate").description("Generate fragment files from component
5409
5645
  componentPattern: options.pattern
5410
5646
  });
5411
5647
  if (!result.success) {
5412
- console.error(pc20.red("\nGenerate completed with errors"));
5648
+ console.error(pc21.red("\nGenerate completed with errors"));
5413
5649
  process.exit(1);
5414
5650
  }
5415
5651
  } catch (error) {
5416
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5652
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5653
+ process.exit(1);
5654
+ }
5655
+ });
5656
+ program.command("graph").description("Query the component relationship graph").argument("[component]", "Component name (optional)").option("-c, --config <path>", "Path to config file").option("-m, --mode <mode>", "Query mode: health, dependencies, dependents, impact, path, composition, alternatives, islands").option("-t, --target <component>", "Target component for path mode").option("--edge-types <types>", "Comma-separated edge types to filter by").option("--depth <number>", "Max traversal depth for impact mode", parseInt).option("--format <format>", "Output format: table, json, dot", "table").action(async (component, options) => {
5657
+ try {
5658
+ await graph(component, options);
5659
+ } catch (error) {
5660
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5417
5661
  process.exit(1);
5418
5662
  }
5419
5663
  });
5420
5664
  program.command("test").description("Run interaction tests for fragments with play functions").option("-c, --config <path>", "Path to config file").option("--component <name>", "Filter by component name").option("--tags <tags>", "Filter by tags (comma-separated)").option("--grep <pattern>", "Filter by variant name pattern").option("--exclude <pattern>", "Exclude tests matching pattern").option("--parallel <count>", "Number of parallel browser contexts", parseInt, 4).option("--timeout <ms>", "Timeout per test in milliseconds", parseInt, 3e4).option("--retries <count>", "Number of retries for failed tests", parseInt, 0).option("--bail", "Stop on first failure").option("--browser <name>", "Browser to use (chromium, firefox, webkit)", "chromium").option("--headed", "Run in headed mode (show browser)").option("--a11y", "Run accessibility checks with axe-core").option("--visual", "Capture screenshots for visual regression").option("--update-snapshots", "Update visual snapshots").option("--watch", "Watch mode - re-run on file changes").option("--reporters <names>", "Reporters to use (console, junit, json)", "console").option("-o, --output <dir>", "Output directory for results", "./test-results").option("--server-url <url>", "URL of running dev server (skips starting server)").option("-p, --port <port>", "Port for dev server", parseInt, 6006).option("--ci", "CI mode - non-interactive, exit with code 1 on failure").option("--list", "List available tests without running them").action(async (options) => {
5421
5665
  try {
5422
5666
  const { config, configDir } = await loadConfig(options.config);
5423
- const { runTestCommand, listTests } = await import("./test-CJDNJTPZ.js");
5667
+ const { runTestCommand, listTests } = await import("./test-OJRXNDO2.js");
5424
5668
  if (options.list) {
5425
5669
  await listTests(config, configDir, {
5426
5670
  component: options.component,
@@ -5453,7 +5697,7 @@ program.command("test").description("Run interaction tests for fragments with pl
5453
5697
  });
5454
5698
  process.exit(exitCode);
5455
5699
  } catch (error) {
5456
- console.error(pc20.red("Error:"), error instanceof Error ? error.message : error);
5700
+ console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5457
5701
  process.exit(1);
5458
5702
  }
5459
5703
  });