@fragments-sdk/cli 0.7.17 → 0.8.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 +227 -53
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-QLTLLQBI.js → chunk-2JIKCJX3.js} +312 -24
  4. package/dist/chunk-2JIKCJX3.js.map +1 -0
  5. package/dist/{chunk-57OW43NL.js → chunk-CJEGT3WD.js} +2 -2
  6. package/dist/{chunk-7CRC46HV.js → chunk-GOVI6COW.js} +13 -3
  7. package/dist/chunk-GOVI6COW.js.map +1 -0
  8. package/dist/{chunk-WLXFE6XW.js → chunk-NGIMCIK2.js} +60 -2
  9. package/dist/chunk-NGIMCIK2.js.map +1 -0
  10. package/dist/{chunk-M42XIHPV.js → chunk-WI6SLMSO.js} +2 -2
  11. package/dist/core/index.d.ts +110 -3
  12. package/dist/core/index.js +12 -2
  13. package/dist/{defineFragment-BI9KoPrs.d.ts → defineFragment-D0UTve-I.d.ts} +9 -0
  14. package/dist/{generate-ICIPKCKV.js → generate-35OIMW4Y.js} +4 -4
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.js +4 -4
  17. package/dist/{init-DIZ6UNBL.js → init-KFYN37ZY.js} +4 -4
  18. package/dist/mcp-bin.js +67 -3
  19. package/dist/mcp-bin.js.map +1 -1
  20. package/dist/{scan-X3DI2X5G.js → scan-65RH3QMM.js} +5 -5
  21. package/dist/{service-JEWWTSKI.js → service-A5GIGGGK.js} +3 -3
  22. package/dist/{static-viewer-JIWCYKVK.js → static-viewer-NSODM5VX.js} +3 -3
  23. package/dist/{test-36UELXTE.js → test-RPWZAYSJ.js} +3 -3
  24. package/dist/{tokens-K2AGUUOJ.js → tokens-NIXSZRX7.js} +4 -4
  25. package/dist/{viewer-QKIAPTPG.js → viewer-HZK4BSDK.js} +43 -12
  26. package/dist/viewer-HZK4BSDK.js.map +1 -0
  27. package/package.json +3 -3
  28. package/src/bin.ts +32 -0
  29. package/src/build.ts +47 -0
  30. package/src/commands/perf.ts +249 -0
  31. package/src/core/bundle-measurer.ts +421 -0
  32. package/src/core/index.ts +16 -0
  33. package/src/core/performance-presets.ts +142 -0
  34. package/src/core/schema.ts +10 -0
  35. package/src/core/types.ts +6 -0
  36. package/src/mcp/server.ts +77 -0
  37. package/src/viewer/components/BottomPanel.tsx +8 -0
  38. package/src/viewer/components/PerformancePanel.tsx +301 -0
  39. package/src/viewer/hooks/useAppState.ts +1 -1
  40. package/src/viewer/vite-plugin.ts +36 -0
  41. package/dist/chunk-7CRC46HV.js.map +0 -1
  42. package/dist/chunk-QLTLLQBI.js.map +0 -1
  43. package/dist/chunk-WLXFE6XW.js.map +0 -1
  44. package/dist/viewer-QKIAPTPG.js.map +0 -1
  45. /package/dist/{chunk-57OW43NL.js.map → chunk-CJEGT3WD.js.map} +0 -0
  46. /package/dist/{chunk-M42XIHPV.js.map → chunk-WI6SLMSO.js.map} +0 -0
  47. /package/dist/{generate-ICIPKCKV.js.map → generate-35OIMW4Y.js.map} +0 -0
  48. /package/dist/{init-DIZ6UNBL.js.map → init-KFYN37ZY.js.map} +0 -0
  49. /package/dist/{scan-X3DI2X5G.js.map → scan-65RH3QMM.js.map} +0 -0
  50. /package/dist/{service-JEWWTSKI.js.map → service-A5GIGGGK.js.map} +0 -0
  51. /package/dist/{static-viewer-JIWCYKVK.js.map → static-viewer-NSODM5VX.js.map} +0 -0
  52. /package/dist/{test-36UELXTE.js.map → test-RPWZAYSJ.js.map} +0 -0
  53. /package/dist/{tokens-K2AGUUOJ.js.map → tokens-NIXSZRX7.js.map} +0 -0
package/dist/bin.js CHANGED
@@ -3,21 +3,23 @@ import { createRequire as __banner_createRequire } from 'module'; const require
3
3
  import {
4
4
  buildFragments,
5
5
  buildFragmentsDir,
6
+ measureBundleSizes,
6
7
  runAnalyzeCommand,
7
8
  runDiffCommand,
8
9
  runScreenshotCommand,
10
+ toPerformanceData,
9
11
  validateAll,
10
12
  validateCoverage,
11
13
  validateSchema,
12
14
  validateSnippets
13
- } from "./chunk-QLTLLQBI.js";
15
+ } from "./chunk-2JIKCJX3.js";
14
16
  import {
15
17
  scan
16
- } from "./chunk-M42XIHPV.js";
18
+ } from "./chunk-WI6SLMSO.js";
17
19
  import {
18
20
  loadConfig,
19
21
  loadFragmentFile
20
- } from "./chunk-57OW43NL.js";
22
+ } from "./chunk-CJEGT3WD.js";
21
23
  import {
22
24
  discoverFragmentFiles
23
25
  } from "./chunk-AWYCDRPG.js";
@@ -38,9 +40,12 @@ import {
38
40
  shutdownSharedPool
39
41
  } from "./chunk-YMPGYEWK.js";
40
42
  import {
41
- generateContext
42
- } from "./chunk-WLXFE6XW.js";
43
- import "./chunk-7CRC46HV.js";
43
+ budgetBar,
44
+ formatBytes,
45
+ generateContext,
46
+ resolvePerformanceConfig
47
+ } from "./chunk-NGIMCIK2.js";
48
+ import "./chunk-GOVI6COW.js";
44
49
  import {
45
50
  BRAND
46
51
  } from "./chunk-EKLMXTWU.js";
@@ -48,7 +53,7 @@ import "./chunk-Z7EY4VHE.js";
48
53
 
49
54
  // src/bin.ts
50
55
  import { Command } from "commander";
51
- import pc21 from "picocolors";
56
+ import pc22 from "picocolors";
52
57
  import { readFileSync } from "fs";
53
58
  import { fileURLToPath } from "url";
54
59
  import { dirname as dirname4, join as join10 } from "path";
@@ -1806,7 +1811,7 @@ ${BRAND.name} Dev Server
1806
1811
  }
1807
1812
  }
1808
1813
  }
1809
- const { createDevServer } = await import("./viewer-QKIAPTPG.js");
1814
+ const { createDevServer } = await import("./viewer-HZK4BSDK.js");
1810
1815
  console.log(pc7.dim("\nStarting dev server..."));
1811
1816
  const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
1812
1817
  try {
@@ -5207,6 +5212,157 @@ Connected Islands (${islands.length})
5207
5212
  }
5208
5213
  }
5209
5214
 
5215
+ // src/commands/perf.ts
5216
+ import pc21 from "picocolors";
5217
+ import { readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
5218
+ import { resolve as resolve7 } from "path";
5219
+ async function perf(options) {
5220
+ const { config: configPath, json, component, concurrency, detail } = options;
5221
+ const shouldWrite = options.write !== false;
5222
+ const { config, configDir } = await loadConfig(configPath);
5223
+ const perfConfig = resolvePerformanceConfig(config.performance ?? "standard");
5224
+ const outFile = resolve7(configDir, config.outFile ?? BRAND.outFile);
5225
+ let data;
5226
+ try {
5227
+ data = JSON.parse(await readFile7(outFile, "utf-8"));
5228
+ } catch {
5229
+ throw new Error(
5230
+ `Could not read ${BRAND.outFile}. Run \`${BRAND.cliCommand} build\` first.`
5231
+ );
5232
+ }
5233
+ let fragments = data.fragments;
5234
+ if (component) {
5235
+ const match = Object.entries(fragments).find(
5236
+ ([name]) => name.toLowerCase() === component.toLowerCase()
5237
+ );
5238
+ if (!match) {
5239
+ throw new Error(
5240
+ `Component "${component}" not found in ${BRAND.outFile}.`
5241
+ );
5242
+ }
5243
+ fragments = { [match[0]]: match[1] };
5244
+ }
5245
+ if (!json) {
5246
+ console.log(pc21.cyan(`
5247
+ ${BRAND.name} Performance Profiler
5248
+ `));
5249
+ console.log(pc21.dim(`Preset: ${perfConfig.preset} (${formatBytes(perfConfig.budgets.bundleSize)} budget)`));
5250
+ console.log(pc21.dim(`Measuring ${Object.keys(fragments).length} component(s)...
5251
+ `));
5252
+ }
5253
+ const result = await measureBundleSizes(fragments, configDir, {
5254
+ concurrency: concurrency ?? 4,
5255
+ perfConfig,
5256
+ onProgress: !json ? (done, total, name) => {
5257
+ process.stdout.write(`\r${pc21.dim(`[${done}/${total}]`)} ${name}`);
5258
+ } : void 0
5259
+ });
5260
+ if (!json) {
5261
+ process.stdout.write("\r" + " ".repeat(80) + "\r");
5262
+ }
5263
+ const perfResults = [];
5264
+ for (const [name, measurement] of result.measurements) {
5265
+ const fragment = fragments[name];
5266
+ const contractBudget = fragment?.contract?.performanceBudget;
5267
+ const perfData = toPerformanceData(measurement, perfConfig, contractBudget);
5268
+ perfResults.push({ name, data: perfData });
5269
+ }
5270
+ perfResults.sort((a, b) => b.data.bundleSize - a.data.bundleSize);
5271
+ const tiers = { lightweight: 0, moderate: 0, heavy: 0 };
5272
+ let overBudgetCount = 0;
5273
+ for (const { data: d } of perfResults) {
5274
+ tiers[d.complexity]++;
5275
+ if (d.overBudget) overBudgetCount++;
5276
+ }
5277
+ if (json) {
5278
+ const output = {
5279
+ preset: perfConfig.preset,
5280
+ budget: perfConfig.budgets.bundleSize,
5281
+ total: perfResults.length,
5282
+ overBudget: overBudgetCount,
5283
+ tiers,
5284
+ components: perfResults.map(({ name, data: d }) => ({
5285
+ name,
5286
+ ...d
5287
+ })),
5288
+ errors: result.errors,
5289
+ elapsed: result.elapsed
5290
+ };
5291
+ console.log(JSON.stringify(output, null, 2));
5292
+ } else {
5293
+ const nameWidth = Math.max(20, ...perfResults.map((r) => r.name.length)) + 2;
5294
+ console.log(
5295
+ pc21.bold(
5296
+ "Component".padEnd(nameWidth) + "Gzip".padStart(8) + "Raw".padStart(10) + "Budget".padStart(8) + "Tier".padStart(14) + " Bar"
5297
+ )
5298
+ );
5299
+ console.log(pc21.dim("\u2500".repeat(nameWidth + 60)));
5300
+ for (const { name, data: d } of perfResults) {
5301
+ const tierColor = d.complexity === "lightweight" ? pc21.green : d.complexity === "moderate" ? pc21.yellow : pc21.red;
5302
+ const budgetColor = d.overBudget ? pc21.red : pc21.green;
5303
+ console.log(
5304
+ name.padEnd(nameWidth) + formatBytes(d.bundleSize).padStart(8) + formatBytes(d.rawSize).padStart(10) + budgetColor(`${d.budgetPercent}%`.padStart(8)) + tierColor(d.complexity.padStart(14)) + " " + budgetBar(d.budgetPercent)
5305
+ );
5306
+ if (d.imports?.length && (detail || d.overBudget)) {
5307
+ for (const imp of d.imports.slice(0, 5)) {
5308
+ const barWidth = Math.max(1, Math.round(imp.percent / 5));
5309
+ const impBar = pc21.dim("\u2588".repeat(barWidth));
5310
+ console.log(
5311
+ pc21.dim(" \u2514\u2500\u2500 ") + pc21.dim(imp.path.length > 50 ? "\u2026" + imp.path.slice(-49) : imp.path) + pc21.dim(` \u2192 ${formatBytes(imp.bytes)} (${imp.percent}%) `) + impBar
5312
+ );
5313
+ }
5314
+ if (d.imports.length > 5) {
5315
+ console.log(pc21.dim(` \u2514\u2500\u2500 \u2026 and ${d.imports.length - 5} more files`));
5316
+ }
5317
+ }
5318
+ }
5319
+ console.log(pc21.dim("\u2500".repeat(nameWidth + 60)));
5320
+ if (result.errors.length > 0) {
5321
+ console.log(pc21.yellow(`
5322
+ ${result.errors.length} component(s) could not be measured:`));
5323
+ for (const err of result.errors.slice(0, 5)) {
5324
+ console.log(pc21.dim(` ${err.name}: ${err.error}`));
5325
+ }
5326
+ if (result.errors.length > 5) {
5327
+ console.log(pc21.dim(` ... and ${result.errors.length - 5} more`));
5328
+ }
5329
+ }
5330
+ console.log(`
5331
+ ${pc21.bold("Summary")}`);
5332
+ console.log(` Total: ${perfResults.length} components measured in ${(result.elapsed / 1e3).toFixed(1)}s`);
5333
+ console.log(` Tiers: ${pc21.green(`${tiers.lightweight} lightweight`)} \xB7 ${pc21.yellow(`${tiers.moderate} moderate`)} \xB7 ${pc21.red(`${tiers.heavy} heavy`)}`);
5334
+ if (overBudgetCount > 0) {
5335
+ console.log(pc21.red(` Over budget: ${overBudgetCount} component(s) exceed ${formatBytes(perfConfig.budgets.bundleSize)} budget`));
5336
+ } else {
5337
+ console.log(pc21.green(" All components within budget"));
5338
+ }
5339
+ console.log("");
5340
+ }
5341
+ if (shouldWrite && perfResults.length > 0) {
5342
+ for (const { name, data: d } of perfResults) {
5343
+ if (data.fragments[name]) {
5344
+ data.fragments[name].performance = d;
5345
+ }
5346
+ }
5347
+ data.performanceSummary = {
5348
+ preset: perfConfig.preset,
5349
+ budget: perfConfig.budgets.bundleSize,
5350
+ total: perfResults.length,
5351
+ overBudget: overBudgetCount,
5352
+ tiers
5353
+ };
5354
+ await writeFile8(outFile, JSON.stringify(data));
5355
+ if (!json) {
5356
+ console.log(pc21.dim(`Results written to ${BRAND.outFile}`));
5357
+ }
5358
+ }
5359
+ return {
5360
+ success: overBudgetCount === 0,
5361
+ total: perfResults.length,
5362
+ overBudget: overBudgetCount
5363
+ };
5364
+ }
5365
+
5210
5366
  // src/bin.ts
5211
5367
  var __dirname = dirname4(fileURLToPath(import.meta.url));
5212
5368
  var pkg = JSON.parse(readFileSync(join10(__dirname, "../package.json"), "utf-8"));
@@ -5219,7 +5375,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
5219
5375
  process.exit(1);
5220
5376
  }
5221
5377
  } catch (error) {
5222
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5378
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5223
5379
  process.exit(1);
5224
5380
  }
5225
5381
  });
@@ -5239,7 +5395,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
5239
5395
  process.exit(1);
5240
5396
  }
5241
5397
  } catch (error) {
5242
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5398
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5243
5399
  process.exit(1);
5244
5400
  }
5245
5401
  });
@@ -5258,7 +5414,7 @@ program.command("context").description("Generate AI-ready context for your desig
5258
5414
  process.exit(1);
5259
5415
  }
5260
5416
  } catch (error) {
5261
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5417
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5262
5418
  process.exit(1);
5263
5419
  }
5264
5420
  });
@@ -5285,7 +5441,7 @@ program.command("ai").description("Generate context optimized for AI assistants
5285
5441
  }
5286
5442
  }
5287
5443
  } catch (error) {
5288
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5444
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5289
5445
  process.exit(1);
5290
5446
  }
5291
5447
  });
@@ -5293,7 +5449,7 @@ program.command("list").description("List all discovered fragment files").option
5293
5449
  try {
5294
5450
  await list(options);
5295
5451
  } catch (error) {
5296
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5452
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5297
5453
  process.exit(1);
5298
5454
  }
5299
5455
  });
@@ -5301,7 +5457,7 @@ program.command("reset").description("Reset to initial state (delete all generat
5301
5457
  try {
5302
5458
  await reset(options);
5303
5459
  } catch (error) {
5304
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5460
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5305
5461
  process.exit(1);
5306
5462
  }
5307
5463
  });
@@ -5315,7 +5471,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
5315
5471
  variants: options.variants
5316
5472
  });
5317
5473
  } catch (error) {
5318
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5474
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5319
5475
  process.exit(1);
5320
5476
  }
5321
5477
  });
@@ -5330,7 +5486,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
5330
5486
  exclude: options.exclude
5331
5487
  });
5332
5488
  } catch (error) {
5333
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5489
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5334
5490
  process.exit(1);
5335
5491
  }
5336
5492
  });
@@ -5345,9 +5501,9 @@ program.command("dev").description("Start the development server with live compo
5345
5501
  skipBuild: options.skipBuild
5346
5502
  });
5347
5503
  } catch (error) {
5348
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5504
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5349
5505
  if (error instanceof Error && error.stack) {
5350
- console.error(pc21.dim(error.stack));
5506
+ console.error(pc22.dim(error.stack));
5351
5507
  }
5352
5508
  process.exit(1);
5353
5509
  }
@@ -5368,7 +5524,7 @@ program.command("screenshot").description("Capture screenshots of component vari
5368
5524
  process.exit(1);
5369
5525
  }
5370
5526
  } catch (error) {
5371
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5527
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5372
5528
  process.exit(1);
5373
5529
  }
5374
5530
  });
@@ -5387,7 +5543,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
5387
5543
  process.exit(1);
5388
5544
  }
5389
5545
  } catch (error) {
5390
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5546
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5391
5547
  process.exit(1);
5392
5548
  }
5393
5549
  });
@@ -5406,8 +5562,8 @@ program.command("compare").argument("[component]", "Component name to compare").
5406
5562
  process.exit(1);
5407
5563
  }
5408
5564
  } catch (error) {
5409
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5410
- console.log(pc21.dim(`
5565
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5566
+ console.log(pc22.dim(`
5411
5567
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5412
5568
  process.exit(1);
5413
5569
  }
@@ -5426,7 +5582,7 @@ program.command("analyze").description("Analyze design system and generate repor
5426
5582
  process.exit(1);
5427
5583
  }
5428
5584
  } catch (error) {
5429
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5585
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5430
5586
  process.exit(1);
5431
5587
  }
5432
5588
  });
@@ -5445,7 +5601,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
5445
5601
  if (options.ci) {
5446
5602
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
5447
5603
  } else {
5448
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5604
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5449
5605
  }
5450
5606
  process.exit(1);
5451
5607
  }
@@ -5462,7 +5618,7 @@ program.command("audit").description("Scan all fragments and show compliance met
5462
5618
  if (options.json) {
5463
5619
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
5464
5620
  } else {
5465
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5621
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5466
5622
  }
5467
5623
  process.exit(1);
5468
5624
  }
@@ -5484,7 +5640,7 @@ program.command("a11y").description("Run accessibility checks on all component v
5484
5640
  if (options.json) {
5485
5641
  console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
5486
5642
  } else {
5487
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5643
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5488
5644
  }
5489
5645
  process.exit(1);
5490
5646
  }
@@ -5507,7 +5663,7 @@ program.command("enhance").description("AI-powered documentation generation from
5507
5663
  if (options.format === "json") {
5508
5664
  console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
5509
5665
  } else {
5510
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5666
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5511
5667
  }
5512
5668
  process.exit(1);
5513
5669
  }
@@ -5528,7 +5684,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
5528
5684
  process.exit(1);
5529
5685
  }
5530
5686
  } catch (error) {
5531
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5687
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5532
5688
  process.exit(1);
5533
5689
  }
5534
5690
  });
@@ -5541,7 +5697,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
5541
5697
  format: options.format
5542
5698
  });
5543
5699
  } catch (error) {
5544
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5700
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5545
5701
  process.exit(1);
5546
5702
  }
5547
5703
  });
@@ -5553,7 +5709,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
5553
5709
  json: options.json
5554
5710
  });
5555
5711
  } catch (error) {
5556
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5712
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5557
5713
  process.exit(1);
5558
5714
  }
5559
5715
  });
@@ -5567,9 +5723,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
5567
5723
  port: options.port
5568
5724
  });
5569
5725
  } catch (error) {
5570
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5726
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5571
5727
  if (action === "update") {
5572
- console.log(pc21.dim(`
5728
+ console.log(pc22.dim(`
5573
5729
  Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5574
5730
  }
5575
5731
  process.exit(1);
@@ -5577,27 +5733,27 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5577
5733
  });
5578
5734
  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) => {
5579
5735
  try {
5580
- const { generateViewerFromJson } = await import("./static-viewer-JIWCYKVK.js");
5736
+ const { generateViewerFromJson } = await import("./static-viewer-NSODM5VX.js");
5581
5737
  const fs2 = await import("fs/promises");
5582
5738
  const path = await import("path");
5583
5739
  const inputPath = path.resolve(process.cwd(), options.input);
5584
5740
  const outputPath = path.resolve(process.cwd(), options.output);
5585
- console.log(pc21.cyan(`
5741
+ console.log(pc22.cyan(`
5586
5742
  ${BRAND.name} Viewer Generator
5587
5743
  `));
5588
5744
  try {
5589
5745
  await fs2.access(inputPath);
5590
5746
  } catch {
5591
- console.log(pc21.red(`Error: ${options.input} not found.`));
5592
- console.log(pc21.dim(`
5593
- Run ${pc21.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
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}
5594
5750
  `));
5595
5751
  process.exit(1);
5596
5752
  }
5597
- console.log(pc21.dim(`Reading: ${options.input}`));
5753
+ console.log(pc22.dim(`Reading: ${options.input}`));
5598
5754
  const html = await generateViewerFromJson(inputPath);
5599
5755
  await fs2.writeFile(outputPath, html);
5600
- console.log(pc21.green(`
5756
+ console.log(pc22.green(`
5601
5757
  \u2713 Generated: ${options.output}
5602
5758
  `));
5603
5759
  if (options.open) {
@@ -5606,7 +5762,7 @@ Run ${pc21.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
5606
5762
  exec(`${openCmd} "${outputPath}"`);
5607
5763
  }
5608
5764
  } catch (error) {
5609
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5765
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5610
5766
  process.exit(1);
5611
5767
  }
5612
5768
  });
@@ -5619,33 +5775,33 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
5619
5775
  component: options.component
5620
5776
  });
5621
5777
  } catch (error) {
5622
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5778
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5623
5779
  process.exit(1);
5624
5780
  }
5625
5781
  });
5626
5782
  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) => {
5627
5783
  try {
5628
- const { init } = await import("./init-DIZ6UNBL.js");
5784
+ const { init } = await import("./init-KFYN37ZY.js");
5629
5785
  const result = await init({
5630
5786
  projectRoot: process.cwd(),
5631
5787
  force: options.force,
5632
5788
  yes: options.yes
5633
5789
  });
5634
5790
  if (!result.success) {
5635
- console.error(pc21.red("\nInit failed with errors:"));
5791
+ console.error(pc22.red("\nInit failed with errors:"));
5636
5792
  for (const error of result.errors) {
5637
- console.error(pc21.red(` - ${error}`));
5793
+ console.error(pc22.red(` - ${error}`));
5638
5794
  }
5639
5795
  process.exit(1);
5640
5796
  }
5641
5797
  } catch (error) {
5642
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5798
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5643
5799
  process.exit(1);
5644
5800
  }
5645
5801
  });
5646
5802
  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) => {
5647
5803
  try {
5648
- const { tokens } = await import("./tokens-K2AGUUOJ.js");
5804
+ const { tokens } = await import("./tokens-NIXSZRX7.js");
5649
5805
  const result = await tokens({
5650
5806
  config: options.config,
5651
5807
  json: options.json,
@@ -5658,13 +5814,13 @@ program.command("tokens").description("Discover and list design tokens from CSS/
5658
5814
  process.exit(1);
5659
5815
  }
5660
5816
  } catch (error) {
5661
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5817
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5662
5818
  process.exit(1);
5663
5819
  }
5664
5820
  });
5665
5821
  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) => {
5666
5822
  try {
5667
- const { generate } = await import("./generate-ICIPKCKV.js");
5823
+ const { generate } = await import("./generate-35OIMW4Y.js");
5668
5824
  const result = await generate({
5669
5825
  projectRoot: process.cwd(),
5670
5826
  component,
@@ -5672,11 +5828,11 @@ program.command("generate").description("Generate fragment files from component
5672
5828
  componentPattern: options.pattern
5673
5829
  });
5674
5830
  if (!result.success) {
5675
- console.error(pc21.red("\nGenerate completed with errors"));
5831
+ console.error(pc22.red("\nGenerate completed with errors"));
5676
5832
  process.exit(1);
5677
5833
  }
5678
5834
  } catch (error) {
5679
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5835
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5680
5836
  process.exit(1);
5681
5837
  }
5682
5838
  });
@@ -5684,14 +5840,32 @@ program.command("graph").description("Query the component relationship graph").a
5684
5840
  try {
5685
5841
  await graph(component, options);
5686
5842
  } catch (error) {
5687
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5843
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5844
+ process.exit(1);
5845
+ }
5846
+ });
5847
+ program.command("perf").description("Profile component bundle sizes and performance budgets").option("-c, --config <path>", "Path to config file").option("--json", "Output results as JSON").option("--component <name>", "Measure specific component only").option("--no-write", "Do not write results to fragments.json").option("--detail", "Show import breakdown for all components").option("--concurrency <n>", "Max concurrent measurements", (v) => Number.parseInt(v, 10), 4).action(async (options) => {
5848
+ try {
5849
+ const result = await perf({
5850
+ config: options.config,
5851
+ json: options.json,
5852
+ component: options.component,
5853
+ write: options.write,
5854
+ detail: options.detail,
5855
+ concurrency: options.concurrency
5856
+ });
5857
+ if (!result.success) {
5858
+ process.exit(1);
5859
+ }
5860
+ } catch (error) {
5861
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5688
5862
  process.exit(1);
5689
5863
  }
5690
5864
  });
5691
5865
  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) => {
5692
5866
  try {
5693
5867
  const { config, configDir } = await loadConfig(options.config);
5694
- const { runTestCommand, listTests } = await import("./test-36UELXTE.js");
5868
+ const { runTestCommand, listTests } = await import("./test-RPWZAYSJ.js");
5695
5869
  if (options.list) {
5696
5870
  await listTests(config, configDir, {
5697
5871
  component: options.component,
@@ -5724,7 +5898,7 @@ program.command("test").description("Run interaction tests for fragments with pl
5724
5898
  });
5725
5899
  process.exit(exitCode);
5726
5900
  } catch (error) {
5727
- console.error(pc21.red("Error:"), error instanceof Error ? error.message : error);
5901
+ console.error(pc22.red("Error:"), error instanceof Error ? error.message : error);
5728
5902
  process.exit(1);
5729
5903
  }
5730
5904
  });