@fragments-sdk/cli 0.13.0 → 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 (47) hide show
  1. package/dist/bin.js +152 -16
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-3SOAPJDX.js → chunk-55KERLWL.js} +2 -2
  4. package/dist/{chunk-4K7EAQ5L.js → chunk-7K3VROEP.js} +2 -2
  5. package/dist/{chunk-RF3C6LGA.js → chunk-FZLPVN32.js} +5 -5
  6. package/dist/{chunk-QM7SVOGF.js → chunk-I34BC3CU.js} +10 -1
  7. package/dist/chunk-I34BC3CU.js.map +1 -0
  8. package/dist/{chunk-DXX6HADE.js → chunk-PJT5IZ37.js} +2 -2
  9. package/dist/{chunk-UV5JQV3R.js → chunk-TXFCEDOC.js} +2 -2
  10. package/dist/{chunk-FO6EBJWP.js → chunk-Z5BUXIFJ.js} +5 -5
  11. package/dist/{chunk-SM674YAS.js → chunk-ZKTFKHWN.js} +2 -2
  12. package/dist/core/index.js +1 -1
  13. package/dist/{discovery-VSGC76JN.js → discovery-VDANZAJ2.js} +3 -3
  14. package/dist/{generate-QZXOXYFW.js → generate-RYWIPDN2.js} +4 -4
  15. package/dist/index.js +6 -6
  16. package/dist/{init-XK6PRUE5.js → init-U6534EMZ.js} +5 -5
  17. package/dist/mcp-bin.js +2 -2
  18. package/dist/{scan-CHQHXWVD.js → scan-LE2JEIJ4.js} +6 -6
  19. package/dist/{scan-generate-U3RFVDTX.js → scan-generate-TFZVL3BT.js} +4 -4
  20. package/dist/{service-MMEKG4MZ.js → service-S5LXPKV4.js} +3 -3
  21. package/dist/{snapshot-53TUR3HW.js → snapshot-C5DYIGIV.js} +2 -2
  22. package/dist/{static-viewer-KKCR4KXR.js → static-viewer-DUVC4UIM.js} +3 -3
  23. package/dist/{test-5UCKXYSC.js → test-JW7JIDFG.js} +4 -4
  24. package/dist/{tokens-L46MK5AW.js → tokens-OPVTVITP.js} +5 -5
  25. package/dist/{viewer-M2EQQSGE.js → viewer-OBTEPVY7.js} +13 -13
  26. package/package.json +6 -6
  27. package/src/bin.ts +15 -3
  28. package/src/commands/govern.ts +158 -1
  29. package/dist/chunk-QM7SVOGF.js.map +0 -1
  30. /package/dist/{chunk-3SOAPJDX.js.map → chunk-55KERLWL.js.map} +0 -0
  31. /package/dist/{chunk-4K7EAQ5L.js.map → chunk-7K3VROEP.js.map} +0 -0
  32. /package/dist/{chunk-RF3C6LGA.js.map → chunk-FZLPVN32.js.map} +0 -0
  33. /package/dist/{chunk-DXX6HADE.js.map → chunk-PJT5IZ37.js.map} +0 -0
  34. /package/dist/{chunk-UV5JQV3R.js.map → chunk-TXFCEDOC.js.map} +0 -0
  35. /package/dist/{chunk-FO6EBJWP.js.map → chunk-Z5BUXIFJ.js.map} +0 -0
  36. /package/dist/{chunk-SM674YAS.js.map → chunk-ZKTFKHWN.js.map} +0 -0
  37. /package/dist/{discovery-VSGC76JN.js.map → discovery-VDANZAJ2.js.map} +0 -0
  38. /package/dist/{generate-QZXOXYFW.js.map → generate-RYWIPDN2.js.map} +0 -0
  39. /package/dist/{init-XK6PRUE5.js.map → init-U6534EMZ.js.map} +0 -0
  40. /package/dist/{scan-CHQHXWVD.js.map → scan-LE2JEIJ4.js.map} +0 -0
  41. /package/dist/{scan-generate-U3RFVDTX.js.map → scan-generate-TFZVL3BT.js.map} +0 -0
  42. /package/dist/{service-MMEKG4MZ.js.map → service-S5LXPKV4.js.map} +0 -0
  43. /package/dist/{snapshot-53TUR3HW.js.map → snapshot-C5DYIGIV.js.map} +0 -0
  44. /package/dist/{static-viewer-KKCR4KXR.js.map → static-viewer-DUVC4UIM.js.map} +0 -0
  45. /package/dist/{test-5UCKXYSC.js.map → test-JW7JIDFG.js.map} +0 -0
  46. /package/dist/{tokens-L46MK5AW.js.map → tokens-OPVTVITP.js.map} +0 -0
  47. /package/dist/{viewer-M2EQQSGE.js.map → viewer-OBTEPVY7.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-DXX6HADE.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-RF3C6LGA.js";
25
+ } from "./chunk-FZLPVN32.js";
26
26
  import {
27
27
  createComponentExtractor
28
28
  } from "./chunk-EYXVAMEX.js";
29
29
  import {
30
30
  scan
31
- } from "./chunk-FO6EBJWP.js";
31
+ } from "./chunk-Z5BUXIFJ.js";
32
32
  import {
33
33
  loadConfig,
34
34
  loadFragmentFile,
35
35
  parseFragmentFile
36
- } from "./chunk-3SOAPJDX.js";
36
+ } from "./chunk-55KERLWL.js";
37
37
  import {
38
38
  discoverFragmentFiles
39
- } from "./chunk-SM674YAS.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-4K7EAQ5L.js";
55
+ } from "./chunk-7K3VROEP.js";
56
56
  import "./chunk-D2CDBRNU.js";
57
57
  import {
58
58
  BRAND,
@@ -60,7 +60,7 @@ import {
60
60
  formatBytes,
61
61
  generateContext,
62
62
  resolvePerformanceConfig
63
- } from "./chunk-QM7SVOGF.js";
63
+ } from "./chunk-I34BC3CU.js";
64
64
  import "./chunk-Z7EY4VHE.js";
65
65
 
66
66
  // src/bin.ts
@@ -1901,7 +1901,7 @@ ${BRAND.name} Dev Server
1901
1901
  }
1902
1902
  }
1903
1903
  }
1904
- const { createDevServer } = await import("./viewer-M2EQQSGE.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 {
@@ -6049,12 +6049,140 @@ async function governInit(options = {}) {
6049
6049
  const { writeFile: writeFile10 } = await import("fs/promises");
6050
6050
  const { resolve: resolve9 } = await import("path");
6051
6051
  const { generateConfigTemplate } = await import("@fragments-sdk/govern");
6052
- const outputPath = resolve9(options.output ?? "govern.config.ts");
6052
+ const outputPath = resolve9(options.output ?? "fragments.config.ts");
6053
6053
  const template = generateConfigTemplate();
6054
6054
  await writeFile10(outputPath, template, "utf-8");
6055
6055
  console.log(pc24.green(`\u2713 Created ${outputPath}
6056
6056
  `));
6057
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
+ }
6058
6186
  async function governReport() {
6059
6187
  const { readFile: readFile10 } = await import("fs/promises");
6060
6188
  console.log(pc24.cyan(`
@@ -6480,7 +6608,7 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
6480
6608
  });
6481
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) => {
6482
6610
  try {
6483
- const { generateViewerFromJson } = await import("./static-viewer-KKCR4KXR.js");
6611
+ const { generateViewerFromJson } = await import("./static-viewer-DUVC4UIM.js");
6484
6612
  const fs2 = await import("fs/promises");
6485
6613
  const path = await import("path");
6486
6614
  const inputPath = path.resolve(process.cwd(), options.input);
@@ -6545,7 +6673,7 @@ program.command("setup").description("Configure @fragments-sdk/ui in a consumer
6545
6673
  });
6546
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) => {
6547
6675
  try {
6548
- const { init } = await import("./init-XK6PRUE5.js");
6676
+ const { init } = await import("./init-U6534EMZ.js");
6549
6677
  const result = await init({
6550
6678
  projectRoot: process.cwd(),
6551
6679
  force: options.force,
@@ -6572,7 +6700,7 @@ program.command("init").description("Initialize fragments in a project (zero-con
6572
6700
  });
6573
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) => {
6574
6702
  try {
6575
- const { snapshot } = await import("./snapshot-53TUR3HW.js");
6703
+ const { snapshot } = await import("./snapshot-C5DYIGIV.js");
6576
6704
  const result = await snapshot({
6577
6705
  port: options.port,
6578
6706
  update: options.update,
@@ -6590,7 +6718,7 @@ program.command("snapshot").description("Run visual snapshot tests per component
6590
6718
  });
6591
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) => {
6592
6720
  try {
6593
- const { tokens } = await import("./tokens-L46MK5AW.js");
6721
+ const { tokens } = await import("./tokens-OPVTVITP.js");
6594
6722
  const result = await tokens({
6595
6723
  config: options.config,
6596
6724
  json: options.json,
@@ -6609,7 +6737,7 @@ program.command("tokens").description("Discover and list design tokens from CSS/
6609
6737
  });
6610
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) => {
6611
6739
  try {
6612
- const { generate } = await import("./generate-QZXOXYFW.js");
6740
+ const { generate } = await import("./generate-RYWIPDN2.js");
6613
6741
  const result = await generate({
6614
6742
  projectRoot: process.cwd(),
6615
6743
  component,
@@ -6654,7 +6782,7 @@ program.command("perf").description("Profile component bundle sizes and performa
6654
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) => {
6655
6783
  try {
6656
6784
  const { config, configDir } = await loadConfig(options.config);
6657
- const { runTestCommand, listTests } = await import("./test-5UCKXYSC.js");
6785
+ const { runTestCommand, listTests } = await import("./test-JW7JIDFG.js");
6658
6786
  if (options.list) {
6659
6787
  await listTests(config, configDir, {
6660
6788
  component: options.component,
@@ -6721,7 +6849,7 @@ governCmd.command("check").description("Validate a UISpec against governance pol
6721
6849
  process.exit(1);
6722
6850
  }
6723
6851
  });
6724
- governCmd.command("init").description("Generate a govern.config.ts template").option("-o, --output <path>", "Output path", "govern.config.ts").action(async (options) => {
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) => {
6725
6853
  try {
6726
6854
  await governInit({ output: options.output });
6727
6855
  } catch (error) {
@@ -6737,5 +6865,13 @@ governCmd.command("report").description("Summarize governance audit log").action
6737
6865
  process.exit(1);
6738
6866
  }
6739
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);
6873
+ process.exit(1);
6874
+ }
6875
+ });
6740
6876
  program.parse();
6741
6877
  //# sourceMappingURL=bin.js.map