@fragments-sdk/cli 0.14.3 → 0.15.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 (181) hide show
  1. package/README.md +0 -3
  2. package/dist/{ai-client-I6MDWNYA.js → ai-client-LSLQGOMM.js} +1 -2
  3. package/dist/bin.js +4745 -3817
  4. package/dist/bin.js.map +1 -1
  5. package/dist/{chunk-TXFCEDOC.js → chunk-2WXKALIG.js} +2 -2
  6. package/dist/{chunk-I34BC3CU.js → chunk-32LIWN2P.js} +1006 -3
  7. package/dist/chunk-32LIWN2P.js.map +1 -0
  8. package/dist/chunk-5JF26E55.js +1255 -0
  9. package/dist/chunk-5JF26E55.js.map +1 -0
  10. package/dist/{chunk-APTQIBS5.js → chunk-6SQPP47U.js} +153 -1342
  11. package/dist/chunk-6SQPP47U.js.map +1 -0
  12. package/dist/chunk-7DZC4YEV.js +294 -0
  13. package/dist/chunk-7DZC4YEV.js.map +1 -0
  14. package/dist/{chunk-PJT5IZ37.js → chunk-BJE3425I.js} +19 -52
  15. package/dist/{chunk-PJT5IZ37.js.map → chunk-BJE3425I.js.map} +1 -1
  16. package/dist/{chunk-55KERLWL.js → chunk-HQ6A6DTV.js} +1587 -1073
  17. package/dist/chunk-HQ6A6DTV.js.map +1 -0
  18. package/dist/chunk-MHIBEEW4.js +511 -0
  19. package/dist/chunk-MHIBEEW4.js.map +1 -0
  20. package/dist/{chunk-5A6X2Y73.js → chunk-ONUP6Z4W.js} +25 -13
  21. package/dist/chunk-ONUP6Z4W.js.map +1 -0
  22. package/dist/chunk-QCN35LJU.js +630 -0
  23. package/dist/chunk-QCN35LJU.js.map +1 -0
  24. package/dist/chunk-T47OLCSF.js +36 -0
  25. package/dist/chunk-T47OLCSF.js.map +1 -0
  26. package/dist/codebase-scanner-MQHUZC2G.js +21 -0
  27. package/dist/converter-7XM3Y6NJ.js +33 -0
  28. package/dist/converter-7XM3Y6NJ.js.map +1 -0
  29. package/dist/core/index.js +43 -2
  30. package/dist/create-IH4R45GE.js +806 -0
  31. package/dist/create-IH4R45GE.js.map +1 -0
  32. package/dist/{generate-RYWIPDN2.js → generate-PVOLUAAC.js} +4 -6
  33. package/dist/{generate-RYWIPDN2.js.map → generate-PVOLUAAC.js.map} +1 -1
  34. package/dist/govern-scan-OYFZYOQW.js +413 -0
  35. package/dist/govern-scan-OYFZYOQW.js.map +1 -0
  36. package/dist/index.d.ts +4 -23
  37. package/dist/index.js +15 -14
  38. package/dist/index.js.map +1 -1
  39. package/dist/{init-WRUSW7R5.js → init-SSGUSP7Z.js} +131 -129
  40. package/dist/init-SSGUSP7Z.js.map +1 -0
  41. package/dist/{init-cloud-REQ3XLHO.js → init-cloud-3DNKPWFB.js} +30 -5
  42. package/dist/{init-cloud-REQ3XLHO.js.map → init-cloud-3DNKPWFB.js.map} +1 -1
  43. package/dist/mcp-bin.js +5 -37
  44. package/dist/mcp-bin.js.map +1 -1
  45. package/dist/node-37AUE74M.js +65 -0
  46. package/dist/push-contracts-WY32TFP6.js +84 -0
  47. package/dist/push-contracts-WY32TFP6.js.map +1 -0
  48. package/dist/scan-PKSYSTRR.js +15 -0
  49. package/dist/{scan-generate-TFZVL3BT.js → scan-generate-VY27PIOX.js} +340 -52
  50. package/dist/scan-generate-VY27PIOX.js.map +1 -0
  51. package/dist/scanner-4KZNOXAK.js +12 -0
  52. package/dist/{service-HKJ6B7P7.js → service-QJGWUIVL.js} +41 -30
  53. package/dist/{snapshot-C5DYIGIV.js → snapshot-WIJMEIFT.js} +2 -3
  54. package/dist/{snapshot-C5DYIGIV.js.map → snapshot-WIJMEIFT.js.map} +1 -1
  55. package/dist/{static-viewer-DUVC4UIM.js → static-viewer-7QIBQZRC.js} +3 -4
  56. package/dist/static-viewer-7QIBQZRC.js.map +1 -0
  57. package/dist/{test-JW7JIDFG.js → test-64Z5BKBA.js} +4 -7
  58. package/dist/{test-JW7JIDFG.js.map → test-64Z5BKBA.js.map} +1 -1
  59. package/dist/token-normalizer-TEPOVBPV.js +312 -0
  60. package/dist/token-normalizer-TEPOVBPV.js.map +1 -0
  61. package/dist/token-parser-32KOIOFN.js +22 -0
  62. package/dist/token-parser-32KOIOFN.js.map +1 -0
  63. package/dist/{tokens-KE73G5JC.js → tokens-NZWFQIAB.js} +10 -9
  64. package/dist/{tokens-KE73G5JC.js.map → tokens-NZWFQIAB.js.map} +1 -1
  65. package/dist/tokens-generate-5JQSJ27E.js +85 -0
  66. package/dist/tokens-generate-5JQSJ27E.js.map +1 -0
  67. package/dist/tokens-push-HY3KO36V.js +148 -0
  68. package/dist/tokens-push-HY3KO36V.js.map +1 -0
  69. package/package.json +8 -6
  70. package/src/bin.ts +300 -48
  71. package/src/commands/__fixtures__/shadcn-label-wrapper/package.json +7 -0
  72. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +42 -0
  73. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.tsx +11 -0
  74. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +20 -0
  75. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.tsx +14 -0
  76. package/src/commands/__fixtures__/shadcn-label-wrapper/tsconfig.app.json +23 -0
  77. package/src/commands/__tests__/build-freshness.test.ts +231 -0
  78. package/src/commands/__tests__/create.test.ts +71 -0
  79. package/src/commands/__tests__/drift-sync.test.ts +1 -1
  80. package/src/commands/__tests__/govern.test.ts +258 -0
  81. package/src/commands/__tests__/init.test.ts +113 -0
  82. package/src/commands/__tests__/scan-generate.test.ts +189 -70
  83. package/src/commands/__tests__/verify.test.ts +91 -0
  84. package/src/commands/build.ts +54 -1
  85. package/src/commands/context.ts +1 -1
  86. package/src/commands/create.ts +536 -0
  87. package/src/commands/discover.ts +151 -0
  88. package/src/commands/doctor.ts +3 -2
  89. package/src/commands/enhance.ts +3 -1
  90. package/src/commands/govern-scan.ts +565 -0
  91. package/src/commands/govern.ts +67 -4
  92. package/src/commands/init-cloud.ts +32 -4
  93. package/src/commands/init.ts +152 -28
  94. package/src/commands/inspect.ts +290 -0
  95. package/src/commands/migrate-contract.ts +85 -0
  96. package/src/commands/push-contracts.ts +112 -0
  97. package/src/commands/scan-generate.ts +439 -51
  98. package/src/commands/scan.ts +14 -0
  99. package/src/commands/setup.ts +27 -50
  100. package/src/commands/sync.ts +2 -2
  101. package/src/commands/tokens-generate.ts +113 -0
  102. package/src/commands/tokens-push.ts +199 -0
  103. package/src/commands/verify.ts +195 -1
  104. package/src/core/__fixtures__/shadcn-input/input.tsx +7 -0
  105. package/src/core/__fixtures__/shadcn-input/tsconfig.json +14 -0
  106. package/src/core/__fixtures__/shadcn-label/label.tsx +11 -0
  107. package/src/core/__fixtures__/shadcn-label/primitive.tsx +14 -0
  108. package/src/core/__fixtures__/shadcn-label/tsconfig.json +14 -0
  109. package/src/core/__fixtures__/shadcn-radix-label/label.tsx +11 -0
  110. package/src/core/__fixtures__/shadcn-radix-label/node_modules/radix-ui/index.d.ts +12 -0
  111. package/src/core/__fixtures__/shadcn-radix-label/tsconfig.json +14 -0
  112. package/src/core/__tests__/contract-parity.test.ts +316 -0
  113. package/src/core/__tests__/token-resolver.test.ts +1 -1
  114. package/src/core/component-extractor.test.ts +40 -1
  115. package/src/core/config.ts +2 -1
  116. package/src/core/discovery.ts +13 -2
  117. package/src/core/drift-verifier.ts +123 -0
  118. package/src/core/extractor-adapter.ts +80 -0
  119. package/src/index.ts +3 -3
  120. package/src/mcp/__tests__/projectFields.test.ts +1 -1
  121. package/src/mcp/utils.ts +1 -50
  122. package/src/migrate/converter.ts +3 -3
  123. package/src/migrate/fragment-to-contract.ts +253 -0
  124. package/src/migrate/report.ts +1 -1
  125. package/src/scripts/token-benchmark.ts +121 -0
  126. package/src/service/__tests__/props-extractor.test.ts +94 -0
  127. package/src/service/__tests__/token-normalizer.test.ts +690 -0
  128. package/src/service/ast-utils.ts +4 -23
  129. package/src/service/babel-config.ts +23 -0
  130. package/src/service/enhance/converter.ts +61 -0
  131. package/src/service/enhance/props-extractor.ts +25 -8
  132. package/src/service/enhance/scanner.ts +5 -24
  133. package/src/service/index.ts +8 -0
  134. package/src/service/snippet-validation.ts +9 -3
  135. package/src/service/tailwind-v4-parser.ts +314 -0
  136. package/src/service/token-normalizer.ts +510 -0
  137. package/src/service/token-parser.ts +56 -0
  138. package/src/setup.ts +10 -39
  139. package/src/shared/index.ts +1 -0
  140. package/src/shared/project-fields.ts +46 -0
  141. package/src/theme/__tests__/component-contrast.test.ts +2 -2
  142. package/src/theme/__tests__/serializer.test.ts +1 -1
  143. package/src/theme/generator.ts +16 -1
  144. package/src/theme/schema.ts +8 -0
  145. package/src/theme/serializer.ts +13 -9
  146. package/src/theme/types.ts +8 -0
  147. package/src/validators.ts +1 -2
  148. package/src/viewer/__tests__/viewer-integration.test.ts +8 -8
  149. package/src/viewer/style-utils.ts +27 -412
  150. package/src/viewer/vite-plugin.ts +2 -2
  151. package/dist/chunk-55KERLWL.js.map +0 -1
  152. package/dist/chunk-5A6X2Y73.js.map +0 -1
  153. package/dist/chunk-APTQIBS5.js.map +0 -1
  154. package/dist/chunk-EYXVAMEX.js +0 -626
  155. package/dist/chunk-EYXVAMEX.js.map +0 -1
  156. package/dist/chunk-I34BC3CU.js.map +0 -1
  157. package/dist/chunk-LOYS64QS.js +0 -2453
  158. package/dist/chunk-LOYS64QS.js.map +0 -1
  159. package/dist/chunk-Z7EY4VHE.js +0 -50
  160. package/dist/chunk-ZKTFKHWN.js +0 -324
  161. package/dist/chunk-ZKTFKHWN.js.map +0 -1
  162. package/dist/discovery-VDANZAJ2.js +0 -28
  163. package/dist/init-WRUSW7R5.js.map +0 -1
  164. package/dist/sass.node-4XJK6YBF.js +0 -130708
  165. package/dist/sass.node-4XJK6YBF.js.map +0 -1
  166. package/dist/scan-YJHQIRKG.js +0 -14
  167. package/dist/scan-generate-TFZVL3BT.js.map +0 -1
  168. package/dist/viewer-2TZS3NDL.js +0 -2730
  169. package/dist/viewer-2TZS3NDL.js.map +0 -1
  170. package/src/build.ts +0 -612
  171. package/src/commands/dev.ts +0 -107
  172. package/src/core/auto-props.ts +0 -464
  173. package/src/core/component-extractor.ts +0 -1030
  174. package/src/core/token-resolver.ts +0 -155
  175. /package/dist/{ai-client-I6MDWNYA.js.map → ai-client-LSLQGOMM.js.map} +0 -0
  176. /package/dist/{chunk-TXFCEDOC.js.map → chunk-2WXKALIG.js.map} +0 -0
  177. /package/dist/{chunk-Z7EY4VHE.js.map → codebase-scanner-MQHUZC2G.js.map} +0 -0
  178. /package/dist/{discovery-VDANZAJ2.js.map → node-37AUE74M.js.map} +0 -0
  179. /package/dist/{scan-YJHQIRKG.js.map → scan-PKSYSTRR.js.map} +0 -0
  180. /package/dist/{service-HKJ6B7P7.js.map → scanner-4KZNOXAK.js.map} +0 -0
  181. /package/dist/{static-viewer-DUVC4UIM.js.map → service-QJGWUIVL.js.map} +0 -0
@@ -2,7 +2,15 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  BRAND,
4
4
  DEFAULTS
5
- } from "./chunk-I34BC3CU.js";
5
+ } from "./chunk-32LIWN2P.js";
6
+ import {
7
+ hexToRgb,
8
+ parseRgb,
9
+ parseTokenFiles
10
+ } from "./chunk-MHIBEEW4.js";
11
+ import {
12
+ BABEL_PARSER_OPTIONS
13
+ } from "./chunk-7DZC4YEV.js";
6
14
 
7
15
  // src/service/browser-pool.ts
8
16
  var BrowserPool = class {
@@ -72,8 +80,8 @@ var BrowserPool = class {
72
80
  }
73
81
  await this.clearContext(context);
74
82
  if (this.waitingQueue.length > 0) {
75
- const resolve5 = this.waitingQueue.shift();
76
- resolve5(context);
83
+ const resolve3 = this.waitingQueue.shift();
84
+ resolve3(context);
77
85
  return;
78
86
  }
79
87
  this.available.push(context);
@@ -100,7 +108,7 @@ var BrowserPool = class {
100
108
  clearTimeout(this.idleTimeout);
101
109
  this.idleTimeout = null;
102
110
  }
103
- for (const resolve5 of this.waitingQueue) {
111
+ for (const resolve3 of this.waitingQueue) {
104
112
  }
105
113
  this.waitingQueue = [];
106
114
  for (const context of this.contexts) {
@@ -187,9 +195,9 @@ var BrowserPool = class {
187
195
  * Wait for an available context.
188
196
  */
189
197
  waitForAvailable() {
190
- return new Promise((resolve5, reject) => {
198
+ return new Promise((resolve3, reject) => {
191
199
  const timeout = setTimeout(() => {
192
- const index = this.waitingQueue.indexOf(resolve5);
200
+ const index = this.waitingQueue.indexOf(resolve3);
193
201
  if (index > -1) {
194
202
  this.waitingQueue.splice(index, 1);
195
203
  }
@@ -202,7 +210,7 @@ var BrowserPool = class {
202
210
  }, 3e4);
203
211
  const wrappedResolve = (ctx) => {
204
212
  clearTimeout(timeout);
205
- resolve5(ctx);
213
+ resolve3(ctx);
206
214
  };
207
215
  this.waitingQueue.push(wrappedResolve);
208
216
  });
@@ -285,16 +293,16 @@ var Timer = class {
285
293
  }
286
294
  };
287
295
  function createDeferred() {
288
- let resolve5;
296
+ let resolve3;
289
297
  let reject;
290
298
  const promise = new Promise((res, rej) => {
291
- resolve5 = res;
299
+ resolve3 = res;
292
300
  reject = rej;
293
301
  });
294
- return { promise, resolve: resolve5, reject };
302
+ return { promise, resolve: resolve3, reject };
295
303
  }
296
304
  function sleep(ms) {
297
- return new Promise((resolve5) => setTimeout(resolve5, ms));
305
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
298
306
  }
299
307
  function bufferToBase64Url(buffer, mimeType = "image/png") {
300
308
  return `data:${mimeType};base64,${buffer.toString("base64")}`;
@@ -450,7 +458,7 @@ var CaptureEngine = class {
450
458
  await page.evaluate(async (timeoutMs) => {
451
459
  await Promise.race([
452
460
  document.fonts.ready,
453
- new Promise((resolve5) => setTimeout(resolve5, timeoutMs))
461
+ new Promise((resolve3) => setTimeout(resolve3, timeoutMs))
454
462
  ]);
455
463
  }, timeout);
456
464
  } catch {
@@ -2548,289 +2556,6 @@ function getScripts() {
2548
2556
  `;
2549
2557
  }
2550
2558
 
2551
- // src/service/token-parser.ts
2552
- import { readFile as readFile2 } from "fs/promises";
2553
- import { relative } from "path";
2554
- import fastGlob from "fast-glob";
2555
- var TOKEN_DECLARATION_PATTERN = /--([a-zA-Z0-9_-]+)\s*:\s*([^;]+);/g;
2556
- var CATEGORY_PATTERNS = [
2557
- { pattern: /color|bg|background|border-color|fill|stroke/i, category: "color" },
2558
- { pattern: /spacing|margin|padding|gap|space|inset/i, category: "spacing" },
2559
- { pattern: /font|text|line-height|letter-spacing|typography/i, category: "typography" },
2560
- { pattern: /radius|rounded|corner/i, category: "radius" },
2561
- { pattern: /shadow|elevation/i, category: "shadow" },
2562
- { pattern: /size|width|height|min|max/i, category: "sizing" },
2563
- { pattern: /border(?!-color)|stroke-width|outline/i, category: "border" },
2564
- { pattern: /animation|transition|duration|timing|delay/i, category: "animation" },
2565
- { pattern: /z-index|layer|stack/i, category: "z-index" }
2566
- ];
2567
- async function parseTokenFile(filePath, themeSelectors = { ":root": "default" }, projectRoot) {
2568
- const startTime = performance.now();
2569
- const tokens = [];
2570
- const errors = [];
2571
- const warnings = [];
2572
- try {
2573
- const content = await readFile2(filePath, "utf-8");
2574
- const relativePath = projectRoot ? relative(projectRoot, filePath) : filePath;
2575
- const tokensByName = /* @__PURE__ */ new Map();
2576
- let lineNumber = 1;
2577
- const lines = content.split("\n");
2578
- let currentSelector = ":root";
2579
- let braceDepth = 0;
2580
- const selectorStack = [];
2581
- for (let i = 0; i < lines.length; i++) {
2582
- const line = lines[i];
2583
- lineNumber = i + 1;
2584
- const openBraces = (line.match(/\{/g) || []).length;
2585
- const closeBraces = (line.match(/\}/g) || []).length;
2586
- if (openBraces > closeBraces) {
2587
- const selectorMatch = line.match(/^\s*([^{]+)\s*\{/);
2588
- if (selectorMatch) {
2589
- selectorStack.push(selectorMatch[1].trim());
2590
- currentSelector = selectorStack[selectorStack.length - 1];
2591
- }
2592
- braceDepth += openBraces - closeBraces;
2593
- } else if (closeBraces > openBraces) {
2594
- braceDepth -= closeBraces - openBraces;
2595
- if (braceDepth >= 0 && selectorStack.length > 0) {
2596
- selectorStack.pop();
2597
- currentSelector = selectorStack.length > 0 ? selectorStack[selectorStack.length - 1] : ":root";
2598
- }
2599
- }
2600
- const tokenMatches = [...line.matchAll(TOKEN_DECLARATION_PATTERN)];
2601
- for (const match of tokenMatches) {
2602
- const [, name, rawValue] = match;
2603
- const fullName = `--${name}`;
2604
- tokensByName.set(fullName, { rawValue: rawValue.trim(), line: lineNumber });
2605
- }
2606
- }
2607
- for (const [name, { rawValue, line }] of tokensByName) {
2608
- const selector = findSelectorForLine(content, line || 1);
2609
- const theme = themeSelectors[selector] || "default";
2610
- const { resolvedValue, chain, hasCircular, unresolvedRef } = resolveValue(
2611
- rawValue,
2612
- tokensByName
2613
- );
2614
- if (hasCircular) {
2615
- warnings.push(
2616
- `Circular reference detected for ${name} at line ${line}`
2617
- );
2618
- }
2619
- if (unresolvedRef) {
2620
- warnings.push(
2621
- `Unresolved reference in ${name}: ${unresolvedRef}`
2622
- );
2623
- }
2624
- const category = inferCategory(name);
2625
- const level = inferLevel(name, rawValue, chain);
2626
- const description = extractDescription(content, line || 1);
2627
- tokens.push({
2628
- name,
2629
- rawValue,
2630
- resolvedValue,
2631
- category,
2632
- level,
2633
- referenceChain: chain,
2634
- sourceFile: relativePath,
2635
- lineNumber: line,
2636
- theme,
2637
- selector,
2638
- description
2639
- });
2640
- }
2641
- } catch (error) {
2642
- errors.push({
2643
- message: error instanceof Error ? error.message : "Unknown error",
2644
- file: filePath
2645
- });
2646
- }
2647
- return {
2648
- tokens,
2649
- errors,
2650
- warnings,
2651
- parseTimeMs: performance.now() - startTime
2652
- };
2653
- }
2654
- async function parseTokenFiles(config, projectRoot) {
2655
- const startTime = performance.now();
2656
- const allTokens = [];
2657
- const allErrors = [];
2658
- const allWarnings = [];
2659
- const files = await fastGlob(config.include, {
2660
- cwd: projectRoot,
2661
- ignore: config.exclude || ["**/node_modules/**"],
2662
- absolute: true
2663
- });
2664
- if (files.length === 0) {
2665
- allWarnings.push(
2666
- `No token files found matching: ${config.include.join(", ")}`
2667
- );
2668
- }
2669
- for (const file of files) {
2670
- const result = await parseTokenFile(
2671
- file,
2672
- config.themeSelectors,
2673
- projectRoot
2674
- );
2675
- allTokens.push(...result.tokens);
2676
- allErrors.push(...result.errors);
2677
- allWarnings.push(...result.warnings);
2678
- }
2679
- return {
2680
- tokens: allTokens,
2681
- errors: allErrors,
2682
- warnings: allWarnings,
2683
- parseTimeMs: performance.now() - startTime
2684
- };
2685
- }
2686
- function resolveValue(rawValue, tokensByName, visited = /* @__PURE__ */ new Set()) {
2687
- const chain = [];
2688
- let current = rawValue;
2689
- let hasCircular = false;
2690
- let unresolvedRef;
2691
- const maxIterations = 20;
2692
- let iterations = 0;
2693
- while (iterations < maxIterations) {
2694
- iterations++;
2695
- const varMatch = current.match(/var\(\s*--([a-zA-Z0-9_-]+)(?:\s*,\s*([^)]+))?\s*\)/);
2696
- if (!varMatch) {
2697
- break;
2698
- }
2699
- const [, refName, fallback] = varMatch;
2700
- const fullRefName = `--${refName}`;
2701
- if (visited.has(fullRefName)) {
2702
- hasCircular = true;
2703
- break;
2704
- }
2705
- visited.add(fullRefName);
2706
- chain.push(fullRefName);
2707
- const refToken = tokensByName.get(fullRefName);
2708
- if (refToken) {
2709
- current = current.replace(
2710
- varMatch[0],
2711
- refToken.rawValue
2712
- );
2713
- } else if (fallback) {
2714
- current = current.replace(varMatch[0], fallback.trim());
2715
- } else {
2716
- unresolvedRef = fullRefName;
2717
- break;
2718
- }
2719
- }
2720
- return {
2721
- resolvedValue: normalizeValue(current.trim()),
2722
- chain,
2723
- hasCircular,
2724
- unresolvedRef
2725
- };
2726
- }
2727
- function normalizeValue(value) {
2728
- value = value.replace(/#[0-9a-fA-F]+/g, (match) => match.toLowerCase());
2729
- value = value.replace(/\s+/g, " ").trim();
2730
- value = value.replace(
2731
- /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/g,
2732
- (_, r, g, b, a) => a !== void 0 ? `rgba(${r}, ${g}, ${b}, ${a})` : `rgb(${r}, ${g}, ${b})`
2733
- );
2734
- return value;
2735
- }
2736
- function inferCategory(name) {
2737
- const lowerName = name.toLowerCase();
2738
- for (const { pattern, category } of CATEGORY_PATTERNS) {
2739
- if (pattern.test(lowerName)) {
2740
- return category;
2741
- }
2742
- }
2743
- return "other";
2744
- }
2745
- function inferLevel(name, rawValue, referenceChain) {
2746
- const lowerName = name.toLowerCase();
2747
- if (/btn|button|input|card|modal|dialog|menu|nav|header|footer|table|form/i.test(
2748
- lowerName
2749
- )) {
2750
- return 3;
2751
- }
2752
- if (referenceChain.length > 0) {
2753
- return 2;
2754
- }
2755
- if (rawValue.match(/^#[0-9a-fA-F]+$/) || rawValue.match(/^\d+(\.\d+)?(px|rem|em|%|vh|vw)?$/)) {
2756
- return 1;
2757
- }
2758
- return 2;
2759
- }
2760
- function findSelectorForLine(content, targetLine) {
2761
- const lines = content.split("\n");
2762
- let currentSelector = ":root";
2763
- let braceDepth = 0;
2764
- for (let i = 0; i < Math.min(targetLine, lines.length); i++) {
2765
- const line = lines[i];
2766
- const selectorMatch = line.match(/^\s*([^{]+)\s*\{/);
2767
- if (selectorMatch) {
2768
- const selector = selectorMatch[1].trim();
2769
- if ((line.match(/\{/g) || []).length > (line.match(/\}/g) || []).length) {
2770
- currentSelector = selector;
2771
- }
2772
- }
2773
- braceDepth += (line.match(/\{/g) || []).length;
2774
- braceDepth -= (line.match(/\}/g) || []).length;
2775
- if (braceDepth === 0) {
2776
- currentSelector = ":root";
2777
- }
2778
- }
2779
- return currentSelector;
2780
- }
2781
- function extractDescription(content, line) {
2782
- const lines = content.split("\n");
2783
- if (line <= 1) return void 0;
2784
- const prevLine = lines[line - 2]?.trim();
2785
- const singleLineMatch = prevLine?.match(/\/\/\s*(.+)$/);
2786
- if (singleLineMatch) {
2787
- return singleLineMatch[1].trim();
2788
- }
2789
- const multiLineMatch = prevLine?.match(/\*\s*(.+)\s*\*\//);
2790
- if (multiLineMatch) {
2791
- return multiLineMatch[1].trim();
2792
- }
2793
- const inlineMatch = prevLine?.match(/\/\*\s*(.+)\s*\*\//);
2794
- if (inlineMatch) {
2795
- return inlineMatch[1].trim();
2796
- }
2797
- return void 0;
2798
- }
2799
- function hexToRgb(hex) {
2800
- const match = hex.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
2801
- if (!match) return null;
2802
- return {
2803
- r: parseInt(match[1], 16),
2804
- g: parseInt(match[2], 16),
2805
- b: parseInt(match[3], 16)
2806
- };
2807
- }
2808
- function rgbToHex(r, g, b) {
2809
- return `#${[r, g, b].map((x) => Math.round(x).toString(16).padStart(2, "0")).join("")}`;
2810
- }
2811
- function parseRgb(color) {
2812
- const match = color.match(
2813
- /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/
2814
- );
2815
- if (!match) return null;
2816
- return {
2817
- r: parseInt(match[1], 10),
2818
- g: parseInt(match[2], 10),
2819
- b: parseInt(match[3], 10),
2820
- a: match[4] ? parseFloat(match[4]) : void 0
2821
- };
2822
- }
2823
- function normalizeColor(color) {
2824
- if (color.startsWith("#")) {
2825
- return color.toLowerCase();
2826
- }
2827
- const rgb = parseRgb(color);
2828
- if (rgb) {
2829
- return rgbToHex(rgb.r, rgb.g, rgb.b);
2830
- }
2831
- return color.toLowerCase();
2832
- }
2833
-
2834
2559
  // src/service/token-registry.ts
2835
2560
  var TokenRegistryManager = class {
2836
2561
  registry = null;
@@ -3116,7 +2841,7 @@ var TokenRegistryManager = class {
3116
2841
  }
3117
2842
  if (theme) {
3118
2843
  candidates = candidates.filter(
3119
- (t5) => t5.theme === theme || t5.theme === "default"
2844
+ (t4) => t4.theme === theme || t4.theme === "default"
3120
2845
  );
3121
2846
  }
3122
2847
  if (isColor) {
@@ -3633,28 +3358,11 @@ import { parse } from "@babel/parser";
3633
3358
  import traverse from "@babel/traverse";
3634
3359
  import generate from "@babel/generator";
3635
3360
  import * as t from "@babel/types";
3636
- var PARSER_OPTIONS = {
3637
- sourceType: "module",
3638
- plugins: [
3639
- "jsx",
3640
- "typescript",
3641
- ["decorators", { decoratorsBeforeExport: true }],
3642
- "classProperties",
3643
- "classPrivateProperties",
3644
- "classPrivateMethods",
3645
- "exportDefaultFrom",
3646
- "exportNamespaceFrom",
3647
- "dynamicImport",
3648
- "nullishCoalescingOperator",
3649
- "optionalChaining",
3650
- "objectRestSpread"
3651
- ]
3652
- };
3653
3361
  function extractStyleLocations(sourceCode, filePath) {
3654
3362
  const locations = [];
3655
3363
  let ast;
3656
3364
  try {
3657
- ast = parse(sourceCode, PARSER_OPTIONS);
3365
+ ast = parse(sourceCode, BABEL_PARSER_OPTIONS);
3658
3366
  } catch (error) {
3659
3367
  console.error(`Failed to parse ${filePath}:`, error);
3660
3368
  return locations;
@@ -3760,7 +3468,7 @@ function extractFromTemplateLiteral(template, path, filePath, type, locations) {
3760
3468
  function applyPatch(sourceCode, styleLocation, oldValue, newValue) {
3761
3469
  let ast;
3762
3470
  try {
3763
- ast = parse(sourceCode, PARSER_OPTIONS);
3471
+ ast = parse(sourceCode, BABEL_PARSER_OPTIONS);
3764
3472
  } catch (error) {
3765
3473
  return {
3766
3474
  success: false,
@@ -3868,7 +3576,7 @@ function applyPatches(sourceCode, patches) {
3868
3576
  }
3869
3577
 
3870
3578
  // src/service/metrics-store.ts
3871
- import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
3579
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
3872
3580
  import { join as join2 } from "path";
3873
3581
  var MetricsStore = class {
3874
3582
  projectRoot;
@@ -3888,7 +3596,7 @@ var MetricsStore = class {
3888
3596
  const filepath = join2(this.metricsDir, filename);
3889
3597
  let snapshots = [];
3890
3598
  try {
3891
- const existing = await readFile3(filepath, "utf-8");
3599
+ const existing = await readFile2(filepath, "utf-8");
3892
3600
  snapshots = JSON.parse(existing);
3893
3601
  } catch {
3894
3602
  }
@@ -3915,7 +3623,7 @@ var MetricsStore = class {
3915
3623
  continue;
3916
3624
  }
3917
3625
  try {
3918
- const content = await readFile3(join2(this.metricsDir, file), "utf-8");
3626
+ const content = await readFile2(join2(this.metricsDir, file), "utf-8");
3919
3627
  const fileSnapshots = JSON.parse(content);
3920
3628
  const matching = component === "all" ? fileSnapshots : fileSnapshots.filter((s) => s.component === component);
3921
3629
  snapshots.push(...matching);
@@ -4042,907 +3750,22 @@ function createMetricsStore(projectRoot) {
4042
3750
  return new MetricsStore(projectRoot);
4043
3751
  }
4044
3752
 
4045
- // src/service/enhance/scanner.ts
3753
+ // src/service/enhance/doc-extractor.ts
4046
3754
  import { parse as parse2 } from "@babel/parser";
4047
3755
  import _traverse from "@babel/traverse";
4048
3756
  import * as t2 from "@babel/types";
4049
- import { readFile as readFile4 } from "fs/promises";
4050
- var traverse2 = _traverse.default || _traverse;
4051
- var PARSER_OPTIONS2 = {
4052
- sourceType: "module",
4053
- plugins: [
4054
- "jsx",
4055
- "typescript",
4056
- ["decorators", { decoratorsBeforeExport: true }],
4057
- "classProperties",
4058
- "classPrivateProperties",
4059
- "classPrivateMethods",
4060
- "exportDefaultFrom",
4061
- "exportNamespaceFrom",
4062
- "dynamicImport",
4063
- "nullishCoalescingOperator",
4064
- "optionalChaining",
4065
- "objectRestSpread"
4066
- ]
4067
- };
4068
- async function scanFileForImports(filePath) {
4069
- const imports = [];
4070
- try {
4071
- const sourceCode = await readFile4(filePath, "utf-8");
4072
- const ast = parse2(sourceCode, PARSER_OPTIONS2);
4073
- traverse2(ast, {
4074
- ImportDeclaration(path) {
4075
- const source = path.node.source.value;
4076
- const line = path.node.loc?.start.line ?? 0;
4077
- for (const specifier of path.node.specifiers) {
4078
- if (t2.isImportSpecifier(specifier)) {
4079
- const importedName = t2.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value;
4080
- const localName = specifier.local.name;
4081
- if (isPascalCase(importedName)) {
4082
- imports.push({
4083
- componentName: importedName,
4084
- localName,
4085
- source,
4086
- isDefault: false,
4087
- filePath,
4088
- line
4089
- });
4090
- }
4091
- } else if (t2.isImportDefaultSpecifier(specifier)) {
4092
- const localName = specifier.local.name;
4093
- if (isPascalCase(localName)) {
4094
- imports.push({
4095
- componentName: localName,
4096
- localName,
4097
- source,
4098
- isDefault: true,
4099
- filePath,
4100
- line
4101
- });
4102
- }
4103
- }
4104
- }
4105
- }
4106
- });
4107
- } catch (error) {
4108
- console.warn(`Failed to parse ${filePath}:`, error.message);
4109
- return [];
4110
- }
4111
- return imports;
4112
- }
4113
- async function scanFileForUsages(filePath, componentNames) {
4114
- const usages = [];
4115
- try {
4116
- const sourceCode = await readFile4(filePath, "utf-8");
4117
- const lines = sourceCode.split("\n");
4118
- const ast = parse2(sourceCode, PARSER_OPTIONS2);
4119
- traverse2(ast, {
4120
- JSXOpeningElement(path) {
4121
- const elementName = getJSXElementName(path.node.name);
4122
- if (!elementName) return;
4123
- const componentName = componentNames.get(elementName);
4124
- if (!componentName) return;
4125
- const loc = path.node.loc;
4126
- if (!loc) return;
4127
- const props = extractProps(path.node.attributes);
4128
- const contextLines = getContextLines(lines, loc.start.line - 1, 3);
4129
- const isConditional = checkIfConditional(path);
4130
- const parentElement = getParentElementName(path);
4131
- usages.push({
4132
- componentName,
4133
- filePath,
4134
- line: loc.start.line,
4135
- column: loc.start.column,
4136
- props,
4137
- context: contextLines,
4138
- parentElement,
4139
- hasSpreadProps: props.spreads.length > 0,
4140
- isConditional
4141
- });
4142
- }
4143
- });
4144
- } catch (error) {
4145
- console.warn(`Failed to parse ${filePath}:`, error.message);
4146
- return [];
4147
- }
4148
- return usages;
4149
- }
4150
- async function scanFile(filePath, trackedComponents) {
4151
- const imports = [];
4152
- const usages = [];
4153
- try {
4154
- const sourceCode = await readFile4(filePath, "utf-8");
4155
- const lines = sourceCode.split("\n");
4156
- const ast = parse2(sourceCode, PARSER_OPTIONS2);
4157
- const localToComponent = /* @__PURE__ */ new Map();
4158
- traverse2(ast, {
4159
- ImportDeclaration(path) {
4160
- const source = path.node.source.value;
4161
- const line = path.node.loc?.start.line ?? 0;
4162
- for (const specifier of path.node.specifiers) {
4163
- if (t2.isImportSpecifier(specifier)) {
4164
- const importedName = t2.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value;
4165
- const localName = specifier.local.name;
4166
- if (isPascalCase(importedName)) {
4167
- if (!trackedComponents || trackedComponents.has(importedName)) {
4168
- imports.push({
4169
- componentName: importedName,
4170
- localName,
4171
- source,
4172
- isDefault: false,
4173
- filePath,
4174
- line
4175
- });
4176
- localToComponent.set(localName, importedName);
4177
- }
4178
- }
4179
- } else if (t2.isImportDefaultSpecifier(specifier)) {
4180
- const localName = specifier.local.name;
4181
- if (isPascalCase(localName)) {
4182
- if (!trackedComponents || trackedComponents.has(localName)) {
4183
- imports.push({
4184
- componentName: localName,
4185
- localName,
4186
- source,
4187
- isDefault: true,
4188
- filePath,
4189
- line
4190
- });
4191
- localToComponent.set(localName, localName);
4192
- }
4193
- }
4194
- }
4195
- }
4196
- },
4197
- JSXOpeningElement(path) {
4198
- const elementName = getJSXElementName(path.node.name);
4199
- if (!elementName) return;
4200
- const componentName = localToComponent.get(elementName);
4201
- if (!componentName) return;
4202
- const loc = path.node.loc;
4203
- if (!loc) return;
4204
- const props = extractProps(path.node.attributes);
4205
- const contextLines = getContextLines(lines, loc.start.line - 1, 3);
4206
- const isConditional = checkIfConditional(path);
4207
- const parentElement = getParentElementName(path);
4208
- usages.push({
4209
- componentName,
4210
- filePath,
4211
- line: loc.start.line,
4212
- column: loc.start.column,
4213
- props,
4214
- context: contextLines,
4215
- parentElement,
4216
- hasSpreadProps: props.spreads.length > 0,
4217
- isConditional
4218
- });
4219
- }
4220
- });
4221
- } catch (error) {
4222
- console.warn(`Failed to parse ${filePath}:`, error.message);
4223
- return { imports: [], usages: [] };
4224
- }
4225
- return { imports, usages };
4226
- }
4227
- function isPascalCase(str) {
4228
- return /^[A-Z][a-zA-Z0-9]*$/.test(str);
4229
- }
4230
- function getJSXElementName(name) {
4231
- if (t2.isJSXIdentifier(name)) {
4232
- return name.name;
4233
- }
4234
- if (t2.isJSXMemberExpression(name)) {
4235
- const parts = [];
4236
- let current = name;
4237
- while (t2.isJSXMemberExpression(current)) {
4238
- parts.unshift(current.property.name);
4239
- current = current.object;
4240
- }
4241
- if (t2.isJSXIdentifier(current)) {
4242
- parts.unshift(current.name);
4243
- }
4244
- return parts.join(".");
4245
- }
4246
- return null;
4247
- }
4248
- function extractProps(attributes) {
4249
- const result = {
4250
- static: {},
4251
- dynamic: [],
4252
- spreads: []
4253
- };
4254
- for (const attr of attributes) {
4255
- if (t2.isJSXSpreadAttribute(attr)) {
4256
- if (t2.isIdentifier(attr.argument)) {
4257
- result.spreads.push(attr.argument.name);
4258
- } else {
4259
- result.spreads.push("(expression)");
4260
- }
4261
- } else if (t2.isJSXAttribute(attr)) {
4262
- const propName = t2.isJSXIdentifier(attr.name) ? attr.name.name : `${attr.name.namespace.name}:${attr.name.name.name}`;
4263
- const value = attr.value;
4264
- if (value === null) {
4265
- result.static[propName] = true;
4266
- } else if (t2.isStringLiteral(value)) {
4267
- result.static[propName] = value.value;
4268
- } else if (t2.isJSXExpressionContainer(value)) {
4269
- const expr = value.expression;
4270
- if (t2.isStringLiteral(expr)) {
4271
- result.static[propName] = expr.value;
4272
- } else if (t2.isNumericLiteral(expr)) {
4273
- result.static[propName] = expr.value;
4274
- } else if (t2.isBooleanLiteral(expr)) {
4275
- result.static[propName] = expr.value;
4276
- } else if (t2.isTemplateLiteral(expr) && expr.expressions.length === 0) {
4277
- result.static[propName] = expr.quasis.map((q) => q.value.raw).join("");
4278
- } else {
4279
- result.dynamic.push(propName);
4280
- }
4281
- }
4282
- }
4283
- }
4284
- return result;
4285
- }
4286
- function getContextLines(lines, centerLine, radius) {
4287
- const start = Math.max(0, centerLine - radius);
4288
- const end = Math.min(lines.length, centerLine + radius + 1);
4289
- return lines.slice(start, end).join("\n");
4290
- }
4291
- function checkIfConditional(path) {
4292
- let current = path.parentPath;
4293
- while (current) {
4294
- if (current.isLogicalExpression() && current.node.operator === "&&") {
4295
- return true;
4296
- }
4297
- if (current.isConditionalExpression()) {
4298
- return true;
4299
- }
4300
- if (current.isJSXExpressionContainer() && current.parentPath?.isJSXElement()) {
4301
- const expr = current.node.expression;
4302
- if (t2.isLogicalExpression(expr) || t2.isConditionalExpression(expr)) {
4303
- return true;
4304
- }
4305
- }
4306
- current = current.parentPath;
4307
- }
4308
- return false;
4309
- }
4310
- function getParentElementName(path) {
4311
- let current = path.parentPath;
4312
- const currentElementName = getJSXElementName(path.node.name);
4313
- while (current) {
4314
- if (current.isJSXElement()) {
4315
- const opening = current.node.openingElement;
4316
- const name = getJSXElementName(opening.name);
4317
- if (name && name !== currentElementName) {
4318
- return name;
4319
- }
4320
- }
4321
- current = current.parentPath;
4322
- }
4323
- return void 0;
4324
- }
4325
-
4326
- // src/service/enhance/aggregator.ts
4327
- function aggregateComponentUsages(componentName, sourceFile, usages, imports) {
4328
- const uniqueFiles = new Set(usages.map((u) => u.filePath));
4329
- const patternMap = /* @__PURE__ */ new Map();
4330
- for (const usage of usages) {
4331
- const propKey = createPropKey(usage.props.static);
4332
- const existing = patternMap.get(propKey);
4333
- if (existing) {
4334
- existing.count++;
4335
- if (!existing.files.includes(usage.filePath)) {
4336
- existing.files.push(usage.filePath);
4337
- }
4338
- if (existing.sampleContexts.length < 3) {
4339
- existing.sampleContexts.push(usage.context);
4340
- }
4341
- } else {
4342
- patternMap.set(propKey, {
4343
- props: { ...usage.props.static },
4344
- count: 1,
4345
- files: [usage.filePath],
4346
- sampleContexts: [usage.context]
4347
- });
4348
- }
4349
- }
4350
- const patterns = Array.from(patternMap.values()).sort(
4351
- (a, b) => b.count - a.count
4352
- );
4353
- const contextMap = /* @__PURE__ */ new Map();
4354
- for (const usage of usages) {
4355
- const context = classifyFileContext(usage.filePath, usage.context);
4356
- const existing = contextMap.get(context);
4357
- if (existing) {
4358
- existing.count++;
4359
- if (!existing.files.includes(usage.filePath)) {
4360
- existing.files.push(usage.filePath);
4361
- }
4362
- } else {
4363
- contextMap.set(context, { count: 1, files: [usage.filePath] });
4364
- }
4365
- }
4366
- const contexts = Array.from(contextMap.entries()).map(([type, data]) => ({ type, ...data })).sort((a, b) => b.count - a.count);
4367
- return {
4368
- name: componentName,
4369
- sourceFile,
4370
- totalUsages: usages.length,
4371
- uniqueFiles: uniqueFiles.size,
4372
- patterns,
4373
- contexts,
4374
- usages,
4375
- imports
4376
- };
4377
- }
4378
- function aggregateAllUsages(usages, imports, componentSources) {
4379
- const usagesByComponent = /* @__PURE__ */ new Map();
4380
- for (const usage of usages) {
4381
- const existing = usagesByComponent.get(usage.componentName) ?? [];
4382
- existing.push(usage);
4383
- usagesByComponent.set(usage.componentName, existing);
4384
- }
4385
- const importsByComponent = /* @__PURE__ */ new Map();
4386
- for (const imp of imports) {
4387
- const existing = importsByComponent.get(imp.componentName) ?? [];
4388
- existing.push(imp);
4389
- importsByComponent.set(imp.componentName, existing);
4390
- }
4391
- const components = {};
4392
- const allComponentNames = /* @__PURE__ */ new Set([
4393
- ...usagesByComponent.keys(),
4394
- ...importsByComponent.keys()
4395
- ]);
4396
- for (const componentName of allComponentNames) {
4397
- const componentUsages = usagesByComponent.get(componentName) ?? [];
4398
- const componentImports = importsByComponent.get(componentName) ?? [];
4399
- const sourceFile = componentSources.get(componentName) ?? "unknown";
4400
- components[componentName] = aggregateComponentUsages(
4401
- componentName,
4402
- sourceFile,
4403
- componentUsages,
4404
- componentImports
4405
- );
4406
- }
4407
- const allFiles = /* @__PURE__ */ new Set();
4408
- for (const usage of usages) {
4409
- allFiles.add(usage.filePath);
4410
- }
4411
- for (const imp of imports) {
4412
- allFiles.add(imp.filePath);
4413
- }
4414
- return {
4415
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4416
- rootDir: "",
4417
- // Will be set by caller
4418
- totalFiles: allFiles.size,
4419
- totalComponents: Object.keys(components).length,
4420
- components,
4421
- errorFiles: []
4422
- // Will be populated by scanner
4423
- };
4424
- }
4425
- function createPropKey(props) {
4426
- const entries = Object.entries(props).sort(([a], [b]) => a.localeCompare(b));
4427
- return entries.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join("|");
4428
- }
4429
- function classifyFileContext(filePath, context) {
4430
- const lowerPath = filePath.toLowerCase();
4431
- const lowerContext = context.toLowerCase();
4432
- if (lowerPath.includes("/modal") || lowerPath.includes("modal.") || lowerContext.includes("<modal")) {
4433
- return "modal";
4434
- }
4435
- if (lowerPath.includes("/dialog") || lowerPath.includes("dialog.") || lowerContext.includes("<dialog")) {
4436
- return "dialog";
4437
- }
4438
- if (lowerPath.includes("/form") || lowerPath.includes("form.") || lowerContext.includes("<form") || lowerContext.includes("onsubmit")) {
4439
- return "form";
4440
- }
4441
- if (lowerPath.includes("/page") || lowerPath.includes("pages/") || lowerPath.includes("/routes/")) {
4442
- return "page";
4443
- }
4444
- if (lowerPath.includes("/layout") || lowerPath.includes("layout.") || lowerPath.includes("/layouts/")) {
4445
- return "layout";
4446
- }
4447
- if (lowerPath.includes("/card") || lowerPath.includes("card.") || lowerContext.includes("<card")) {
4448
- return "card";
4449
- }
4450
- if (lowerPath.includes("/table") || lowerPath.includes("table.") || lowerContext.includes("<table") || lowerContext.includes("<tr")) {
4451
- return "table";
4452
- }
4453
- if (lowerPath.includes("/list") || lowerPath.includes("list.") || lowerContext.includes("<ul") || lowerContext.includes("<ol") || lowerContext.includes("<li")) {
4454
- return "list";
4455
- }
4456
- if (lowerPath.includes("/nav") || lowerPath.includes("navigation") || lowerContext.includes("<nav")) {
4457
- return "navigation";
4458
- }
4459
- if (lowerPath.includes("/header") || lowerPath.includes("header.") || lowerContext.includes("<header")) {
4460
- return "header";
4461
- }
4462
- if (lowerPath.includes("/footer") || lowerPath.includes("footer.") || lowerContext.includes("<footer")) {
4463
- return "footer";
4464
- }
4465
- if (lowerPath.includes("/sidebar") || lowerPath.includes("sidebar.") || lowerContext.includes("<aside")) {
4466
- return "sidebar";
4467
- }
4468
- return "unknown";
4469
- }
4470
- function findCommonPropCombinations(usages, minOccurrences = 3) {
4471
- const combinations = /* @__PURE__ */ new Map();
4472
- for (const usage of usages) {
4473
- const allProps = [
4474
- ...Object.keys(usage.props.static),
4475
- ...usage.props.dynamic
4476
- ].sort();
4477
- for (let size = 2; size <= Math.min(allProps.length, 4); size++) {
4478
- for (const combo of combinations_k(allProps, size)) {
4479
- const key = combo.join(",");
4480
- combinations.set(key, (combinations.get(key) ?? 0) + 1);
4481
- }
4482
- }
4483
- }
4484
- return Array.from(combinations.entries()).filter(([, count]) => count >= minOccurrences).map(([key, count]) => ({ props: key.split(","), count })).sort((a, b) => b.count - a.count);
4485
- }
4486
- function* combinations_k(arr, k) {
4487
- if (k === 0) {
4488
- yield [];
4489
- return;
4490
- }
4491
- if (arr.length < k) return;
4492
- for (let i = 0; i <= arr.length - k; i++) {
4493
- for (const combo of combinations_k(arr.slice(i + 1), k - 1)) {
4494
- yield [arr[i], ...combo];
4495
- }
4496
- }
4497
- }
4498
- function inferRelations(componentName, analysis, allAnalyses) {
4499
- const relations = [];
4500
- const parentCounts = /* @__PURE__ */ new Map();
4501
- const siblingCounts = /* @__PURE__ */ new Map();
4502
- for (const usage of analysis.usages) {
4503
- if (usage.parentElement && usage.parentElement !== "div" && usage.parentElement !== "span") {
4504
- const parent = usage.parentElement;
4505
- const existing = parentCounts.get(parent);
4506
- if (existing) {
4507
- existing.count++;
4508
- if (!existing.files.includes(usage.filePath)) {
4509
- existing.files.push(usage.filePath);
4510
- }
4511
- } else {
4512
- parentCounts.set(parent, { count: 1, files: [usage.filePath] });
4513
- }
4514
- }
4515
- }
4516
- const filesWithThisComponent = new Set(analysis.usages.map((u) => u.filePath));
4517
- for (const [otherName, otherAnalysis] of Object.entries(allAnalyses)) {
4518
- if (otherName === componentName) continue;
4519
- let sharedFiles = 0;
4520
- const sharedFileList = [];
4521
- for (const usage of otherAnalysis.usages) {
4522
- if (filesWithThisComponent.has(usage.filePath)) {
4523
- if (!sharedFileList.includes(usage.filePath)) {
4524
- sharedFiles++;
4525
- sharedFileList.push(usage.filePath);
4526
- }
4527
- }
4528
- }
4529
- if (sharedFiles >= 3) {
4530
- siblingCounts.set(otherName, {
4531
- count: sharedFiles,
4532
- files: sharedFileList.slice(0, 5)
4533
- });
4534
- }
4535
- }
4536
- for (const [parent, data] of parentCounts) {
4537
- if (data.count >= 2) {
4538
- relations.push({
4539
- component: parent,
4540
- relationship: "parent",
4541
- frequency: data.count,
4542
- sampleFiles: data.files.slice(0, 3)
4543
- });
4544
- }
4545
- }
4546
- for (const [sibling, data] of siblingCounts) {
4547
- relations.push({
4548
- component: sibling,
4549
- relationship: "sibling",
4550
- frequency: data.count,
4551
- sampleFiles: data.files.slice(0, 3)
4552
- });
4553
- }
4554
- relations.sort((a, b) => b.frequency - a.frequency);
4555
- return relations;
4556
- }
4557
- function inferAllRelations(analysis) {
4558
- const allRelations = /* @__PURE__ */ new Map();
4559
- for (const [componentName, componentAnalysis] of Object.entries(analysis.components)) {
4560
- const relations = inferRelations(componentName, componentAnalysis, analysis.components);
4561
- if (relations.length > 0) {
4562
- allRelations.set(componentName, relations);
4563
- }
4564
- }
4565
- return allRelations;
4566
- }
4567
- function summarizePatternsForPrompt(analysis, maxPatterns = 10, maxContexts = 5) {
4568
- const lines = [];
4569
- lines.push(`## ${analysis.name}`);
4570
- lines.push(`Total usages: ${analysis.totalUsages} across ${analysis.uniqueFiles} files`);
4571
- lines.push("");
4572
- lines.push("### Usage Patterns (by frequency)");
4573
- const topPatterns = analysis.patterns.slice(0, maxPatterns);
4574
- for (const pattern of topPatterns) {
4575
- const propsStr = Object.entries(pattern.props).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(", ");
4576
- lines.push(`- ${propsStr || "(no props)"}: ${pattern.count} usages in ${pattern.files.length} files`);
4577
- }
4578
- lines.push("");
4579
- lines.push("### File Contexts");
4580
- const topContexts = analysis.contexts.slice(0, maxContexts);
4581
- for (const ctx of topContexts) {
4582
- lines.push(`- ${ctx.type}: ${ctx.count} usages`);
4583
- }
4584
- lines.push("");
4585
- lines.push("### Sample Usages");
4586
- for (const pattern of topPatterns.slice(0, 3)) {
4587
- if (pattern.sampleContexts[0]) {
4588
- lines.push("```tsx");
4589
- lines.push(pattern.sampleContexts[0].trim());
4590
- lines.push("```");
4591
- lines.push("");
4592
- }
4593
- }
4594
- return lines.join("\n");
4595
- }
4596
-
4597
- // src/service/enhance/cache.ts
4598
- import { readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
3757
+ import { readFile as readFile3 } from "fs/promises";
4599
3758
  import { existsSync as existsSync2 } from "fs";
4600
- import { createHash as createHash2 } from "crypto";
4601
- import { join as join3, dirname as dirname3 } from "path";
4602
- import { mkdir as mkdir3 } from "fs/promises";
4603
- var CURRENT_CACHE_VERSION = 1;
4604
- var CACHE_FILENAME = "analysis-cache.json";
4605
- function getCachePath(rootDir) {
4606
- return join3(rootDir, ".fragments", CACHE_FILENAME);
4607
- }
4608
- async function loadCache(rootDir) {
4609
- const cachePath = getCachePath(rootDir);
4610
- if (!existsSync2(cachePath)) {
4611
- return null;
4612
- }
4613
- try {
4614
- const content = await readFile5(cachePath, "utf-8");
4615
- const cache = JSON.parse(content);
4616
- if (cache.version !== CURRENT_CACHE_VERSION) {
4617
- console.warn(
4618
- `Cache version mismatch: expected ${CURRENT_CACHE_VERSION}, got ${cache.version}. Invalidating cache.`
4619
- );
4620
- return null;
4621
- }
4622
- if (cache.rootDir !== rootDir) {
4623
- console.warn(`Cache root mismatch. Invalidating cache.`);
4624
- return null;
4625
- }
4626
- return cache;
4627
- } catch (error) {
4628
- console.warn(`Failed to load cache: ${error.message}`);
4629
- return null;
4630
- }
4631
- }
4632
- async function saveCache(rootDir, cache) {
4633
- const cachePath = getCachePath(rootDir);
4634
- const cacheDir = dirname3(cachePath);
4635
- if (!existsSync2(cacheDir)) {
4636
- await mkdir3(cacheDir, { recursive: true });
4637
- }
4638
- cache.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
4639
- await writeFile3(cachePath, JSON.stringify(cache, null, 2));
4640
- }
4641
- function createEmptyCache(rootDir) {
4642
- const now = (/* @__PURE__ */ new Date()).toISOString();
4643
- return {
4644
- version: CURRENT_CACHE_VERSION,
4645
- createdAt: now,
4646
- updatedAt: now,
4647
- rootDir,
4648
- files: {}
4649
- };
4650
- }
4651
- function computeFileHash(content) {
4652
- return createHash2("md5").update(content).digest("hex");
4653
- }
4654
- function getCachedFile(cache, filePath) {
4655
- return cache.files[filePath] ?? null;
4656
- }
4657
- function updateCacheFile(cache, filePath, hash, imports, usages) {
4658
- cache.files[filePath] = {
4659
- hash,
4660
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4661
- imports,
4662
- usages
4663
- };
4664
- }
4665
- function removeCacheFile(cache, filePath) {
4666
- delete cache.files[filePath];
4667
- }
4668
- async function detectFileChanges(cache, currentFiles, getFileHash) {
4669
- const changes = {
4670
- added: [],
4671
- modified: [],
4672
- deleted: [],
4673
- unchanged: []
4674
- };
4675
- const currentFileSet = new Set(currentFiles);
4676
- const cachedFileSet = new Set(Object.keys(cache.files));
4677
- for (const filePath of currentFiles) {
4678
- const entry = cache.files[filePath];
4679
- if (!entry) {
4680
- changes.added.push(filePath);
4681
- } else {
4682
- const currentHash = await getFileHash(filePath);
4683
- if (currentHash !== entry.hash) {
4684
- changes.modified.push(filePath);
4685
- } else {
4686
- changes.unchanged.push(filePath);
4687
- }
4688
- }
4689
- }
4690
- for (const cachedFile of cachedFileSet) {
4691
- if (!currentFileSet.has(cachedFile)) {
4692
- changes.deleted.push(cachedFile);
4693
- }
4694
- }
4695
- return changes;
4696
- }
4697
- function getCacheStats(cache) {
4698
- let totalImports = 0;
4699
- let totalUsages = 0;
4700
- for (const entry of Object.values(cache.files)) {
4701
- totalImports += entry.imports.length;
4702
- totalUsages += entry.usages.length;
4703
- }
4704
- const ageMs = Date.now() - new Date(cache.updatedAt).getTime();
4705
- const ageMinutes = Math.round(ageMs / 6e4);
4706
- const cacheAge = ageMinutes < 60 ? `${ageMinutes} minutes ago` : ageMinutes < 1440 ? `${Math.round(ageMinutes / 60)} hours ago` : `${Math.round(ageMinutes / 1440)} days ago`;
4707
- return {
4708
- totalFiles: Object.keys(cache.files).length,
4709
- totalImports,
4710
- totalUsages,
4711
- cacheAge
4712
- };
4713
- }
4714
-
4715
- // src/service/enhance/codebase-scanner.ts
4716
- import fg from "fast-glob";
4717
- import { readFile as readFile6 } from "fs/promises";
4718
- import { relative as relative2, resolve as resolve3, dirname as dirname4 } from "path";
4719
- var DEFAULT_INCLUDE = [
4720
- "**/*.tsx",
4721
- "**/*.ts",
4722
- "**/*.jsx",
4723
- "**/*.js"
4724
- ];
4725
- var DEFAULT_EXCLUDE = [
4726
- "**/node_modules/**",
4727
- "**/dist/**",
4728
- "**/build/**",
4729
- "**/.next/**",
4730
- "**/coverage/**",
4731
- "**/__tests__/**",
4732
- "**/*.test.*",
4733
- "**/*.spec.*",
4734
- "**/*.stories.*",
4735
- "**/*.fragment.*",
4736
- "**/storybook-static/**"
4737
- ];
4738
- async function scanCodebase(options) {
4739
- const {
4740
- rootDir,
4741
- include = DEFAULT_INCLUDE,
4742
- exclude = DEFAULT_EXCLUDE,
4743
- componentNames,
4744
- useCache = true,
4745
- onProgress
4746
- } = options;
4747
- const absoluteRoot = resolve3(rootDir);
4748
- let cache = null;
4749
- if (useCache) {
4750
- cache = await loadCache(absoluteRoot);
4751
- }
4752
- if (!cache) {
4753
- cache = createEmptyCache(absoluteRoot);
4754
- }
4755
- onProgress?.({
4756
- current: 0,
4757
- total: 0,
4758
- currentFile: "",
4759
- phase: "discovering"
4760
- });
4761
- const files = await fg(include, {
4762
- cwd: absoluteRoot,
4763
- ignore: exclude,
4764
- absolute: true,
4765
- onlyFiles: true
4766
- });
4767
- const totalFiles = files.length;
4768
- const trackedComponents = componentNames ? new Set(componentNames) : void 0;
4769
- const allImports = [];
4770
- const allUsages = [];
4771
- const errorFiles = [];
4772
- const componentSources = /* @__PURE__ */ new Map();
4773
- for (let i = 0; i < files.length; i++) {
4774
- const filePath = files[i];
4775
- const relativePath = relative2(absoluteRoot, filePath);
4776
- onProgress?.({
4777
- current: i + 1,
4778
- total: totalFiles,
4779
- currentFile: relativePath,
4780
- phase: "scanning"
4781
- });
4782
- try {
4783
- const content = await readFile6(filePath, "utf-8");
4784
- const fileHash = computeFileHash(content);
4785
- const cachedEntry = getCachedFile(cache, filePath);
4786
- if (cachedEntry && cachedEntry.hash === fileHash) {
4787
- allImports.push(...cachedEntry.imports);
4788
- allUsages.push(...cachedEntry.usages);
4789
- for (const imp of cachedEntry.imports) {
4790
- if (!componentSources.has(imp.componentName)) {
4791
- const sourceFile = resolveImportSource(filePath, imp.source);
4792
- if (sourceFile) {
4793
- componentSources.set(imp.componentName, sourceFile);
4794
- }
4795
- }
4796
- }
4797
- continue;
4798
- }
4799
- const { imports, usages } = await scanFile(filePath, trackedComponents);
4800
- updateCacheFile(cache, filePath, fileHash, imports, usages);
4801
- allImports.push(...imports);
4802
- allUsages.push(...usages);
4803
- for (const imp of imports) {
4804
- if (!componentSources.has(imp.componentName)) {
4805
- const sourceFile = resolveImportSource(filePath, imp.source);
4806
- if (sourceFile) {
4807
- componentSources.set(imp.componentName, sourceFile);
4808
- }
4809
- }
4810
- }
4811
- } catch (error) {
4812
- errorFiles.push(relativePath);
4813
- console.warn(`Error scanning ${relativePath}:`, error.message);
4814
- }
4815
- }
4816
- if (useCache) {
4817
- await saveCache(absoluteRoot, cache);
4818
- }
4819
- onProgress?.({
4820
- current: totalFiles,
4821
- total: totalFiles,
4822
- currentFile: "",
4823
- phase: "aggregating"
4824
- });
4825
- const analysis = aggregateAllUsages(allUsages, allImports, componentSources);
4826
- analysis.rootDir = absoluteRoot;
4827
- analysis.totalFiles = totalFiles;
4828
- analysis.errorFiles = errorFiles;
4829
- return analysis;
4830
- }
4831
- async function incrementalScan(rootDir, changes, existingCache, onProgress) {
4832
- const absoluteRoot = resolve3(rootDir);
4833
- const cache = { ...existingCache, files: { ...existingCache.files } };
4834
- for (const filePath of changes.deleted) {
4835
- removeCacheFile(cache, filePath);
4836
- }
4837
- const filesToScan = [...changes.added, ...changes.modified];
4838
- const totalFiles = filesToScan.length;
4839
- const allImports = [];
4840
- const allUsages = [];
4841
- const errorFiles = [];
4842
- const componentSources = /* @__PURE__ */ new Map();
4843
- for (const filePath of changes.unchanged) {
4844
- const cachedEntry = getCachedFile(cache, filePath);
4845
- if (cachedEntry) {
4846
- allImports.push(...cachedEntry.imports);
4847
- allUsages.push(...cachedEntry.usages);
4848
- for (const imp of cachedEntry.imports) {
4849
- if (!componentSources.has(imp.componentName)) {
4850
- const sourceFile = resolveImportSource(filePath, imp.source);
4851
- if (sourceFile) {
4852
- componentSources.set(imp.componentName, sourceFile);
4853
- }
4854
- }
4855
- }
4856
- }
4857
- }
4858
- for (let i = 0; i < filesToScan.length; i++) {
4859
- const filePath = filesToScan[i];
4860
- const relativePath = relative2(absoluteRoot, filePath);
4861
- onProgress?.({
4862
- current: i + 1,
4863
- total: totalFiles,
4864
- currentFile: relativePath,
4865
- phase: "scanning"
4866
- });
4867
- try {
4868
- const content = await readFile6(filePath, "utf-8");
4869
- const fileHash = computeFileHash(content);
4870
- const { imports, usages } = await scanFile(filePath);
4871
- updateCacheFile(cache, filePath, fileHash, imports, usages);
4872
- allImports.push(...imports);
4873
- allUsages.push(...usages);
4874
- for (const imp of imports) {
4875
- if (!componentSources.has(imp.componentName)) {
4876
- const sourceFile = resolveImportSource(filePath, imp.source);
4877
- if (sourceFile) {
4878
- componentSources.set(imp.componentName, sourceFile);
4879
- }
4880
- }
4881
- }
4882
- } catch (error) {
4883
- errorFiles.push(relativePath);
4884
- }
4885
- }
4886
- await saveCache(absoluteRoot, cache);
4887
- const analysis = aggregateAllUsages(allUsages, allImports, componentSources);
4888
- analysis.rootDir = absoluteRoot;
4889
- analysis.totalFiles = changes.unchanged.length + filesToScan.length;
4890
- analysis.errorFiles = errorFiles;
4891
- return { analysis, cache };
4892
- }
4893
- function resolveImportSource(importingFile, source) {
4894
- if (!source.startsWith(".") && !source.startsWith("/")) {
4895
- return null;
4896
- }
4897
- const importDir = dirname4(importingFile);
4898
- const extensions = ["", ".tsx", ".ts", ".jsx", ".js", "/index.tsx", "/index.ts"];
4899
- for (const ext of extensions) {
4900
- const fullPath = resolve3(importDir, source + ext);
4901
- if (ext === "" && source.endsWith(".tsx")) {
4902
- return fullPath;
4903
- }
4904
- if (ext) {
4905
- return resolve3(importDir, source) + ext;
4906
- }
4907
- }
4908
- return resolve3(importDir, source);
4909
- }
4910
- function getScanStats(analysis) {
4911
- const totalUsages = Object.values(analysis.components).reduce(
4912
- (sum, c) => sum + c.totalUsages,
4913
- 0
4914
- );
4915
- const topComponents = Object.values(analysis.components).map((c) => ({ name: c.name, usages: c.totalUsages })).sort((a, b) => b.usages - a.usages).slice(0, 10);
4916
- return {
4917
- totalFiles: analysis.totalFiles,
4918
- totalComponents: analysis.totalComponents,
4919
- totalUsages,
4920
- topComponents
4921
- };
4922
- }
4923
- async function hasCachedAnalysis(rootDir) {
4924
- const cache = await loadCache(resolve3(rootDir));
4925
- if (!cache) return false;
4926
- const stats = getCacheStats(cache);
4927
- return stats.totalFiles > 0;
4928
- }
4929
-
4930
- // src/service/enhance/doc-extractor.ts
4931
- import { parse as parse3 } from "@babel/parser";
4932
- import _traverse2 from "@babel/traverse";
4933
- import * as t3 from "@babel/types";
4934
- import { readFile as readFile7 } from "fs/promises";
4935
- import { existsSync as existsSync3 } from "fs";
4936
- import { basename as basename2, dirname as dirname5, join as join4 } from "path";
4937
- var traverse3 = _traverse2.default || _traverse2;
3759
+ import { basename, dirname as dirname3, join as join3 } from "path";
3760
+ var traverse2 = _traverse.default || _traverse;
4938
3761
  async function extractComponentDocs(filePath) {
4939
- const content = await readFile7(filePath, "utf-8");
3762
+ const content = await readFile3(filePath, "utf-8");
4940
3763
  return extractDocsFromSource(content, filePath);
4941
3764
  }
4942
3765
  function extractDocsFromSource(source, filePath) {
4943
3766
  const isTypeScript = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
4944
3767
  const isJSX = filePath.endsWith(".tsx") || filePath.endsWith(".jsx");
4945
- const ast = parse3(source, {
3768
+ const ast = parse2(source, {
4946
3769
  sourceType: "module",
4947
3770
  plugins: [
4948
3771
  ...isTypeScript ? ["typescript"] : [],
@@ -4959,7 +3782,7 @@ function extractDocsFromSource(source, filePath) {
4959
3782
  tags: {}
4960
3783
  };
4961
3784
  let mainExportComment;
4962
- traverse3(ast, {
3785
+ traverse2(ast, {
4963
3786
  // Extract JSDoc from function declarations
4964
3787
  FunctionDeclaration(path) {
4965
3788
  const leadingComments = path.node.leadingComments;
@@ -5095,7 +3918,7 @@ function processTag(docs, tag, content) {
5095
3918
  function extractPropsFromInterface(node) {
5096
3919
  const props = [];
5097
3920
  for (const member of node.body.body) {
5098
- if (t3.isTSPropertySignature(member) && t3.isIdentifier(member.key)) {
3921
+ if (t2.isTSPropertySignature(member) && t2.isIdentifier(member.key)) {
5099
3922
  const name = member.key.name;
5100
3923
  const type = member.typeAnnotation ? typeAnnotationToString(member.typeAnnotation.typeAnnotation) : "unknown";
5101
3924
  const required = !member.optional;
@@ -5115,9 +3938,9 @@ function extractPropsFromInterface(node) {
5115
3938
  }
5116
3939
  function extractPropsFromTypeAlias(node) {
5117
3940
  const props = [];
5118
- if (t3.isTSTypeLiteral(node.typeAnnotation)) {
3941
+ if (t2.isTSTypeLiteral(node.typeAnnotation)) {
5119
3942
  for (const member of node.typeAnnotation.members) {
5120
- if (t3.isTSPropertySignature(member) && t3.isIdentifier(member.key)) {
3943
+ if (t2.isTSPropertySignature(member) && t2.isIdentifier(member.key)) {
5121
3944
  const name = member.key.name;
5122
3945
  const type = member.typeAnnotation ? typeAnnotationToString(member.typeAnnotation.typeAnnotation) : "unknown";
5123
3946
  const required = !member.optional;
@@ -5133,23 +3956,23 @@ function extractPropsFromTypeAlias(node) {
5133
3956
  return props;
5134
3957
  }
5135
3958
  function typeAnnotationToString(node) {
5136
- if (t3.isTSStringKeyword(node)) return "string";
5137
- if (t3.isTSNumberKeyword(node)) return "number";
5138
- if (t3.isTSBooleanKeyword(node)) return "boolean";
5139
- if (t3.isTSNullKeyword(node)) return "null";
5140
- if (t3.isTSUndefinedKeyword(node)) return "undefined";
5141
- if (t3.isTSVoidKeyword(node)) return "void";
5142
- if (t3.isTSAnyKeyword(node)) return "any";
5143
- if (t3.isTSNeverKeyword(node)) return "never";
5144
- if (t3.isTSUnknownKeyword(node)) return "unknown";
5145
- if (t3.isTSLiteralType(node)) {
5146
- if (t3.isStringLiteral(node.literal)) return `"${node.literal.value}"`;
5147
- if (t3.isNumericLiteral(node.literal)) return String(node.literal.value);
5148
- if (t3.isBooleanLiteral(node.literal)) return String(node.literal.value);
3959
+ if (t2.isTSStringKeyword(node)) return "string";
3960
+ if (t2.isTSNumberKeyword(node)) return "number";
3961
+ if (t2.isTSBooleanKeyword(node)) return "boolean";
3962
+ if (t2.isTSNullKeyword(node)) return "null";
3963
+ if (t2.isTSUndefinedKeyword(node)) return "undefined";
3964
+ if (t2.isTSVoidKeyword(node)) return "void";
3965
+ if (t2.isTSAnyKeyword(node)) return "any";
3966
+ if (t2.isTSNeverKeyword(node)) return "never";
3967
+ if (t2.isTSUnknownKeyword(node)) return "unknown";
3968
+ if (t2.isTSLiteralType(node)) {
3969
+ if (t2.isStringLiteral(node.literal)) return `"${node.literal.value}"`;
3970
+ if (t2.isNumericLiteral(node.literal)) return String(node.literal.value);
3971
+ if (t2.isBooleanLiteral(node.literal)) return String(node.literal.value);
5149
3972
  return "literal";
5150
3973
  }
5151
- if (t3.isTSTypeReference(node)) {
5152
- if (t3.isIdentifier(node.typeName)) {
3974
+ if (t2.isTSTypeReference(node)) {
3975
+ if (t2.isIdentifier(node.typeName)) {
5153
3976
  const name = node.typeName.name;
5154
3977
  if (node.typeParameters) {
5155
3978
  const params = node.typeParameters.params.map(typeAnnotationToString).join(", ");
@@ -5158,28 +3981,28 @@ function typeAnnotationToString(node) {
5158
3981
  return name;
5159
3982
  }
5160
3983
  }
5161
- if (t3.isTSUnionType(node)) {
3984
+ if (t2.isTSUnionType(node)) {
5162
3985
  return node.types.map(typeAnnotationToString).join(" | ");
5163
3986
  }
5164
- if (t3.isTSIntersectionType(node)) {
3987
+ if (t2.isTSIntersectionType(node)) {
5165
3988
  return node.types.map(typeAnnotationToString).join(" & ");
5166
3989
  }
5167
- if (t3.isTSArrayType(node)) {
3990
+ if (t2.isTSArrayType(node)) {
5168
3991
  return `${typeAnnotationToString(node.elementType)}[]`;
5169
3992
  }
5170
- if (t3.isTSFunctionType(node)) {
3993
+ if (t2.isTSFunctionType(node)) {
5171
3994
  return "(...args: any[]) => any";
5172
3995
  }
5173
- if (t3.isTSTupleType(node)) {
3996
+ if (t2.isTSTupleType(node)) {
5174
3997
  const elements = node.elementTypes.map((el) => {
5175
- if (t3.isTSNamedTupleMember(el)) {
3998
+ if (t2.isTSNamedTupleMember(el)) {
5176
3999
  return typeAnnotationToString(el.elementType);
5177
4000
  }
5178
4001
  return typeAnnotationToString(el);
5179
4002
  }).join(", ");
5180
4003
  return `[${elements}]`;
5181
4004
  }
5182
- if (t3.isTSTypeLiteral(node)) {
4005
+ if (t2.isTSTypeLiteral(node)) {
5183
4006
  return "object";
5184
4007
  }
5185
4008
  return "unknown";
@@ -5189,28 +4012,28 @@ function isPropsInterface(name) {
5189
4012
  }
5190
4013
  function isExportedComponent(path) {
5191
4014
  const parent = path.parent;
5192
- if (t3.isExportDefaultDeclaration(parent)) return true;
5193
- if (t3.isExportNamedDeclaration(parent)) return true;
5194
- if (t3.isProgram(parent) && path.node.id && /^[A-Z]/.test(path.node.id.name)) {
4015
+ if (t2.isExportDefaultDeclaration(parent)) return true;
4016
+ if (t2.isExportNamedDeclaration(parent)) return true;
4017
+ if (t2.isProgram(parent) && path.node.id && /^[A-Z]/.test(path.node.id.name)) {
5195
4018
  return true;
5196
4019
  }
5197
4020
  return false;
5198
4021
  }
5199
4022
  function hasExportedArrowFunction(path) {
5200
4023
  const parent = path.parent;
5201
- if (!t3.isExportNamedDeclaration(parent)) return false;
4024
+ if (!t2.isExportNamedDeclaration(parent)) return false;
5202
4025
  for (const declarator of path.node.declarations) {
5203
- if (t3.isIdentifier(declarator.id) && /^[A-Z]/.test(declarator.id.name) && (t3.isArrowFunctionExpression(declarator.init) || t3.isFunctionExpression(declarator.init))) {
4026
+ if (t2.isIdentifier(declarator.id) && /^[A-Z]/.test(declarator.id.name) && (t2.isArrowFunctionExpression(declarator.init) || t2.isFunctionExpression(declarator.init))) {
5204
4027
  return true;
5205
4028
  }
5206
4029
  }
5207
4030
  return false;
5208
4031
  }
5209
4032
  function inferComponentName(filePath) {
5210
- const fileName = basename2(filePath);
4033
+ const fileName = basename(filePath);
5211
4034
  let name = fileName.replace(/\.(tsx?|jsx?)$/, "");
5212
4035
  if (name === "index") {
5213
- name = basename2(dirname5(filePath));
4036
+ name = basename(dirname3(filePath));
5214
4037
  }
5215
4038
  return name;
5216
4039
  }
@@ -5249,8 +4072,8 @@ async function findComponentSource(componentName, searchDirs) {
5249
4072
  ];
5250
4073
  for (const dir of searchDirs) {
5251
4074
  for (const pattern of patterns) {
5252
- const fullPath = join4(dir, pattern);
5253
- if (existsSync3(fullPath)) {
4075
+ const fullPath = join3(dir, pattern);
4076
+ if (existsSync2(fullPath)) {
5254
4077
  return fullPath;
5255
4078
  }
5256
4079
  }
@@ -5275,21 +4098,21 @@ async function extractAllComponentDocs(componentFiles) {
5275
4098
  }
5276
4099
 
5277
4100
  // src/service/enhance/storybook-parser.ts
5278
- import { parse as parse4 } from "@babel/parser";
5279
- import _traverse3 from "@babel/traverse";
5280
- import * as t4 from "@babel/types";
5281
- import { readFile as readFile8 } from "fs/promises";
5282
- import fg2 from "fast-glob";
5283
- import { basename as basename3, relative as relative3 } from "path";
5284
- var traverse4 = _traverse3.default || _traverse3;
4101
+ import { parse as parse3 } from "@babel/parser";
4102
+ import _traverse2 from "@babel/traverse";
4103
+ import * as t3 from "@babel/types";
4104
+ import { readFile as readFile4 } from "fs/promises";
4105
+ import fg from "fast-glob";
4106
+ import { basename as basename2, relative } from "path";
4107
+ var traverse3 = _traverse2.default || _traverse2;
5285
4108
  async function parseStoryFile(filePath) {
5286
- const content = await readFile8(filePath, "utf-8");
4109
+ const content = await readFile4(filePath, "utf-8");
5287
4110
  return parseStorySource(content, filePath);
5288
4111
  }
5289
4112
  function parseStorySource(source, filePath) {
5290
4113
  const isTypeScript = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
5291
4114
  const isJSX = filePath.endsWith(".tsx") || filePath.endsWith(".jsx");
5292
- const ast = parse4(source, {
4115
+ const ast = parse3(source, {
5293
4116
  sourceType: "module",
5294
4117
  plugins: [
5295
4118
  ...isTypeScript ? ["typescript"] : [],
@@ -5305,7 +4128,7 @@ function parseStorySource(source, filePath) {
5305
4128
  stories: []
5306
4129
  };
5307
4130
  let defaultExportNode = null;
5308
- traverse4(ast, {
4131
+ traverse3(ast, {
5309
4132
  ExportDefaultDeclaration(path) {
5310
4133
  defaultExportNode = path.node.declaration;
5311
4134
  }
@@ -5316,12 +4139,12 @@ function parseStorySource(source, filePath) {
5316
4139
  result.meta = parseMetaObject(metaObject, result.meta.componentName);
5317
4140
  }
5318
4141
  }
5319
- traverse4(ast, {
4142
+ traverse3(ast, {
5320
4143
  ExportNamedDeclaration(path) {
5321
4144
  const declaration = path.node.declaration;
5322
- if (t4.isVariableDeclaration(declaration)) {
4145
+ if (t3.isVariableDeclaration(declaration)) {
5323
4146
  for (const declarator of declaration.declarations) {
5324
- if (!t4.isIdentifier(declarator.id)) continue;
4147
+ if (!t3.isIdentifier(declarator.id)) continue;
5325
4148
  const storyName = declarator.id.name;
5326
4149
  if (!/^[A-Z]/.test(storyName)) continue;
5327
4150
  const story = parseStoryDeclarator(
@@ -5346,25 +4169,25 @@ function parseStorySource(source, filePath) {
5346
4169
  return result;
5347
4170
  }
5348
4171
  function extractMetaObject(node, ast) {
5349
- if (t4.isObjectExpression(node)) {
4172
+ if (t3.isObjectExpression(node)) {
5350
4173
  return node;
5351
4174
  }
5352
- if (t4.isIdentifier(node)) {
4175
+ if (t3.isIdentifier(node)) {
5353
4176
  const metaName = node.name;
5354
4177
  let foundObject = null;
5355
- traverse4(ast, {
4178
+ traverse3(ast, {
5356
4179
  VariableDeclarator(path) {
5357
- if (t4.isIdentifier(path.node.id) && path.node.id.name === metaName && t4.isObjectExpression(path.node.init)) {
4180
+ if (t3.isIdentifier(path.node.id) && path.node.id.name === metaName && t3.isObjectExpression(path.node.init)) {
5358
4181
  foundObject = path.node.init;
5359
4182
  }
5360
4183
  }
5361
4184
  });
5362
4185
  return foundObject;
5363
4186
  }
5364
- if (t4.isTSAsExpression(node) && t4.isObjectExpression(node.expression)) {
4187
+ if (t3.isTSAsExpression(node) && t3.isObjectExpression(node.expression)) {
5365
4188
  return node.expression;
5366
4189
  }
5367
- if (t4.isTSSatisfiesExpression && t4.isTSSatisfiesExpression(node) && t4.isObjectExpression(node.expression)) {
4190
+ if (t3.isTSSatisfiesExpression && t3.isTSSatisfiesExpression(node) && t3.isObjectExpression(node.expression)) {
5368
4191
  return node.expression;
5369
4192
  }
5370
4193
  return null;
@@ -5374,23 +4197,23 @@ function parseMetaObject(obj, fallbackName) {
5374
4197
  componentName: fallbackName
5375
4198
  };
5376
4199
  for (const prop of obj.properties) {
5377
- if (!t4.isObjectProperty(prop) || !t4.isIdentifier(prop.key)) continue;
4200
+ if (!t3.isObjectProperty(prop) || !t3.isIdentifier(prop.key)) continue;
5378
4201
  const key = prop.key.name;
5379
4202
  switch (key) {
5380
4203
  case "title":
5381
- if (t4.isStringLiteral(prop.value)) {
4204
+ if (t3.isStringLiteral(prop.value)) {
5382
4205
  meta.title = prop.value.value;
5383
4206
  const parts = meta.title.split("/");
5384
4207
  meta.componentName = parts[parts.length - 1];
5385
4208
  }
5386
4209
  break;
5387
4210
  case "component":
5388
- if (t4.isIdentifier(prop.value)) {
4211
+ if (t3.isIdentifier(prop.value)) {
5389
4212
  meta.componentName = prop.value.name;
5390
4213
  }
5391
4214
  break;
5392
4215
  case "parameters":
5393
- if (t4.isObjectExpression(prop.value)) {
4216
+ if (t3.isObjectExpression(prop.value)) {
5394
4217
  meta.parameters = extractObjectLiteral(prop.value);
5395
4218
  const docs = meta.parameters?.docs;
5396
4219
  if (docs?.description) {
@@ -5402,7 +4225,7 @@ function parseMetaObject(obj, fallbackName) {
5402
4225
  }
5403
4226
  break;
5404
4227
  case "argTypes":
5405
- if (t4.isObjectExpression(prop.value)) {
4228
+ if (t3.isObjectExpression(prop.value)) {
5406
4229
  meta.argTypes = parseArgTypes(prop.value);
5407
4230
  }
5408
4231
  break;
@@ -5413,29 +4236,29 @@ function parseMetaObject(obj, fallbackName) {
5413
4236
  function parseArgTypes(obj) {
5414
4237
  const argTypes = {};
5415
4238
  for (const prop of obj.properties) {
5416
- if (!t4.isObjectProperty(prop) || !t4.isIdentifier(prop.key)) continue;
4239
+ if (!t3.isObjectProperty(prop) || !t3.isIdentifier(prop.key)) continue;
5417
4240
  const propName = prop.key.name;
5418
4241
  const argType = {};
5419
- if (t4.isObjectExpression(prop.value)) {
4242
+ if (t3.isObjectExpression(prop.value)) {
5420
4243
  for (const inner of prop.value.properties) {
5421
- if (!t4.isObjectProperty(inner) || !t4.isIdentifier(inner.key)) continue;
4244
+ if (!t3.isObjectProperty(inner) || !t3.isIdentifier(inner.key)) continue;
5422
4245
  const innerKey = inner.key.name;
5423
- if (innerKey === "description" && t4.isStringLiteral(inner.value)) {
4246
+ if (innerKey === "description" && t3.isStringLiteral(inner.value)) {
5424
4247
  argType.description = inner.value.value;
5425
4248
  }
5426
4249
  if (innerKey === "defaultValue") {
5427
4250
  argType.defaultValue = extractLiteralValue(inner.value);
5428
4251
  }
5429
4252
  if (innerKey === "control") {
5430
- if (t4.isStringLiteral(inner.value)) {
4253
+ if (t3.isStringLiteral(inner.value)) {
5431
4254
  argType.control = inner.value.value;
5432
- } else if (t4.isObjectExpression(inner.value)) {
4255
+ } else if (t3.isObjectExpression(inner.value)) {
5433
4256
  const controlObj = extractObjectLiteral(inner.value);
5434
4257
  argType.control = controlObj?.type;
5435
4258
  }
5436
4259
  }
5437
- if (innerKey === "options" && t4.isArrayExpression(inner.value)) {
5438
- argType.options = inner.value.elements.filter((el) => t4.isStringLiteral(el)).map((el) => el.value);
4260
+ if (innerKey === "options" && t3.isArrayExpression(inner.value)) {
4261
+ argType.options = inner.value.elements.filter((el) => t3.isStringLiteral(el)).map((el) => el.value);
5439
4262
  }
5440
4263
  }
5441
4264
  }
@@ -5453,25 +4276,25 @@ function parseStoryDeclarator(name, declarator, source, componentName) {
5453
4276
  code: "",
5454
4277
  isDefault: false
5455
4278
  };
5456
- if (t4.isObjectExpression(init)) {
4279
+ if (t3.isObjectExpression(init)) {
5457
4280
  parseStoryObject(init, story);
5458
4281
  story.code = generateStoryCode(componentName, story.args);
5459
4282
  return story;
5460
4283
  }
5461
- if (t4.isTSAsExpression(init) && t4.isObjectExpression(init.expression)) {
4284
+ if (t3.isTSAsExpression(init) && t3.isObjectExpression(init.expression)) {
5462
4285
  parseStoryObject(init.expression, story);
5463
4286
  story.code = generateStoryCode(componentName, story.args);
5464
4287
  return story;
5465
4288
  }
5466
- if (t4.isArrowFunctionExpression(init) || t4.isFunctionExpression(init)) {
4289
+ if (t3.isArrowFunctionExpression(init) || t3.isFunctionExpression(init)) {
5467
4290
  if (init.start != null && init.end != null) {
5468
4291
  const fnCode = source.slice(init.start, init.end);
5469
4292
  story.code = fnCode;
5470
4293
  }
5471
4294
  return story;
5472
4295
  }
5473
- if (t4.isTSSatisfiesExpression && t4.isTSSatisfiesExpression(init)) {
5474
- if (t4.isObjectExpression(init.expression)) {
4296
+ if (t3.isTSSatisfiesExpression && t3.isTSSatisfiesExpression(init)) {
4297
+ if (t3.isObjectExpression(init.expression)) {
5475
4298
  parseStoryObject(init.expression, story);
5476
4299
  story.code = generateStoryCode(componentName, story.args);
5477
4300
  return story;
@@ -5481,21 +4304,21 @@ function parseStoryDeclarator(name, declarator, source, componentName) {
5481
4304
  }
5482
4305
  function parseStoryObject(obj, story) {
5483
4306
  for (const prop of obj.properties) {
5484
- if (!t4.isObjectProperty(prop) || !t4.isIdentifier(prop.key)) continue;
4307
+ if (!t3.isObjectProperty(prop) || !t3.isIdentifier(prop.key)) continue;
5485
4308
  const key = prop.key.name;
5486
4309
  switch (key) {
5487
4310
  case "name":
5488
- if (t4.isStringLiteral(prop.value)) {
4311
+ if (t3.isStringLiteral(prop.value)) {
5489
4312
  story.displayName = prop.value.value;
5490
4313
  }
5491
4314
  break;
5492
4315
  case "args":
5493
- if (t4.isObjectExpression(prop.value)) {
4316
+ if (t3.isObjectExpression(prop.value)) {
5494
4317
  story.args = extractObjectLiteral(prop.value);
5495
4318
  }
5496
4319
  break;
5497
4320
  case "parameters":
5498
- if (t4.isObjectExpression(prop.value)) {
4321
+ if (t3.isObjectExpression(prop.value)) {
5499
4322
  const params = extractObjectLiteral(prop.value);
5500
4323
  const docs = params?.docs;
5501
4324
  if (docs?.description) {
@@ -5510,15 +4333,15 @@ function parseStoryObject(obj, story) {
5510
4333
  }
5511
4334
  }
5512
4335
  function extractLiteralValue(node) {
5513
- if (t4.isStringLiteral(node)) return node.value;
5514
- if (t4.isNumericLiteral(node)) return node.value;
5515
- if (t4.isBooleanLiteral(node)) return node.value;
5516
- if (t4.isNullLiteral(node)) return null;
5517
- if (t4.isIdentifier(node) && node.name === "undefined") return void 0;
5518
- if (t4.isArrayExpression(node)) {
5519
- return node.elements.filter((el) => el !== null && t4.isExpression(el)).map(extractLiteralValue);
5520
- }
5521
- if (t4.isObjectExpression(node)) {
4336
+ if (t3.isStringLiteral(node)) return node.value;
4337
+ if (t3.isNumericLiteral(node)) return node.value;
4338
+ if (t3.isBooleanLiteral(node)) return node.value;
4339
+ if (t3.isNullLiteral(node)) return null;
4340
+ if (t3.isIdentifier(node) && node.name === "undefined") return void 0;
4341
+ if (t3.isArrayExpression(node)) {
4342
+ return node.elements.filter((el) => el !== null && t3.isExpression(el)).map(extractLiteralValue);
4343
+ }
4344
+ if (t3.isObjectExpression(node)) {
5522
4345
  return extractObjectLiteral(node);
5523
4346
  }
5524
4347
  return void 0;
@@ -5526,12 +4349,12 @@ function extractLiteralValue(node) {
5526
4349
  function extractObjectLiteral(node) {
5527
4350
  const obj = {};
5528
4351
  for (const prop of node.properties) {
5529
- if (t4.isSpreadElement(prop)) continue;
5530
- if (!t4.isObjectProperty(prop)) continue;
4352
+ if (t3.isSpreadElement(prop)) continue;
4353
+ if (!t3.isObjectProperty(prop)) continue;
5531
4354
  let key;
5532
- if (t4.isIdentifier(prop.key)) {
4355
+ if (t3.isIdentifier(prop.key)) {
5533
4356
  key = prop.key.name;
5534
- } else if (t4.isStringLiteral(prop.key)) {
4357
+ } else if (t3.isStringLiteral(prop.key)) {
5535
4358
  key = prop.key.value;
5536
4359
  } else {
5537
4360
  continue;
@@ -5559,12 +4382,12 @@ function camelToTitle(str) {
5559
4382
  return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
5560
4383
  }
5561
4384
  function inferComponentFromPath(filePath) {
5562
- const fileName = basename3(filePath);
4385
+ const fileName = basename2(filePath);
5563
4386
  const name = fileName.replace(/\.stories\.(tsx?|jsx?|mdx?)$/, "");
5564
4387
  return name;
5565
4388
  }
5566
4389
  async function findStoryFiles(rootDir, include = ["**/*.stories.{tsx,ts,jsx,js}"], exclude = ["**/node_modules/**", "**/dist/**"]) {
5567
- return fg2(include, {
4390
+ return fg(include, {
5568
4391
  cwd: rootDir,
5569
4392
  ignore: exclude,
5570
4393
  absolute: true,
@@ -5580,7 +4403,7 @@ async function parseAllStories(rootDir) {
5580
4403
  results.set(parsed.meta.componentName, parsed);
5581
4404
  } catch (error) {
5582
4405
  console.warn(
5583
- `Failed to parse story file ${relative3(rootDir, filePath)}:`,
4406
+ `Failed to parse story file ${relative(rootDir, filePath)}:`,
5584
4407
  error.message
5585
4408
  );
5586
4409
  }
@@ -5918,12 +4741,12 @@ If there isn't enough usage data to make confident recommendations, indicate tha
5918
4741
 
5919
4742
  // src/service/enhance/props-extractor.ts
5920
4743
  import * as ts from "typescript";
5921
- import { readFile as readFile9 } from "fs/promises";
5922
- import { existsSync as existsSync4 } from "fs";
5923
- import { basename as basename4, dirname as dirname7, join as join6, resolve as resolve4 } from "path";
4744
+ import { readFile as readFile5 } from "fs/promises";
4745
+ import { existsSync as existsSync3 } from "fs";
4746
+ import { basename as basename3, dirname as dirname5, join as join5, resolve as resolve2 } from "path";
5924
4747
  async function extractPropsFromFile(filePath, options = {}) {
5925
- const absPath = resolve4(filePath);
5926
- if (!existsSync4(absPath)) {
4748
+ const absPath = resolve2(filePath);
4749
+ if (!existsSync3(absPath)) {
5927
4750
  return {
5928
4751
  filePath: absPath,
5929
4752
  componentName: inferComponentName2(absPath),
@@ -5932,7 +4755,7 @@ async function extractPropsFromFile(filePath, options = {}) {
5932
4755
  warnings: [`File not found: ${absPath}`]
5933
4756
  };
5934
4757
  }
5935
- const content = await readFile9(absPath, "utf-8");
4758
+ const content = await readFile5(absPath, "utf-8");
5936
4759
  return extractPropsFromSource(content, absPath, options);
5937
4760
  }
5938
4761
  function extractPropsFromSource(source, filePath, options = {}) {
@@ -6221,8 +5044,19 @@ function extractPropsFromInlineParams(componentName, sourceFile) {
6221
5044
  }
6222
5045
  if (ts.isVariableStatement(node)) {
6223
5046
  for (const decl of node.declarationList.declarations) {
6224
- if (ts.isIdentifier(decl.name) && decl.name.text === componentName && decl.initializer && (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {
6225
- targetFunc = decl.initializer;
5047
+ if (ts.isIdentifier(decl.name) && decl.name.text === componentName && decl.initializer) {
5048
+ if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {
5049
+ targetFunc = decl.initializer;
5050
+ } else if (ts.isCallExpression(decl.initializer)) {
5051
+ const callee = decl.initializer.expression;
5052
+ const isForwardRef = ts.isPropertyAccessExpression(callee) && callee.name.text === "forwardRef" || ts.isIdentifier(callee) && callee.text === "forwardRef";
5053
+ if (isForwardRef && decl.initializer.arguments.length > 0) {
5054
+ const firstArg = decl.initializer.arguments[0];
5055
+ if (ts.isArrowFunction(firstArg) || ts.isFunctionExpression(firstArg)) {
5056
+ targetFunc = firstArg;
5057
+ }
5058
+ }
5059
+ }
6226
5060
  }
6227
5061
  }
6228
5062
  }
@@ -6340,12 +5174,12 @@ function extractCvaVariants(sourceFile, props) {
6340
5174
  }
6341
5175
  }
6342
5176
  function inferComponentName2(filePath) {
6343
- const fileName = basename4(filePath);
5177
+ const fileName = basename3(filePath);
6344
5178
  let name = fileName.replace(/\.(tsx?|jsx?)$/, "");
6345
5179
  if (name === "index") {
6346
- name = basename4(dirname7(filePath));
5180
+ name = basename3(dirname5(filePath));
6347
5181
  }
6348
- return name;
5182
+ return name.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
6349
5183
  }
6350
5184
  function convertToFragmentProps(props) {
6351
5185
  const result = {};
@@ -6391,10 +5225,11 @@ async function extractPropsForComponent(componentName, searchDirs) {
6391
5225
  ];
6392
5226
  for (const dir of searchDirs) {
6393
5227
  for (const pattern of patterns) {
6394
- const fullPath = join6(dir, pattern);
6395
- if (existsSync4(fullPath)) {
5228
+ const fullPath = join5(dir, pattern);
5229
+ if (existsSync3(fullPath)) {
6396
5230
  return extractPropsFromFile(fullPath, {
6397
- propsTypeName: `${componentName}Props`
5231
+ propsTypeName: `${componentName}Props`,
5232
+ componentName
6398
5233
  });
6399
5234
  }
6400
5235
  }
@@ -6406,7 +5241,8 @@ async function extractAllComponentProps(componentFiles) {
6406
5241
  for (const [componentName, filePath] of componentFiles) {
6407
5242
  try {
6408
5243
  const extraction = await extractPropsFromFile(filePath, {
6409
- propsTypeName: `${componentName}Props`
5244
+ propsTypeName: `${componentName}Props`,
5245
+ componentName
6410
5246
  });
6411
5247
  results.set(componentName, extraction);
6412
5248
  } catch (error) {
@@ -6709,12 +5545,6 @@ export {
6709
5545
  getGrade,
6710
5546
  getScoreColor,
6711
5547
  generateHtmlReport,
6712
- parseTokenFile,
6713
- parseTokenFiles,
6714
- hexToRgb,
6715
- rgbToHex,
6716
- parseRgb,
6717
- normalizeColor,
6718
5548
  TokenRegistryManager,
6719
5549
  getSharedTokenRegistry,
6720
5550
  initializeSharedRegistry,
@@ -6730,25 +5560,6 @@ export {
6730
5560
  applyPatches,
6731
5561
  MetricsStore,
6732
5562
  createMetricsStore,
6733
- scanFileForImports,
6734
- scanFileForUsages,
6735
- scanFile,
6736
- aggregateComponentUsages,
6737
- aggregateAllUsages,
6738
- findCommonPropCombinations,
6739
- inferRelations,
6740
- inferAllRelations,
6741
- summarizePatternsForPrompt,
6742
- loadCache,
6743
- saveCache,
6744
- createEmptyCache,
6745
- computeFileHash,
6746
- detectFileChanges,
6747
- getCacheStats,
6748
- scanCodebase,
6749
- incrementalScan,
6750
- getScanStats,
6751
- hasCachedAnalysis,
6752
5563
  extractComponentDocs,
6753
5564
  extractDocsFromSource,
6754
5565
  findComponentSource,
@@ -6776,4 +5587,4 @@ export {
6776
5587
  getStorybookStoryIds,
6777
5588
  renderAllComponentVariants
6778
5589
  };
6779
- //# sourceMappingURL=chunk-APTQIBS5.js.map
5590
+ //# sourceMappingURL=chunk-6SQPP47U.js.map