@fragments-sdk/cli 0.12.1 → 0.13.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 (53) hide show
  1. package/dist/bin.js +299 -61
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-AM4MRTMN.js → chunk-55KERLWL.js} +2 -2
  4. package/dist/{chunk-LVWFOLUZ.js → chunk-7K3VROEP.js} +2 -2
  5. package/dist/{chunk-JJ2VRTBU.js → chunk-EYXVAMEX.js} +2 -2
  6. package/dist/chunk-EYXVAMEX.js.map +1 -0
  7. package/dist/{chunk-GVDSFQ4E.js → chunk-FZLPVN32.js} +6 -6
  8. package/dist/{chunk-WFS63PCW.js → chunk-I34BC3CU.js} +45 -2
  9. package/dist/chunk-I34BC3CU.js.map +1 -0
  10. package/dist/{chunk-T5OMVL7E.js → chunk-PJT5IZ37.js} +2 -2
  11. package/dist/{chunk-4OC7FTJB.js → chunk-TXFCEDOC.js} +2 -2
  12. package/dist/{chunk-TPWGL2XS.js → chunk-Z5BUXIFJ.js} +5 -5
  13. package/dist/{chunk-OQKMEFOS.js → chunk-ZKTFKHWN.js} +2 -2
  14. package/dist/core/index.js +5 -1
  15. package/dist/{discovery-ZJQSXF56.js → discovery-VDANZAJ2.js} +3 -3
  16. package/dist/{generate-RJFS2JWA.js → generate-RYWIPDN2.js} +4 -4
  17. package/dist/index.js +7 -7
  18. package/dist/{init-ZSX3NRCZ.js → init-U6534EMZ.js} +5 -5
  19. package/dist/mcp-bin.js +2 -2
  20. package/dist/{scan-3PMCJ4RB.js → scan-LE2JEIJ4.js} +6 -6
  21. package/dist/{scan-generate-SYU4PYZD.js → scan-generate-TFZVL3BT.js} +5 -5
  22. package/dist/{service-VMGNJZ42.js → service-S5LXPKV4.js} +3 -3
  23. package/dist/{snapshot-XOISO2IS.js → snapshot-C5DYIGIV.js} +2 -2
  24. package/dist/{static-viewer-5GXH2MGE.js → static-viewer-DUVC4UIM.js} +3 -3
  25. package/dist/{test-SI4NSHQX.js → test-JW7JIDFG.js} +4 -4
  26. package/dist/{tokens-T6SIVUT5.js → tokens-OPVTVITP.js} +5 -5
  27. package/dist/{viewer-7ZEAFBVN.js → viewer-OBTEPVY7.js} +14 -14
  28. package/dist/viewer-OBTEPVY7.js.map +1 -0
  29. package/package.json +11 -9
  30. package/src/bin.ts +67 -0
  31. package/src/commands/govern.ts +279 -0
  32. package/src/core/component-extractor.ts +1 -1
  33. package/src/viewer/vite-plugin.ts +1 -1
  34. package/dist/chunk-JJ2VRTBU.js.map +0 -1
  35. package/dist/chunk-WFS63PCW.js.map +0 -1
  36. package/dist/viewer-7ZEAFBVN.js.map +0 -1
  37. /package/dist/{chunk-AM4MRTMN.js.map → chunk-55KERLWL.js.map} +0 -0
  38. /package/dist/{chunk-LVWFOLUZ.js.map → chunk-7K3VROEP.js.map} +0 -0
  39. /package/dist/{chunk-GVDSFQ4E.js.map → chunk-FZLPVN32.js.map} +0 -0
  40. /package/dist/{chunk-T5OMVL7E.js.map → chunk-PJT5IZ37.js.map} +0 -0
  41. /package/dist/{chunk-4OC7FTJB.js.map → chunk-TXFCEDOC.js.map} +0 -0
  42. /package/dist/{chunk-TPWGL2XS.js.map → chunk-Z5BUXIFJ.js.map} +0 -0
  43. /package/dist/{chunk-OQKMEFOS.js.map → chunk-ZKTFKHWN.js.map} +0 -0
  44. /package/dist/{discovery-ZJQSXF56.js.map → discovery-VDANZAJ2.js.map} +0 -0
  45. /package/dist/{generate-RJFS2JWA.js.map → generate-RYWIPDN2.js.map} +0 -0
  46. /package/dist/{init-ZSX3NRCZ.js.map → init-U6534EMZ.js.map} +0 -0
  47. /package/dist/{scan-3PMCJ4RB.js.map → scan-LE2JEIJ4.js.map} +0 -0
  48. /package/dist/{scan-generate-SYU4PYZD.js.map → scan-generate-TFZVL3BT.js.map} +0 -0
  49. /package/dist/{service-VMGNJZ42.js.map → service-S5LXPKV4.js.map} +0 -0
  50. /package/dist/{snapshot-XOISO2IS.js.map → snapshot-C5DYIGIV.js.map} +0 -0
  51. /package/dist/{static-viewer-5GXH2MGE.js.map → static-viewer-DUVC4UIM.js.map} +0 -0
  52. /package/dist/{test-SI4NSHQX.js.map → test-JW7JIDFG.js.map} +0 -0
  53. /package/dist/{tokens-T6SIVUT5.js.map → tokens-OPVTVITP.js.map} +0 -0
package/dist/bin.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-SXTKFDCR.js";
8
8
  import {
9
9
  setup
10
- } from "./chunk-T5OMVL7E.js";
10
+ } from "./chunk-PJT5IZ37.js";
11
11
  import {
12
12
  buildFragments,
13
13
  buildFragmentsDir,
@@ -22,21 +22,21 @@ import {
22
22
  validateDrift,
23
23
  validateSchema,
24
24
  validateSnippets
25
- } from "./chunk-GVDSFQ4E.js";
25
+ } from "./chunk-FZLPVN32.js";
26
26
  import {
27
27
  createComponentExtractor
28
- } from "./chunk-JJ2VRTBU.js";
28
+ } from "./chunk-EYXVAMEX.js";
29
29
  import {
30
30
  scan
31
- } from "./chunk-TPWGL2XS.js";
31
+ } from "./chunk-Z5BUXIFJ.js";
32
32
  import {
33
33
  loadConfig,
34
34
  loadFragmentFile,
35
35
  parseFragmentFile
36
- } from "./chunk-AM4MRTMN.js";
36
+ } from "./chunk-55KERLWL.js";
37
37
  import {
38
38
  discoverFragmentFiles
39
- } from "./chunk-OQKMEFOS.js";
39
+ } from "./chunk-ZKTFKHWN.js";
40
40
  import {
41
41
  FigmaClient,
42
42
  StorageManager,
@@ -52,7 +52,7 @@ import {
52
52
  renderAllComponentVariants,
53
53
  scanCodebase,
54
54
  shutdownSharedPool
55
- } from "./chunk-LVWFOLUZ.js";
55
+ } from "./chunk-7K3VROEP.js";
56
56
  import "./chunk-D2CDBRNU.js";
57
57
  import {
58
58
  BRAND,
@@ -60,12 +60,12 @@ import {
60
60
  formatBytes,
61
61
  generateContext,
62
62
  resolvePerformanceConfig
63
- } from "./chunk-WFS63PCW.js";
63
+ } from "./chunk-I34BC3CU.js";
64
64
  import "./chunk-Z7EY4VHE.js";
65
65
 
66
66
  // src/bin.ts
67
67
  import { Command } from "commander";
68
- import pc24 from "picocolors";
68
+ import pc25 from "picocolors";
69
69
  import { readFileSync } from "fs";
70
70
  import { fileURLToPath } from "url";
71
71
  import { dirname as dirname4, join as join11 } from "path";
@@ -1901,7 +1901,7 @@ ${BRAND.name} Dev Server
1901
1901
  }
1902
1902
  }
1903
1903
  }
1904
- const { createDevServer } = await import("./viewer-7ZEAFBVN.js");
1904
+ const { createDevServer } = await import("./viewer-OBTEPVY7.js");
1905
1905
  console.log(pc7.dim("\nStarting dev server..."));
1906
1906
  const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
1907
1907
  try {
@@ -6023,6 +6023,205 @@ function escapeRegex(str) {
6023
6023
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6024
6024
  }
6025
6025
 
6026
+ // src/commands/govern.ts
6027
+ import pc24 from "picocolors";
6028
+ async function governCheck(options = {}) {
6029
+ console.log(pc24.cyan(`
6030
+ ${BRAND.name} Governance Check
6031
+ `));
6032
+ const { cliCheck, formatVerdict } = await import("@fragments-sdk/govern");
6033
+ const result = await cliCheck(options);
6034
+ const output = formatVerdict(result.verdict, options.format ?? "summary");
6035
+ if (!options.quiet) {
6036
+ console.log(output);
6037
+ console.log();
6038
+ }
6039
+ if (result.verdict.passed) {
6040
+ console.log(pc24.green(`\u2713 Governance check passed (score: ${result.verdict.score}/100)
6041
+ `));
6042
+ } else {
6043
+ console.log(pc24.red(`\u2717 Governance check failed (score: ${result.verdict.score}/100)
6044
+ `));
6045
+ }
6046
+ return { exitCode: result.exitCode };
6047
+ }
6048
+ async function governInit(options = {}) {
6049
+ const { writeFile: writeFile10 } = await import("fs/promises");
6050
+ const { resolve: resolve9 } = await import("path");
6051
+ const { generateConfigTemplate } = await import("@fragments-sdk/govern");
6052
+ const outputPath = resolve9(options.output ?? "fragments.config.ts");
6053
+ const template = generateConfigTemplate();
6054
+ await writeFile10(outputPath, template, "utf-8");
6055
+ console.log(pc24.green(`\u2713 Created ${outputPath}
6056
+ `));
6057
+ }
6058
+ async function governConnect() {
6059
+ const { readFile: readFile10, writeFile: writeFile10, appendFile } = await import("fs/promises");
6060
+ const { existsSync: existsSync2 } = await import("fs");
6061
+ const { resolve: resolve9 } = await import("path");
6062
+ const { platform } = await import("os");
6063
+ const { exec } = await import("child_process");
6064
+ const { password, confirm } = await import("@inquirer/prompts");
6065
+ const cloudUrl = process.env.FRAGMENTS_URL ?? "https://app.usefragments.com";
6066
+ console.log(pc24.cyan(`
6067
+ ${BRAND.name} \u2014 Connect to Cloud
6068
+ `));
6069
+ console.log(
6070
+ pc24.dim(" This will connect your project to the Fragments dashboard\n") + pc24.dim(" for centralized audit tracking and team visibility.\n")
6071
+ );
6072
+ console.log(pc24.bold(" Step 1 of 3: Get your API key\n"));
6073
+ const dashboardUrl = `${cloudUrl}/dashboard/settings`;
6074
+ console.log(pc24.dim(` \u2192 Opening the dashboard in your browser...`));
6075
+ console.log(pc24.dim(` Copy your API key from Settings \u2192 API Keys
6076
+ `));
6077
+ const os = platform();
6078
+ const openCmd = os === "darwin" ? `open "${dashboardUrl}"` : os === "win32" ? `start "" "${dashboardUrl}"` : `xdg-open "${dashboardUrl}"`;
6079
+ exec(openCmd);
6080
+ let apiKey;
6081
+ let orgName;
6082
+ while (true) {
6083
+ apiKey = await password({
6084
+ message: "Paste your API key:",
6085
+ mask: "*"
6086
+ });
6087
+ if (!apiKey.trim()) {
6088
+ console.log(pc24.yellow("\n API key cannot be empty. Please try again.\n"));
6089
+ continue;
6090
+ }
6091
+ console.log(pc24.dim("\n Verifying..."));
6092
+ try {
6093
+ const response = await fetch(`${cloudUrl}/api/verify`, {
6094
+ headers: { Authorization: `Bearer ${apiKey.trim()}` }
6095
+ });
6096
+ if (!response.ok) {
6097
+ console.log(pc24.red(`
6098
+ \u2717 Invalid API key (HTTP ${response.status}). Please try again.
6099
+ `));
6100
+ continue;
6101
+ }
6102
+ const data = await response.json();
6103
+ if (!data.valid) {
6104
+ console.log(pc24.red("\n \u2717 API key not recognized. Please try again.\n"));
6105
+ continue;
6106
+ }
6107
+ orgName = data.orgName ?? "your organization";
6108
+ console.log(pc24.green(`
6109
+ \u2713 Connected to "${orgName}" (verified)
6110
+ `));
6111
+ break;
6112
+ } catch (error) {
6113
+ console.log(
6114
+ pc24.red("\n \u2717 Could not reach the dashboard.")
6115
+ );
6116
+ console.log(
6117
+ pc24.dim(` ${error instanceof Error ? error.message : "Network error"}
6118
+ `)
6119
+ );
6120
+ continue;
6121
+ }
6122
+ }
6123
+ console.log(pc24.bold(" Step 2 of 3: Save configuration\n"));
6124
+ const saveToEnv = await confirm({
6125
+ message: "Save API key to .env file?",
6126
+ default: true
6127
+ });
6128
+ if (saveToEnv) {
6129
+ const envPath = resolve9(".env");
6130
+ const envEntry = `FRAGMENTS_API_KEY=${apiKey.trim()}`;
6131
+ if (existsSync2(envPath)) {
6132
+ const envContent = await readFile10(envPath, "utf-8");
6133
+ if (envContent.includes("FRAGMENTS_API_KEY=")) {
6134
+ const updated = envContent.replace(
6135
+ /^FRAGMENTS_API_KEY=.*$/m,
6136
+ envEntry
6137
+ );
6138
+ await writeFile10(envPath, updated, "utf-8");
6139
+ console.log(pc24.green(" \u2713 Updated FRAGMENTS_API_KEY in .env"));
6140
+ } else {
6141
+ await appendFile(envPath, `
6142
+ ${envEntry}
6143
+ `, "utf-8");
6144
+ console.log(pc24.green(" \u2713 Added FRAGMENTS_API_KEY to .env"));
6145
+ }
6146
+ } else {
6147
+ await writeFile10(envPath, `${envEntry}
6148
+ `, "utf-8");
6149
+ console.log(pc24.green(" \u2713 Created .env with FRAGMENTS_API_KEY"));
6150
+ }
6151
+ if (cloudUrl !== "https://app.usefragments.com") {
6152
+ const envContent = await readFile10(envPath, "utf-8");
6153
+ if (!envContent.includes("FRAGMENTS_URL=")) {
6154
+ await appendFile(envPath, `FRAGMENTS_URL=${cloudUrl}
6155
+ `, "utf-8");
6156
+ console.log(pc24.green(` \u2713 Added FRAGMENTS_URL to .env`));
6157
+ }
6158
+ }
6159
+ const gitignorePath = resolve9(".gitignore");
6160
+ if (existsSync2(gitignorePath)) {
6161
+ const gitignore = await readFile10(gitignorePath, "utf-8");
6162
+ if (!gitignore.split("\n").some((line) => line.trim() === ".env")) {
6163
+ await appendFile(gitignorePath, "\n.env\n", "utf-8");
6164
+ console.log(pc24.green(" \u2713 Added .env to .gitignore"));
6165
+ }
6166
+ } else {
6167
+ await writeFile10(gitignorePath, ".env\n", "utf-8");
6168
+ console.log(pc24.green(" \u2713 Created .gitignore with .env entry"));
6169
+ }
6170
+ }
6171
+ console.log(pc24.bold("\n Step 3 of 3: Config check\n"));
6172
+ const { findGovernConfig } = await import("@fragments-sdk/govern");
6173
+ const configPath = findGovernConfig();
6174
+ if (configPath) {
6175
+ console.log(pc24.green(` \u2713 Found govern config: ${configPath}`));
6176
+ } else {
6177
+ console.log(
6178
+ pc24.yellow(" No govern config found \u2014 run `fragments govern init` to create one")
6179
+ );
6180
+ }
6181
+ console.log(pc24.dim("\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
6182
+ console.log(pc24.green(" \u2713 All set!") + " Run `fragments govern check` to send your first audit.\n");
6183
+ console.log(pc24.dim(` Dashboard: ${cloudUrl}/dashboard
6184
+ `));
6185
+ }
6186
+ async function governReport() {
6187
+ const { readFile: readFile10 } = await import("fs/promises");
6188
+ console.log(pc24.cyan(`
6189
+ ${BRAND.name} Governance Report
6190
+ `));
6191
+ let raw;
6192
+ try {
6193
+ raw = await readFile10(".govern-audit.jsonl", "utf-8");
6194
+ } catch {
6195
+ console.log(pc24.yellow("No audit log found (.govern-audit.jsonl)\n"));
6196
+ console.log(pc24.dim("Run `fragments govern check` to generate audit data.\n"));
6197
+ return;
6198
+ }
6199
+ const lines = raw.trim().split("\n").filter(Boolean);
6200
+ if (lines.length === 0) {
6201
+ console.log(pc24.yellow("Audit log is empty.\n"));
6202
+ return;
6203
+ }
6204
+ let totalScore = 0;
6205
+ let passCount = 0;
6206
+ let totalViolations = 0;
6207
+ for (const line of lines) {
6208
+ try {
6209
+ const entry = JSON.parse(line);
6210
+ totalScore += entry.score ?? 0;
6211
+ if (entry.passed) passCount++;
6212
+ totalViolations += entry.violationCount ?? 0;
6213
+ } catch {
6214
+ }
6215
+ }
6216
+ const avgScore = Math.round(totalScore / lines.length);
6217
+ const passRate = Math.round(passCount / lines.length * 100);
6218
+ console.log(` Checks: ${lines.length}`);
6219
+ console.log(` Pass rate: ${passRate}%`);
6220
+ console.log(` Avg score: ${avgScore}/100`);
6221
+ console.log(` Violations: ${totalViolations} total`);
6222
+ console.log();
6223
+ }
6224
+
6026
6225
  // src/bin.ts
6027
6226
  var __dirname = dirname4(fileURLToPath(import.meta.url));
6028
6227
  var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
@@ -6035,7 +6234,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
6035
6234
  process.exit(1);
6036
6235
  }
6037
6236
  } catch (error) {
6038
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6237
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6039
6238
  process.exit(1);
6040
6239
  }
6041
6240
  });
@@ -6051,7 +6250,7 @@ program.command("sync").description("Auto-update fragment files from component s
6051
6250
  process.exit(1);
6052
6251
  }
6053
6252
  } catch (error) {
6054
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6253
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6055
6254
  process.exit(1);
6056
6255
  }
6057
6256
  });
@@ -6071,7 +6270,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
6071
6270
  process.exit(1);
6072
6271
  }
6073
6272
  } catch (error) {
6074
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6273
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6075
6274
  process.exit(1);
6076
6275
  }
6077
6276
  });
@@ -6090,7 +6289,7 @@ program.command("context").description("Generate AI-ready context for your desig
6090
6289
  process.exit(1);
6091
6290
  }
6092
6291
  } catch (error) {
6093
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6292
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6094
6293
  process.exit(1);
6095
6294
  }
6096
6295
  });
@@ -6117,7 +6316,7 @@ program.command("ai").description("Generate context optimized for AI assistants
6117
6316
  }
6118
6317
  }
6119
6318
  } catch (error) {
6120
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6319
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6121
6320
  process.exit(1);
6122
6321
  }
6123
6322
  });
@@ -6125,7 +6324,7 @@ program.command("list").description("List all discovered fragment files").option
6125
6324
  try {
6126
6325
  await list(options);
6127
6326
  } catch (error) {
6128
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6327
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6129
6328
  process.exit(1);
6130
6329
  }
6131
6330
  });
@@ -6133,7 +6332,7 @@ program.command("reset").description("Reset to initial state (delete all generat
6133
6332
  try {
6134
6333
  await reset(options);
6135
6334
  } catch (error) {
6136
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6335
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6137
6336
  process.exit(1);
6138
6337
  }
6139
6338
  });
@@ -6147,7 +6346,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
6147
6346
  variants: options.variants
6148
6347
  });
6149
6348
  } catch (error) {
6150
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6349
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6151
6350
  process.exit(1);
6152
6351
  }
6153
6352
  });
@@ -6162,7 +6361,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
6162
6361
  exclude: options.exclude
6163
6362
  });
6164
6363
  } catch (error) {
6165
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6364
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6166
6365
  process.exit(1);
6167
6366
  }
6168
6367
  });
@@ -6177,9 +6376,9 @@ program.command("dev").description("Start the development server with live compo
6177
6376
  skipBuild: options.skipBuild
6178
6377
  });
6179
6378
  } catch (error) {
6180
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6379
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6181
6380
  if (error instanceof Error && error.stack) {
6182
- console.error(pc24.dim(error.stack));
6381
+ console.error(pc25.dim(error.stack));
6183
6382
  }
6184
6383
  process.exit(1);
6185
6384
  }
@@ -6200,7 +6399,7 @@ program.command("screenshot").description("Capture screenshots of component vari
6200
6399
  process.exit(1);
6201
6400
  }
6202
6401
  } catch (error) {
6203
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6402
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6204
6403
  process.exit(1);
6205
6404
  }
6206
6405
  });
@@ -6219,7 +6418,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
6219
6418
  process.exit(1);
6220
6419
  }
6221
6420
  } catch (error) {
6222
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6421
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6223
6422
  process.exit(1);
6224
6423
  }
6225
6424
  });
@@ -6238,8 +6437,8 @@ program.command("compare").argument("[component]", "Component name to compare").
6238
6437
  process.exit(1);
6239
6438
  }
6240
6439
  } catch (error) {
6241
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6242
- console.log(pc24.dim(`
6440
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6441
+ console.log(pc25.dim(`
6243
6442
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
6244
6443
  process.exit(1);
6245
6444
  }
@@ -6258,7 +6457,7 @@ program.command("analyze").description("Analyze design system and generate repor
6258
6457
  process.exit(1);
6259
6458
  }
6260
6459
  } catch (error) {
6261
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6460
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6262
6461
  process.exit(1);
6263
6462
  }
6264
6463
  });
@@ -6277,7 +6476,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
6277
6476
  if (options.ci) {
6278
6477
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
6279
6478
  } else {
6280
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6479
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6281
6480
  }
6282
6481
  process.exit(1);
6283
6482
  }
@@ -6294,7 +6493,7 @@ program.command("audit").description("Scan all fragments and show compliance met
6294
6493
  if (options.json) {
6295
6494
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
6296
6495
  } else {
6297
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6496
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6298
6497
  }
6299
6498
  process.exit(1);
6300
6499
  }
@@ -6316,7 +6515,7 @@ program.command("a11y").description("Run accessibility checks on all component v
6316
6515
  if (options.json) {
6317
6516
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
6318
6517
  } else {
6319
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6518
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6320
6519
  }
6321
6520
  process.exit(1);
6322
6521
  }
@@ -6339,7 +6538,7 @@ program.command("enhance").description("AI-powered documentation generation from
6339
6538
  if (options.format === "json") {
6340
6539
  console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
6341
6540
  } else {
6342
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6541
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6343
6542
  }
6344
6543
  process.exit(1);
6345
6544
  }
@@ -6360,7 +6559,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
6360
6559
  process.exit(1);
6361
6560
  }
6362
6561
  } catch (error) {
6363
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6562
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6364
6563
  process.exit(1);
6365
6564
  }
6366
6565
  });
@@ -6373,7 +6572,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
6373
6572
  format: options.format
6374
6573
  });
6375
6574
  } catch (error) {
6376
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6575
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6377
6576
  process.exit(1);
6378
6577
  }
6379
6578
  });
@@ -6385,7 +6584,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
6385
6584
  json: options.json
6386
6585
  });
6387
6586
  } catch (error) {
6388
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6587
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6389
6588
  process.exit(1);
6390
6589
  }
6391
6590
  });
@@ -6399,9 +6598,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
6399
6598
  port: options.port
6400
6599
  });
6401
6600
  } catch (error) {
6402
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6601
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6403
6602
  if (action === "update") {
6404
- console.log(pc24.dim(`
6603
+ console.log(pc25.dim(`
6405
6604
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
6406
6605
  }
6407
6606
  process.exit(1);
@@ -6409,27 +6608,27 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
6409
6608
  });
6410
6609
  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) => {
6411
6610
  try {
6412
- const { generateViewerFromJson } = await import("./static-viewer-5GXH2MGE.js");
6611
+ const { generateViewerFromJson } = await import("./static-viewer-DUVC4UIM.js");
6413
6612
  const fs2 = await import("fs/promises");
6414
6613
  const path = await import("path");
6415
6614
  const inputPath = path.resolve(process.cwd(), options.input);
6416
6615
  const outputPath = path.resolve(process.cwd(), options.output);
6417
- console.log(pc24.cyan(`
6616
+ console.log(pc25.cyan(`
6418
6617
  ${BRAND.name} Viewer Generator
6419
6618
  `));
6420
6619
  try {
6421
6620
  await fs2.access(inputPath);
6422
6621
  } catch {
6423
- console.log(pc24.red(`Error: ${options.input} not found.`));
6424
- console.log(pc24.dim(`
6425
- Run ${pc24.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
6622
+ console.log(pc25.red(`Error: ${options.input} not found.`));
6623
+ console.log(pc25.dim(`
6624
+ Run ${pc25.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
6426
6625
  `));
6427
6626
  process.exit(1);
6428
6627
  }
6429
- console.log(pc24.dim(`Reading: ${options.input}`));
6628
+ console.log(pc25.dim(`Reading: ${options.input}`));
6430
6629
  const html = await generateViewerFromJson(inputPath);
6431
6630
  await fs2.writeFile(outputPath, html);
6432
- console.log(pc24.green(`
6631
+ console.log(pc25.green(`
6433
6632
  \u2713 Generated: ${options.output}
6434
6633
  `));
6435
6634
  if (options.open) {
@@ -6438,7 +6637,7 @@ Run ${pc24.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
6438
6637
  exec(`${openCmd} "${outputPath}"`);
6439
6638
  }
6440
6639
  } catch (error) {
6441
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6640
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6442
6641
  process.exit(1);
6443
6642
  }
6444
6643
  });
@@ -6451,7 +6650,7 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
6451
6650
  component: options.component
6452
6651
  });
6453
6652
  } catch (error) {
6454
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6653
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6455
6654
  process.exit(1);
6456
6655
  }
6457
6656
  });
@@ -6468,13 +6667,13 @@ program.command("setup").description("Configure @fragments-sdk/ui in a consumer
6468
6667
  process.exit(1);
6469
6668
  }
6470
6669
  } catch (error) {
6471
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6670
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6472
6671
  process.exit(1);
6473
6672
  }
6474
6673
  });
6475
6674
  program.command("init").description("Initialize fragments in a project (zero-config by default)").option("--force", "Overwrite existing config").option("-y, --yes", "Non-interactive mode (now the default)").option("--configure", "Interactive mode for theme seeds, snapshots, etc.").option("--scan <path>", "Scan a TypeScript component directory and generate fragment files").option("--enrich", "Use AI to fill knowledge fields during --scan (requires API key)").option("--dry-run", "Show what --enrich would generate without calling API").option("--provider <provider>", "AI provider for enrichment: anthropic or openai").option("--api-key <key>", "API key for AI enrichment").option("--model <model>", "Override AI model for enrichment").action(async (options) => {
6476
6675
  try {
6477
- const { init } = await import("./init-ZSX3NRCZ.js");
6676
+ const { init } = await import("./init-U6534EMZ.js");
6478
6677
  const result = await init({
6479
6678
  projectRoot: process.cwd(),
6480
6679
  force: options.force,
@@ -6488,20 +6687,20 @@ program.command("init").description("Initialize fragments in a project (zero-con
6488
6687
  model: options.model
6489
6688
  });
6490
6689
  if (!result.success) {
6491
- console.error(pc24.red("\nInit failed with errors:"));
6690
+ console.error(pc25.red("\nInit failed with errors:"));
6492
6691
  for (const error of result.errors) {
6493
- console.error(pc24.red(` - ${error}`));
6692
+ console.error(pc25.red(` - ${error}`));
6494
6693
  }
6495
6694
  process.exit(1);
6496
6695
  }
6497
6696
  } catch (error) {
6498
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6697
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6499
6698
  process.exit(1);
6500
6699
  }
6501
6700
  });
6502
6701
  program.command("snapshot").description("Run visual snapshot tests per component variant").option("-p, --port <port>", "Port of running dev server (skips starting one)").option("--update", "Update existing snapshots instead of comparing").option("--component <name>", "Filter to a specific component").option("--spec <path>", "Path to snapshot spec file").option("--ci", "CI mode - exit 1 on mismatch").action(async (options) => {
6503
6702
  try {
6504
- const { snapshot } = await import("./snapshot-XOISO2IS.js");
6703
+ const { snapshot } = await import("./snapshot-C5DYIGIV.js");
6505
6704
  const result = await snapshot({
6506
6705
  port: options.port,
6507
6706
  update: options.update,
@@ -6513,13 +6712,13 @@ program.command("snapshot").description("Run visual snapshot tests per component
6513
6712
  process.exit(1);
6514
6713
  }
6515
6714
  } catch (error) {
6516
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6715
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6517
6716
  process.exit(1);
6518
6717
  }
6519
6718
  });
6520
6719
  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) => {
6521
6720
  try {
6522
- const { tokens } = await import("./tokens-T6SIVUT5.js");
6721
+ const { tokens } = await import("./tokens-OPVTVITP.js");
6523
6722
  const result = await tokens({
6524
6723
  config: options.config,
6525
6724
  json: options.json,
@@ -6532,13 +6731,13 @@ program.command("tokens").description("Discover and list design tokens from CSS/
6532
6731
  process.exit(1);
6533
6732
  }
6534
6733
  } catch (error) {
6535
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6734
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6536
6735
  process.exit(1);
6537
6736
  }
6538
6737
  });
6539
6738
  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) => {
6540
6739
  try {
6541
- const { generate } = await import("./generate-RJFS2JWA.js");
6740
+ const { generate } = await import("./generate-RYWIPDN2.js");
6542
6741
  const result = await generate({
6543
6742
  projectRoot: process.cwd(),
6544
6743
  component,
@@ -6546,11 +6745,11 @@ program.command("generate").description("Generate fragment files from component
6546
6745
  componentPattern: options.pattern
6547
6746
  });
6548
6747
  if (!result.success) {
6549
- console.error(pc24.red("\nGenerate completed with errors"));
6748
+ console.error(pc25.red("\nGenerate completed with errors"));
6550
6749
  process.exit(1);
6551
6750
  }
6552
6751
  } catch (error) {
6553
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6752
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6554
6753
  process.exit(1);
6555
6754
  }
6556
6755
  });
@@ -6558,7 +6757,7 @@ program.command("graph").description("Query the component relationship graph").a
6558
6757
  try {
6559
6758
  await graph(component, options);
6560
6759
  } catch (error) {
6561
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6760
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6562
6761
  process.exit(1);
6563
6762
  }
6564
6763
  });
@@ -6576,14 +6775,14 @@ program.command("perf").description("Profile component bundle sizes and performa
6576
6775
  process.exit(1);
6577
6776
  }
6578
6777
  } catch (error) {
6579
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6778
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6580
6779
  process.exit(1);
6581
6780
  }
6582
6781
  });
6583
6782
  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) => {
6584
6783
  try {
6585
6784
  const { config, configDir } = await loadConfig(options.config);
6586
- const { runTestCommand, listTests } = await import("./test-SI4NSHQX.js");
6785
+ const { runTestCommand, listTests } = await import("./test-JW7JIDFG.js");
6587
6786
  if (options.list) {
6588
6787
  await listTests(config, configDir, {
6589
6788
  component: options.component,
@@ -6616,7 +6815,7 @@ program.command("test").description("Run interaction tests for fragments with pl
6616
6815
  });
6617
6816
  process.exit(exitCode);
6618
6817
  } catch (error) {
6619
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6818
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6620
6819
  process.exit(1);
6621
6820
  }
6622
6821
  });
@@ -6631,7 +6830,46 @@ program.command("doctor").description("Diagnose design system configuration issu
6631
6830
  process.exit(1);
6632
6831
  }
6633
6832
  } catch (error) {
6634
- console.error(pc24.red("Error:"), error instanceof Error ? error.message : error);
6833
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6834
+ process.exit(1);
6835
+ }
6836
+ });
6837
+ var governCmd = program.command("govern").description("AI UI governance checks");
6838
+ governCmd.command("check").description("Validate a UISpec against governance policies").option("-i, --input <path>", "Path to UISpec JSON file (or - for stdin)").option("-c, --config <path>", "Path to govern.config.ts").option("-f, --format <format>", "Output format: summary, json, sarif", "summary").option("-q, --quiet", "Suppress non-error output").action(async (options) => {
6839
+ try {
6840
+ const { exitCode } = await governCheck({
6841
+ input: options.input,
6842
+ config: options.config,
6843
+ format: options.format,
6844
+ quiet: options.quiet
6845
+ });
6846
+ process.exit(exitCode);
6847
+ } catch (error) {
6848
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6849
+ process.exit(1);
6850
+ }
6851
+ });
6852
+ governCmd.command("init").description("Generate a fragments.config.ts with govern section").option("-o, --output <path>", "Output path", "fragments.config.ts").action(async (options) => {
6853
+ try {
6854
+ await governInit({ output: options.output });
6855
+ } catch (error) {
6856
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6857
+ process.exit(1);
6858
+ }
6859
+ });
6860
+ governCmd.command("report").description("Summarize governance audit log").action(async () => {
6861
+ try {
6862
+ await governReport();
6863
+ } catch (error) {
6864
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6865
+ process.exit(1);
6866
+ }
6867
+ });
6868
+ governCmd.command("connect").description("Connect your project to the Fragments Govern cloud dashboard").action(async () => {
6869
+ try {
6870
+ await governConnect();
6871
+ } catch (error) {
6872
+ console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
6635
6873
  process.exit(1);
6636
6874
  }
6637
6875
  });