@fragments-sdk/cli 0.10.1 → 0.12.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 (223) hide show
  1. package/dist/ai-client-I6MDWNYA.js +21 -0
  2. package/dist/bin.js +292 -367
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-PW7QTQA6.js → chunk-4OC7FTJB.js} +2 -2
  5. package/dist/{chunk-HRFUSSZI.js → chunk-AM4MRTMN.js} +2 -2
  6. package/dist/{chunk-5G3VZH43.js → chunk-GVDSFQ4E.js} +281 -351
  7. package/dist/chunk-GVDSFQ4E.js.map +1 -0
  8. package/dist/chunk-JJ2VRTBU.js +626 -0
  9. package/dist/chunk-JJ2VRTBU.js.map +1 -0
  10. package/dist/{chunk-D5PYOXEI.js → chunk-LVWFOLUZ.js} +148 -13
  11. package/dist/{chunk-D5PYOXEI.js.map → chunk-LVWFOLUZ.js.map} +1 -1
  12. package/dist/{chunk-WXSR2II7.js → chunk-OQKMEFOS.js} +58 -6
  13. package/dist/chunk-OQKMEFOS.js.map +1 -0
  14. package/dist/chunk-SXTKFDCR.js +104 -0
  15. package/dist/chunk-SXTKFDCR.js.map +1 -0
  16. package/dist/chunk-T5OMVL7E.js +443 -0
  17. package/dist/chunk-T5OMVL7E.js.map +1 -0
  18. package/dist/{chunk-ZM4ZQZWZ.js → chunk-TPWGL2XS.js} +39 -37
  19. package/dist/chunk-TPWGL2XS.js.map +1 -0
  20. package/dist/{chunk-OQO55NKV.js → chunk-WFS63PCW.js} +85 -11
  21. package/dist/chunk-WFS63PCW.js.map +1 -0
  22. package/dist/core/index.js +9 -1
  23. package/dist/{discovery-NEOY4MPN.js → discovery-ZJQSXF56.js} +3 -3
  24. package/dist/{generate-FBHSXR3D.js → generate-RJFS2JWA.js} +4 -4
  25. package/dist/index.js +7 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/init-ZSX3NRCZ.js +636 -0
  28. package/dist/init-ZSX3NRCZ.js.map +1 -0
  29. package/dist/mcp-bin.js +2 -2
  30. package/dist/{scan-CJF2DOQW.js → scan-3PMCJ4RB.js} +6 -6
  31. package/dist/scan-generate-SYU4PYZD.js +1115 -0
  32. package/dist/scan-generate-SYU4PYZD.js.map +1 -0
  33. package/dist/{service-TQYWY65E.js → service-VMGNJZ42.js} +3 -3
  34. package/dist/snapshot-XOISO2IS.js +139 -0
  35. package/dist/snapshot-XOISO2IS.js.map +1 -0
  36. package/dist/{static-viewer-NUBFPKWH.js → static-viewer-5GXH2MGE.js} +3 -3
  37. package/dist/static-viewer-5GXH2MGE.js.map +1 -0
  38. package/dist/{test-Z5LVO724.js → test-SI4NSHQX.js} +4 -4
  39. package/dist/{tokens-CE46OTMD.js → tokens-T6SIVUT5.js} +5 -5
  40. package/dist/{viewer-DNMNC5VS.js → viewer-7ZEAFBVN.js} +80 -58
  41. package/dist/viewer-7ZEAFBVN.js.map +1 -0
  42. package/package.json +6 -14
  43. package/src/ai-client.ts +156 -0
  44. package/src/bin.ts +74 -2
  45. package/src/build.ts +95 -33
  46. package/src/commands/__tests__/drift-sync.test.ts +252 -0
  47. package/src/commands/__tests__/scan-generate.test.ts +497 -45
  48. package/src/commands/enhance.ts +11 -35
  49. package/src/commands/init.ts +296 -193
  50. package/src/commands/scan-generate.ts +740 -139
  51. package/src/commands/scan.ts +37 -32
  52. package/src/commands/setup.ts +143 -52
  53. package/src/commands/snapshot.ts +197 -0
  54. package/src/commands/sync.ts +357 -0
  55. package/src/commands/validate.ts +43 -1
  56. package/src/core/component-extractor.test.ts +282 -0
  57. package/src/core/component-extractor.ts +1030 -0
  58. package/src/core/discovery.ts +93 -7
  59. package/src/service/enhance/props-extractor.ts +235 -13
  60. package/src/validators.ts +236 -0
  61. package/src/viewer/__tests__/viewer-integration.test.ts +85 -74
  62. package/src/viewer/server.ts +37 -22
  63. package/src/viewer/vite-plugin.ts +25 -9
  64. package/dist/chunk-5G3VZH43.js.map +0 -1
  65. package/dist/chunk-OQO55NKV.js.map +0 -1
  66. package/dist/chunk-WXSR2II7.js.map +0 -1
  67. package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
  68. package/dist/init-NDQXUWDU.js +0 -796
  69. package/dist/init-NDQXUWDU.js.map +0 -1
  70. package/dist/scan-generate-SJAN5MVI.js +0 -691
  71. package/dist/scan-generate-SJAN5MVI.js.map +0 -1
  72. package/dist/viewer-DNMNC5VS.js.map +0 -1
  73. package/src/ai.ts +0 -266
  74. package/src/commands/init-framework.ts +0 -414
  75. package/src/mcp/bin.ts +0 -36
  76. package/src/migrate/bin.ts +0 -114
  77. package/src/theme/index.ts +0 -77
  78. package/src/viewer/__tests__/a11y-fixes.test.ts +0 -358
  79. package/src/viewer/__tests__/jsx-parser.test.ts +0 -502
  80. package/src/viewer/__tests__/render-utils.test.ts +0 -232
  81. package/src/viewer/__tests__/style-utils.test.ts +0 -404
  82. package/src/viewer/assets/fragments-logo.ts +0 -4
  83. package/src/viewer/assets/fragments_logo.png +0 -0
  84. package/src/viewer/bin.ts +0 -86
  85. package/src/viewer/cli/health.ts +0 -256
  86. package/src/viewer/cli/index.ts +0 -33
  87. package/src/viewer/cli/scan.ts +0 -124
  88. package/src/viewer/cli/utils.ts +0 -174
  89. package/src/viewer/components/AccessibilityPanel.tsx +0 -1457
  90. package/src/viewer/components/ActionCapture.tsx +0 -172
  91. package/src/viewer/components/ActionsPanel.tsx +0 -332
  92. package/src/viewer/components/AllVariantsPreview.tsx +0 -78
  93. package/src/viewer/components/App.tsx +0 -582
  94. package/src/viewer/components/BottomPanel.tsx +0 -288
  95. package/src/viewer/components/CodePanel.naming.test.tsx +0 -59
  96. package/src/viewer/components/CodePanel.tsx +0 -118
  97. package/src/viewer/components/CommandPalette.tsx +0 -392
  98. package/src/viewer/components/ComponentDocView.tsx +0 -164
  99. package/src/viewer/components/ComponentGraph.tsx +0 -380
  100. package/src/viewer/components/ComponentHeader.tsx +0 -88
  101. package/src/viewer/components/ContractPanel.tsx +0 -241
  102. package/src/viewer/components/EmptyVariantMessage.tsx +0 -54
  103. package/src/viewer/components/ErrorBoundary.tsx +0 -97
  104. package/src/viewer/components/FigmaEmbed.tsx +0 -238
  105. package/src/viewer/components/FragmentEditor.tsx +0 -525
  106. package/src/viewer/components/FragmentRenderer.tsx +0 -61
  107. package/src/viewer/components/HeaderSearch.tsx +0 -24
  108. package/src/viewer/components/HealthDashboard.tsx +0 -441
  109. package/src/viewer/components/HmrStatusIndicator.tsx +0 -61
  110. package/src/viewer/components/Icons.tsx +0 -479
  111. package/src/viewer/components/InteractionsPanel.tsx +0 -757
  112. package/src/viewer/components/IsolatedPreviewFrame.tsx +0 -346
  113. package/src/viewer/components/IsolatedRender.tsx +0 -113
  114. package/src/viewer/components/KeyboardShortcutsHelp.tsx +0 -53
  115. package/src/viewer/components/LandingPage.tsx +0 -421
  116. package/src/viewer/components/Layout.tsx +0 -27
  117. package/src/viewer/components/LeftSidebar.tsx +0 -472
  118. package/src/viewer/components/LoadErrorMessage.tsx +0 -102
  119. package/src/viewer/components/MultiViewportPreview.tsx +0 -522
  120. package/src/viewer/components/NoVariantsMessage.tsx +0 -59
  121. package/src/viewer/components/PanelShell.tsx +0 -161
  122. package/src/viewer/components/PerformancePanel.tsx +0 -304
  123. package/src/viewer/components/PreviewArea.tsx +0 -472
  124. package/src/viewer/components/PreviewAside.tsx +0 -168
  125. package/src/viewer/components/PreviewFrameHost.tsx +0 -303
  126. package/src/viewer/components/PreviewPane.tsx +0 -149
  127. package/src/viewer/components/PreviewToolbar.tsx +0 -80
  128. package/src/viewer/components/PropsEditor.tsx +0 -506
  129. package/src/viewer/components/PropsTable.tsx +0 -111
  130. package/src/viewer/components/RelationsSection.tsx +0 -88
  131. package/src/viewer/components/ResizablePanel.tsx +0 -271
  132. package/src/viewer/components/RightSidebar.tsx +0 -102
  133. package/src/viewer/components/RuntimeToolsRegistrar.tsx +0 -17
  134. package/src/viewer/components/ScreenshotButton.tsx +0 -90
  135. package/src/viewer/components/Sidebar.tsx +0 -169
  136. package/src/viewer/components/SkeletonLoader.tsx +0 -161
  137. package/src/viewer/components/ThemeProvider.tsx +0 -42
  138. package/src/viewer/components/Toast.tsx +0 -3
  139. package/src/viewer/components/TokenStylePanel.tsx +0 -699
  140. package/src/viewer/components/TopToolbar.tsx +0 -159
  141. package/src/viewer/components/UsageSection.tsx +0 -95
  142. package/src/viewer/components/VariantMatrix.tsx +0 -388
  143. package/src/viewer/components/VariantRenderer.tsx +0 -131
  144. package/src/viewer/components/VariantTabs.tsx +0 -40
  145. package/src/viewer/components/ViewerHeader.tsx +0 -69
  146. package/src/viewer/components/ViewerStateSync.tsx +0 -52
  147. package/src/viewer/components/ViewportSelector.tsx +0 -172
  148. package/src/viewer/components/WebMCPDevTools.tsx +0 -503
  149. package/src/viewer/components/WebMCPIntegration.tsx +0 -47
  150. package/src/viewer/components/WebMCPStatusIndicator.tsx +0 -60
  151. package/src/viewer/components/_future/CreatePage.tsx +0 -836
  152. package/src/viewer/components/viewer-utils.ts +0 -16
  153. package/src/viewer/composition-renderer.ts +0 -381
  154. package/src/viewer/constants/index.ts +0 -1
  155. package/src/viewer/constants/ui.ts +0 -166
  156. package/src/viewer/entry.tsx +0 -335
  157. package/src/viewer/hooks/index.ts +0 -2
  158. package/src/viewer/hooks/useA11yCache.ts +0 -383
  159. package/src/viewer/hooks/useA11yService.ts +0 -364
  160. package/src/viewer/hooks/useActions.ts +0 -138
  161. package/src/viewer/hooks/useAppState.ts +0 -147
  162. package/src/viewer/hooks/useCompiledFragments.ts +0 -42
  163. package/src/viewer/hooks/useFigmaIntegration.ts +0 -132
  164. package/src/viewer/hooks/useHmrStatus.ts +0 -109
  165. package/src/viewer/hooks/useKeyboardShortcuts.ts +0 -270
  166. package/src/viewer/hooks/usePreviewBridge.ts +0 -347
  167. package/src/viewer/hooks/useScrollSpy.ts +0 -78
  168. package/src/viewer/hooks/useUrlState.ts +0 -318
  169. package/src/viewer/hooks/useViewSettings.ts +0 -111
  170. package/src/viewer/index.html +0 -28
  171. package/src/viewer/intelligence/healthReport.ts +0 -505
  172. package/src/viewer/intelligence/styleDrift.ts +0 -340
  173. package/src/viewer/intelligence/usageScanner.ts +0 -309
  174. package/src/viewer/jsx-parser.ts +0 -486
  175. package/src/viewer/preview-frame-entry.tsx +0 -25
  176. package/src/viewer/preview-frame.html +0 -125
  177. package/src/viewer/public/favicon.ico +0 -0
  178. package/src/viewer/render-template.html +0 -68
  179. package/src/viewer/styles/globals.css +0 -278
  180. package/src/viewer/types/a11y.ts +0 -197
  181. package/src/viewer/utils/a11y-fixes.ts +0 -509
  182. package/src/viewer/utils/actionExport.ts +0 -372
  183. package/src/viewer/utils/colorSchemes.ts +0 -201
  184. package/src/viewer/utils/detectRelationships.ts +0 -256
  185. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +0 -10
  186. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +0 -2
  187. package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +0 -274
  188. package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +0 -129
  189. package/src/viewer/vendor/shared/src/DocsPageAsideHost.tsx +0 -89
  190. package/src/viewer/vendor/shared/src/DocsPageShell.tsx +0 -124
  191. package/src/viewer/vendor/shared/src/DocsSearchCommand.tsx +0 -99
  192. package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +0 -66
  193. package/src/viewer/vendor/shared/src/PropsTable.module.scss +0 -68
  194. package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +0 -2
  195. package/src/viewer/vendor/shared/src/PropsTable.tsx +0 -76
  196. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +0 -114
  197. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +0 -2
  198. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +0 -137
  199. package/src/viewer/vendor/shared/src/docs-data/index.ts +0 -32
  200. package/src/viewer/vendor/shared/src/docs-data/mcp-configs.ts +0 -72
  201. package/src/viewer/vendor/shared/src/docs-data/palettes.ts +0 -75
  202. package/src/viewer/vendor/shared/src/docs-data/setup-examples.ts +0 -55
  203. package/src/viewer/vendor/shared/src/docs-layout.scss +0 -28
  204. package/src/viewer/vendor/shared/src/docs-layout.scss.d.ts +0 -2
  205. package/src/viewer/vendor/shared/src/index.ts +0 -34
  206. package/src/viewer/vendor/shared/src/types.ts +0 -53
  207. package/src/viewer/webmcp/__tests__/analytics.test.ts +0 -108
  208. package/src/viewer/webmcp/analytics.ts +0 -165
  209. package/src/viewer/webmcp/index.ts +0 -3
  210. package/src/viewer/webmcp/posthog-bridge.ts +0 -39
  211. package/src/viewer/webmcp/runtime-tools.ts +0 -152
  212. package/src/viewer/webmcp/scan-utils.ts +0 -135
  213. package/src/viewer/webmcp/use-tool-analytics.ts +0 -69
  214. package/src/viewer/webmcp/viewer-state.ts +0 -45
  215. /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
  216. /package/dist/{chunk-PW7QTQA6.js.map → chunk-4OC7FTJB.js.map} +0 -0
  217. /package/dist/{chunk-HRFUSSZI.js.map → chunk-AM4MRTMN.js.map} +0 -0
  218. /package/dist/{scan-CJF2DOQW.js.map → discovery-ZJQSXF56.js.map} +0 -0
  219. /package/dist/{generate-FBHSXR3D.js.map → generate-RJFS2JWA.js.map} +0 -0
  220. /package/dist/{service-TQYWY65E.js.map → scan-3PMCJ4RB.js.map} +0 -0
  221. /package/dist/{static-viewer-NUBFPKWH.js.map → service-VMGNJZ42.js.map} +0 -0
  222. /package/dist/{test-Z5LVO724.js.map → test-SI4NSHQX.js.map} +0 -0
  223. /package/dist/{tokens-CE46OTMD.js.map → tokens-T6SIVUT5.js.map} +0 -0
@@ -1,10 +1,10 @@
1
1
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
2
  import {
3
3
  loadConfig
4
- } from "./chunk-HRFUSSZI.js";
4
+ } from "./chunk-AM4MRTMN.js";
5
5
  import {
6
6
  discoverAllComponents
7
- } from "./chunk-WXSR2II7.js";
7
+ } from "./chunk-OQKMEFOS.js";
8
8
  import {
9
9
  convertToFragmentProps,
10
10
  extractPropsFromFile,
@@ -14,10 +14,10 @@ import {
14
14
  inferAllRelations,
15
15
  parseAllStories,
16
16
  scanCodebase
17
- } from "./chunk-D5PYOXEI.js";
17
+ } from "./chunk-LVWFOLUZ.js";
18
18
  import {
19
19
  BRAND
20
- } from "./chunk-OQO55NKV.js";
20
+ } from "./chunk-WFS63PCW.js";
21
21
 
22
22
  // src/commands/scan.ts
23
23
  import { writeFile, mkdir } from "fs/promises";
@@ -27,6 +27,8 @@ async function scan(options = {}) {
27
27
  const startTime = Date.now();
28
28
  const errors = [];
29
29
  const warnings = [];
30
+ const log = options.quiet ? (() => {
31
+ }) : console.log.bind(console);
30
32
  let configDir;
31
33
  let outputFile;
32
34
  let componentPatterns;
@@ -40,18 +42,18 @@ async function scan(options = {}) {
40
42
  outputFile = options.output || "fragments.json";
41
43
  componentPatterns = options.componentPatterns;
42
44
  }
43
- console.log(pc.cyan(`
45
+ log(pc.cyan(`
44
46
  ${BRAND.name} Scan
45
47
  `));
46
- console.log(pc.dim("Zero-config fragments.json generation from source code\n"));
47
- console.log(pc.dim("Phase 1: Discovering components..."));
48
+ log(pc.dim("Zero-config fragments.json generation from source code\n"));
49
+ log(pc.dim("Phase 1: Discovering components..."));
48
50
  const components = await discoverAllComponents(configDir, {
49
51
  patterns: componentPatterns,
50
52
  exclude: ["**/*.test.*", "**/*.spec.*", "**/__tests__/**"],
51
53
  barrelFiles: options.barrelFiles
52
54
  });
53
55
  if (components.length === 0) {
54
- console.log(pc.yellow("No components found. Check your patterns or config."));
56
+ log(pc.yellow("No components found. Check your patterns or config."));
55
57
  return {
56
58
  success: false,
57
59
  outputPath: resolve(configDir, outputFile),
@@ -64,16 +66,16 @@ ${BRAND.name} Scan
64
66
  warnings: []
65
67
  };
66
68
  }
67
- console.log(pc.green(` Found ${components.length} components`));
69
+ log(pc.green(` Found ${components.length} components`));
68
70
  if (options.verbose) {
69
71
  for (const comp of components.slice(0, 10)) {
70
- console.log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));
72
+ log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));
71
73
  }
72
74
  if (components.length > 10) {
73
- console.log(pc.dim(` ... and ${components.length - 10} more`));
75
+ log(pc.dim(` ... and ${components.length - 10} more`));
74
76
  }
75
77
  }
76
- console.log(pc.dim("\nPhase 2: Extracting props from TypeScript..."));
78
+ log(pc.dim("\nPhase 2: Extracting props from TypeScript..."));
77
79
  const propsMap = /* @__PURE__ */ new Map();
78
80
  const propsResults = /* @__PURE__ */ new Map();
79
81
  let propsExtracted = 0;
@@ -96,12 +98,12 @@ ${BRAND.name} Scan
96
98
  }
97
99
  }
98
100
  }
99
- console.log(pc.green(` Extracted props for ${propsExtracted} components`));
101
+ log(pc.green(` Extracted props for ${propsExtracted} components`));
100
102
  let usageAnalysis;
101
103
  let usagesFound = 0;
102
104
  let allRelations = /* @__PURE__ */ new Map();
103
105
  if (!options.skipUsage) {
104
- console.log(pc.dim("\nPhase 3: Scanning for usage patterns..."));
106
+ log(pc.dim("\nPhase 3: Scanning for usage patterns..."));
105
107
  const usageDir = options.usageDir || configDir;
106
108
  try {
107
109
  const componentNames = components.map((c) => c.name);
@@ -123,22 +125,22 @@ ${BRAND.name} Scan
123
125
  0
124
126
  );
125
127
  allRelations = inferAllRelations(usageAnalysis);
126
- console.log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));
127
- console.log(pc.green(` Inferred relations for ${allRelations.size} components`));
128
+ log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));
129
+ log(pc.green(` Inferred relations for ${allRelations.size} components`));
128
130
  } catch (e) {
129
131
  warnings.push({
130
132
  component: "*",
131
133
  warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`
132
134
  });
133
- console.log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : "unknown error"}`));
135
+ log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : "unknown error"}`));
134
136
  }
135
137
  } else {
136
- console.log(pc.dim("\nPhase 3: Skipping usage analysis"));
138
+ log(pc.dim("\nPhase 3: Skipping usage analysis"));
137
139
  }
138
140
  const storiesMap = /* @__PURE__ */ new Map();
139
141
  let storiesParsed = 0;
140
142
  if (!options.skipStorybook) {
141
- console.log(pc.dim("\nPhase 4: Parsing Storybook stories..."));
143
+ log(pc.dim("\nPhase 4: Parsing Storybook stories..."));
142
144
  try {
143
145
  const allStories = await parseAllStories(configDir);
144
146
  for (const [name, stories] of Object.entries(allStories)) {
@@ -147,18 +149,18 @@ ${BRAND.name} Scan
147
149
  storiesParsed++;
148
150
  }
149
151
  }
150
- console.log(pc.green(` Parsed stories for ${storiesParsed} components`));
152
+ log(pc.green(` Parsed stories for ${storiesParsed} components`));
151
153
  } catch (e) {
152
154
  warnings.push({
153
155
  component: "*",
154
156
  warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`
155
157
  });
156
- console.log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : "unknown error"}`));
158
+ log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : "unknown error"}`));
157
159
  }
158
160
  } else {
159
- console.log(pc.dim("\nPhase 4: Skipping Storybook parsing"));
161
+ log(pc.dim("\nPhase 4: Skipping Storybook parsing"));
160
162
  }
161
- console.log(pc.dim("\nPhase 5: Generating fragments..."));
163
+ log(pc.dim("\nPhase 5: Generating fragments..."));
162
164
  const fragments = {};
163
165
  for (const comp of components) {
164
166
  try {
@@ -187,32 +189,32 @@ ${BRAND.name} Scan
187
189
  };
188
190
  await writeFile(outputPath, JSON.stringify(output, null, 2));
189
191
  const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
190
- console.log(pc.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
191
- console.log(pc.green(`
192
+ log(pc.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
193
+ log(pc.green(`
192
194
  \u2713 Generated fragments.json in ${elapsed}s`));
193
- console.log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));
194
- console.log(pc.dim(` Components: ${Object.keys(fragments).length}`));
195
- console.log(pc.dim(` Props extracted: ${propsExtracted}`));
196
- console.log(pc.dim(` Usages found: ${usagesFound}`));
197
- console.log(pc.dim(` Relations inferred: ${allRelations.size}`));
198
- console.log(pc.dim(` Stories parsed: ${storiesParsed}`));
195
+ log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));
196
+ log(pc.dim(` Components: ${Object.keys(fragments).length}`));
197
+ log(pc.dim(` Props extracted: ${propsExtracted}`));
198
+ log(pc.dim(` Usages found: ${usagesFound}`));
199
+ log(pc.dim(` Relations inferred: ${allRelations.size}`));
200
+ log(pc.dim(` Stories parsed: ${storiesParsed}`));
199
201
  if (warnings.length > 0) {
200
- console.log(pc.yellow(`
202
+ log(pc.yellow(`
201
203
  ${warnings.length} warning(s)`));
202
204
  if (options.verbose) {
203
205
  for (const w of warnings) {
204
- console.log(pc.dim(` ${w.component}: ${w.warning}`));
206
+ log(pc.dim(` ${w.component}: ${w.warning}`));
205
207
  }
206
208
  }
207
209
  }
208
210
  if (errors.length > 0) {
209
- console.log(pc.red(`
211
+ log(pc.red(`
210
212
  ${errors.length} error(s)`));
211
213
  for (const e of errors) {
212
- console.log(pc.dim(` ${e.component}: ${e.error}`));
214
+ log(pc.dim(` ${e.component}: ${e.error}`));
213
215
  }
214
216
  }
215
- console.log();
217
+ log();
216
218
  return {
217
219
  success: errors.length === 0,
218
220
  outputPath,
@@ -368,4 +370,4 @@ function calculateConfidence(props, usageAnalysis, storyFile) {
368
370
  export {
369
371
  scan
370
372
  };
371
- //# sourceMappingURL=chunk-ZM4ZQZWZ.js.map
373
+ //# sourceMappingURL=chunk-TPWGL2XS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/scan.ts"],"sourcesContent":["/**\n * fragments scan - Zero-config fragments.json generation from source code\n *\n * Automatically extracts component documentation by:\n * 1. Discovering components from source files and barrel exports\n * 2. Extracting props from TypeScript interfaces\n * 3. Scanning codebase for usage patterns\n * 4. Parsing Storybook stories for examples\n * 5. Inferring component relationships from usage data\n * 6. Generating complete fragments.json without manual documentation\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join, dirname, relative } from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n BRAND,\n type CompiledFragmentsFile,\n type CompiledFragment,\n type PropDefinition,\n} from \"../core/index.js\";\nimport {\n loadConfig,\n discoverAllComponents,\n type DiscoveredComponent,\n} from \"../core/node.js\";\nimport {\n scanCodebase,\n extractPropsFromFile,\n parseAllStories,\n inferAllRelations,\n generateComponentContext,\n generateEnhancementSuggestions,\n filterBoilerplate,\n convertToFragmentProps,\n type UsageAnalysis,\n type ComponentRelation,\n type PropsExtractionResult,\n type ParsedStoryFile,\n} from \"../service/index.js\";\n\nexport interface ScanOptions {\n /** Path to config file */\n config?: string;\n /** Output file path (default: fragments.json) */\n output?: string;\n /** Component patterns to scan */\n componentPatterns?: string[];\n /** Barrel export files to parse */\n barrelFiles?: string[];\n /** Directory to scan for usage patterns */\n usageDir?: string;\n /** Skip usage analysis */\n skipUsage?: boolean;\n /** Skip Storybook parsing */\n skipStorybook?: boolean;\n /** Verbose output */\n verbose?: boolean;\n /** Suppress all console output (for use as a sub-step) */\n quiet?: boolean;\n}\n\nexport interface ScanResult {\n success: boolean;\n outputPath: string;\n componentCount: number;\n propsExtracted: number;\n usagesFound: number;\n relationsInferred: number;\n storiesParsed: number;\n errors: Array<{ component: string; error: string }>;\n warnings: Array<{ component: string; warning: string }>;\n}\n\n/**\n * Scan codebase and generate fragments.json directly from source\n */\nexport async function scan(options: ScanOptions = {}): Promise<ScanResult> {\n const startTime = Date.now();\n const errors: Array<{ component: string; error: string }> = [];\n const warnings: Array<{ component: string; warning: string }> = [];\n\n // In quiet mode, suppress all console output\n const log = options.quiet ? (() => {}) : console.log.bind(console);\n\n // Load config or use defaults\n let configDir: string;\n let outputFile: string;\n let componentPatterns: string[] | undefined;\n\n try {\n const loaded = await loadConfig(options.config);\n configDir = loaded.configDir;\n outputFile = options.output || loaded.config.outFile || \"fragments.json\";\n componentPatterns = options.componentPatterns || loaded.config.components;\n } catch {\n // No config file, use defaults\n configDir = process.cwd();\n outputFile = options.output || \"fragments.json\";\n componentPatterns = options.componentPatterns;\n }\n\n log(pc.cyan(`\\n${BRAND.name} Scan\\n`));\n log(pc.dim(\"Zero-config fragments.json generation from source code\\n\"));\n\n // Phase 1: Discover components\n log(pc.dim(\"Phase 1: Discovering components...\"));\n const components = await discoverAllComponents(configDir, {\n patterns: componentPatterns,\n exclude: [\"**/*.test.*\", \"**/*.spec.*\", \"**/__tests__/**\"],\n barrelFiles: options.barrelFiles,\n });\n\n if (components.length === 0) {\n log(pc.yellow(\"No components found. Check your patterns or config.\"));\n return {\n success: false,\n outputPath: resolve(configDir, outputFile),\n componentCount: 0,\n propsExtracted: 0,\n usagesFound: 0,\n relationsInferred: 0,\n storiesParsed: 0,\n errors: [{ component: \"*\", error: \"No components found\" }],\n warnings: [],\n };\n }\n\n log(pc.green(` Found ${components.length} components`));\n if (options.verbose) {\n for (const comp of components.slice(0, 10)) {\n log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));\n }\n if (components.length > 10) {\n log(pc.dim(` ... and ${components.length - 10} more`));\n }\n }\n\n // Phase 2: Extract props from TypeScript\n log(pc.dim(\"\\nPhase 2: Extracting props from TypeScript...\"));\n const propsMap = new Map<string, ReturnType<typeof convertToFragmentProps>>();\n const propsResults = new Map<string, PropsExtractionResult>();\n let propsExtracted = 0;\n\n for (const comp of components) {\n try {\n const extraction = await extractPropsFromFile(comp.sourcePath, {\n propsTypeName: `${comp.name}Props`,\n });\n\n propsResults.set(comp.name, extraction);\n\n if (extraction.success && extraction.props.length > 0) {\n propsMap.set(comp.name, convertToFragmentProps(extraction.props));\n propsExtracted++;\n }\n } catch (e) {\n if (options.verbose) {\n warnings.push({\n component: comp.name,\n warning: `Props extraction failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n }\n\n log(pc.green(` Extracted props for ${propsExtracted} components`));\n\n // Phase 3: Scan for usage patterns\n let usageAnalysis: UsageAnalysis | undefined;\n let usagesFound = 0;\n let allRelations = new Map<string, ComponentRelation[]>();\n\n if (!options.skipUsage) {\n log(pc.dim(\"\\nPhase 3: Scanning for usage patterns...\"));\n const usageDir = options.usageDir || configDir;\n\n try {\n // Get component names for filtering\n const componentNames = components.map((c) => c.name);\n\n usageAnalysis = await scanCodebase({\n rootDir: usageDir,\n include: [\"**/*.tsx\", \"**/*.ts\", \"**/*.jsx\", \"**/*.js\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/*.stories.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n ],\n componentNames,\n useCache: true,\n });\n\n // Count total usages across all components\n usagesFound = Object.values(usageAnalysis.components).reduce(\n (sum, comp) => sum + comp.totalUsages,\n 0\n );\n\n // Infer relations\n allRelations = inferAllRelations(usageAnalysis);\n log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));\n log(pc.green(` Inferred relations for ${allRelations.size} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n log(pc.dim(\"\\nPhase 3: Skipping usage analysis\"));\n }\n\n // Phase 4: Parse Storybook stories\n const storiesMap = new Map<string, ParsedStoryFile>();\n let storiesParsed = 0;\n\n if (!options.skipStorybook) {\n log(pc.dim(\"\\nPhase 4: Parsing Storybook stories...\"));\n\n try {\n const allStories = await parseAllStories(configDir);\n\n for (const [name, stories] of Object.entries(allStories)) {\n if (stories && stories.stories.length > 0) {\n storiesMap.set(name, stories);\n storiesParsed++;\n }\n }\n\n log(pc.green(` Parsed stories for ${storiesParsed} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n log(pc.dim(\"\\nPhase 4: Skipping Storybook parsing\"));\n }\n\n // Phase 5: Generate fragments\n log(pc.dim(\"\\nPhase 5: Generating fragments...\"));\n const fragments: Record<string, CompiledFragment> = {};\n\n for (const comp of components) {\n try {\n const fragment = generateFragmentFromData(\n comp,\n configDir,\n propsMap.get(comp.name),\n usageAnalysis?.components[comp.name],\n allRelations.get(comp.name),\n storiesMap.get(comp.name)\n );\n\n fragments[comp.name] = fragment;\n } catch (e) {\n errors.push({\n component: comp.name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n // Write output\n const outputPath = resolve(configDir, outputFile);\n await mkdir(dirname(outputPath), { recursive: true });\n\n const output: CompiledFragmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n fragments,\n };\n\n await writeFile(outputPath, JSON.stringify(output, null, 2));\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n // Summary\n log(pc.dim(\"\\n────────────────────────────────────────\"));\n log(pc.green(`\\n✓ Generated fragments.json in ${elapsed}s`));\n log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));\n log(pc.dim(` Components: ${Object.keys(fragments).length}`));\n log(pc.dim(` Props extracted: ${propsExtracted}`));\n log(pc.dim(` Usages found: ${usagesFound}`));\n log(pc.dim(` Relations inferred: ${allRelations.size}`));\n log(pc.dim(` Stories parsed: ${storiesParsed}`));\n\n if (warnings.length > 0) {\n log(pc.yellow(`\\n ${warnings.length} warning(s)`));\n if (options.verbose) {\n for (const w of warnings) {\n log(pc.dim(` ${w.component}: ${w.warning}`));\n }\n }\n }\n\n if (errors.length > 0) {\n log(pc.red(`\\n ${errors.length} error(s)`));\n for (const e of errors) {\n log(pc.dim(` ${e.component}: ${e.error}`));\n }\n }\n\n log();\n\n return {\n success: errors.length === 0,\n outputPath,\n componentCount: Object.keys(fragments).length,\n propsExtracted,\n usagesFound,\n relationsInferred: allRelations.size,\n storiesParsed,\n errors,\n warnings,\n };\n}\n\n/**\n * Generate a CompiledFragment from extracted data\n */\nfunction generateFragmentFromData(\n comp: DiscoveredComponent,\n configDir: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n relations: ComponentRelation[] | undefined,\n storyFile: ParsedStoryFile | undefined\n): CompiledFragment {\n // Generate context for AI suggestions\n const context = generateComponentContext(\n comp.name,\n usageAnalysis,\n undefined, // No extracted docs yet\n storyFile,\n undefined, // No props extraction result (we have the converted props already)\n relations\n );\n\n // Generate enhancement suggestions from context\n const suggestions = generateEnhancementSuggestions(context);\n\n // Filter boilerplate from suggestions\n const when = filterBoilerplate(suggestions.suggestions.when);\n const whenNot = filterBoilerplate(suggestions.suggestions.whenNot);\n\n // Infer category from path\n const category = inferCategory(comp.relativePath);\n\n // Infer status from path\n const status = inferStatus(comp.relativePath);\n\n // Build variants from stories\n const variants: CompiledFragment[\"variants\"] = [];\n if (storyFile?.stories) {\n for (const story of storyFile.stories) {\n variants.push({\n name: story.name,\n description: story.description || `${story.displayName} variant`,\n code: story.code,\n });\n }\n }\n\n // Build relations\n const compiledRelations: CompiledFragment[\"relations\"] = [];\n if (relations && relations.length > 0) {\n for (const rel of relations.slice(0, 10)) {\n compiledRelations.push({\n component: rel.component,\n relationship: rel.relationship,\n note: `Appears together ${rel.frequency} times`,\n });\n }\n }\n\n // Generate description\n const description = generateDescription(comp.name, props, usageAnalysis);\n\n return {\n filePath: comp.relativePath,\n meta: {\n name: comp.name,\n description,\n category,\n status,\n },\n usage: {\n when: when.length > 0 ? when : [`Use ${comp.name} for its intended purpose`],\n whenNot: whenNot,\n },\n props: props || {},\n relations: compiledRelations.length > 0 ? compiledRelations : undefined,\n variants,\n _generated: {\n source: \"ai\",\n sourceFile: comp.relativePath,\n confidence: calculateConfidence(props, usageAnalysis, storyFile),\n timestamp: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Infer category from file path\n */\nfunction inferCategory(relativePath: string): string {\n const parts = relativePath.toLowerCase().split(\"/\");\n\n // Common category patterns\n const categoryPatterns: Record<string, string[]> = {\n \"Actions\": [\"button\", \"action\", \"cta\"],\n \"Forms\": [\"form\", \"input\", \"select\", \"checkbox\", \"radio\", \"textarea\", \"field\"],\n \"Layout\": [\"layout\", \"container\", \"grid\", \"flex\", \"stack\", \"box\", \"divider\", \"spacer\"],\n \"Navigation\": [\"nav\", \"menu\", \"breadcrumb\", \"tab\", \"link\", \"pagination\"],\n \"Feedback\": [\"alert\", \"toast\", \"notification\", \"message\", \"badge\", \"indicator\", \"progress\", \"spinner\", \"loading\"],\n \"Data Display\": [\"table\", \"list\", \"card\", \"avatar\", \"stat\", \"timeline\", \"tree\"],\n \"Overlays\": [\"modal\", \"dialog\", \"drawer\", \"popover\", \"tooltip\", \"dropdown\"],\n \"Typography\": [\"text\", \"heading\", \"title\", \"label\", \"paragraph\"],\n \"Media\": [\"image\", \"video\", \"icon\", \"avatar\"],\n };\n\n for (const [category, patterns] of Object.entries(categoryPatterns)) {\n for (const pattern of patterns) {\n if (parts.some((part) => part.includes(pattern))) {\n return category;\n }\n }\n }\n\n // Check path structure for category\n const componentIdx = parts.findIndex((p) => p === \"components\");\n if (componentIdx !== -1 && parts.length > componentIdx + 1) {\n const categoryPart = parts[componentIdx + 1];\n return categoryPart.charAt(0).toUpperCase() + categoryPart.slice(1);\n }\n\n return \"Components\";\n}\n\n/**\n * Infer status from file path\n */\nfunction inferStatus(\n relativePath: string\n): \"stable\" | \"beta\" | \"experimental\" | \"deprecated\" {\n const lowerPath = relativePath.toLowerCase();\n\n if (lowerPath.includes(\"/experimental/\") || lowerPath.includes(\"/labs/\")) {\n return \"experimental\";\n }\n if (lowerPath.includes(\"/beta/\")) {\n return \"beta\";\n }\n if (lowerPath.includes(\"/deprecated/\") || lowerPath.includes(\"/legacy/\")) {\n return \"deprecated\";\n }\n\n return \"stable\";\n}\n\n/**\n * Generate component description\n */\nfunction generateDescription(\n name: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined\n): string {\n // Convert name to readable form\n const words = name\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Check props for hints\n const hasOnClick = props && (\"onClick\" in props || \"onPress\" in props);\n const hasValue = props && (\"value\" in props || \"defaultValue\" in props);\n const hasChildren = props && \"children\" in props;\n const hasHref = props && \"href\" in props;\n\n // Check usage contexts\n const topContext = usageAnalysis?.contexts[0]?.type;\n\n if (hasHref) {\n return `Navigational ${words} for linking to other pages or resources`;\n }\n\n if (hasOnClick && !hasValue) {\n return `Interactive ${words} for triggering actions`;\n }\n\n if (hasValue) {\n return `Form ${words} for user input`;\n }\n\n if (topContext && topContext !== \"unknown\") {\n return `${words.charAt(0).toUpperCase() + words.slice(1)} commonly used in ${topContext} contexts`;\n }\n\n if (hasChildren) {\n return `Container ${words} for composing UI`;\n }\n\n return `${words.charAt(0).toUpperCase() + words.slice(1)} component`;\n}\n\n/**\n * Calculate confidence score based on available data\n */\nfunction calculateConfidence(\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n storyFile: ParsedStoryFile | undefined\n): number {\n let confidence = 0;\n\n // Props give +30 confidence\n if (props && Object.keys(props).length > 0) {\n confidence += 30;\n }\n\n // Usage data gives up to +40 confidence\n if (usageAnalysis) {\n if (usageAnalysis.totalUsages > 10) confidence += 40;\n else if (usageAnalysis.totalUsages > 5) confidence += 30;\n else if (usageAnalysis.totalUsages > 0) confidence += 20;\n }\n\n // Stories give +30 confidence\n if (storyFile && storyFile.stories.length > 0) {\n confidence += 30;\n }\n\n return Math.min(confidence, 100);\n}\n"],"mappings":"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","names":[]}
@@ -241,7 +241,13 @@ var fragmentContractSchema = z.object({
241
241
  a11yRules: z.array(z.string()).optional(),
242
242
  bans: z.array(fragmentBanSchema).optional(),
243
243
  scenarioTags: z.array(z.string()).optional(),
244
- performanceBudget: z.number().positive().optional()
244
+ performanceBudget: z.number().positive().optional(),
245
+ compoundChildren: z.record(z.object({
246
+ required: z.boolean().optional(),
247
+ accepts: z.array(z.string()).optional(),
248
+ description: z.string().optional()
249
+ })).optional(),
250
+ canonicalUsage: z.array(z.string()).optional()
245
251
  });
246
252
  var fragmentGeneratedSchema = z.object({
247
253
  source: z.enum(["storybook", "manual", "ai"]),
@@ -314,14 +320,76 @@ var fragmentsConfigSchema = z.object({
314
320
  excludeSubComponents: z.boolean().optional()
315
321
  }).optional()
316
322
  });
323
+ var compositionMetadataSchema = z.object({
324
+ pattern: z.enum(["compound", "simple", "controlled", "wrapper"]).optional(),
325
+ subComponents: z.array(z.string()).optional(),
326
+ requiredChildren: z.array(z.string()).optional(),
327
+ commonPatterns: z.array(z.string()).optional()
328
+ });
329
+ var fragmentProvenanceSchema = z.object({
330
+ source: z.enum(["storybook", "manual", "ai", "scan"]),
331
+ sourceFile: z.string().optional(),
332
+ confidence: z.number().min(0).max(1).optional(),
333
+ timestamp: z.string().datetime().optional(),
334
+ autoFields: z.array(z.string()).optional(),
335
+ humanFields: z.array(z.string()).optional()
336
+ });
337
+ var fragmentDefinitionV2Schema = z.object({
338
+ component: z.any(),
339
+ meta: fragmentMetaSchema,
340
+ guidance: fragmentUsageSchema,
341
+ props: z.record(propDefinitionSchema),
342
+ relations: z.array(componentRelationSchema).optional(),
343
+ examples: z.array(fragmentVariantSchema),
344
+ composition: compositionMetadataSchema.optional(),
345
+ contract: fragmentContractSchema.optional(),
346
+ _provenance: fragmentProvenanceSchema.optional()
347
+ });
317
348
  var recipeDefinitionSchema = blockDefinitionSchema;
349
+ function isV2Definition(def) {
350
+ return "guidance" in def || "examples" in def;
351
+ }
352
+ function normalizeToV1(def) {
353
+ let ai;
354
+ if (def.composition) {
355
+ ai = {
356
+ compositionPattern: def.composition.pattern,
357
+ subComponents: def.composition.subComponents,
358
+ requiredChildren: def.composition.requiredChildren,
359
+ commonPatterns: def.composition.commonPatterns
360
+ };
361
+ }
362
+ let generated;
363
+ if (def._provenance) {
364
+ generated = {
365
+ source: def._provenance.source === "scan" ? "ai" : def._provenance.source,
366
+ sourceFile: def._provenance.sourceFile,
367
+ confidence: def._provenance.confidence,
368
+ timestamp: def._provenance.timestamp
369
+ };
370
+ }
371
+ return {
372
+ component: def.component,
373
+ meta: def.meta,
374
+ usage: def.guidance,
375
+ props: def.props,
376
+ relations: def.relations,
377
+ variants: def.examples,
378
+ contract: def.contract,
379
+ ai,
380
+ _generated: generated
381
+ };
382
+ }
318
383
  function defineFragment(definition) {
319
384
  if (process.env.NODE_ENV !== "production") {
320
- const result = fragmentDefinitionSchema.safeParse(definition);
385
+ const v2 = isV2Definition(definition);
386
+ const schema = v2 ? fragmentDefinitionV2Schema : fragmentDefinitionSchema;
387
+ const result = schema.safeParse(definition);
321
388
  if (!result.success) {
389
+ const name = definition.meta?.name || "unknown";
322
390
  const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
323
391
  throw new Error(
324
- `Invalid fragment definition for "${definition.meta?.name || "unknown"}":
392
+ `Invalid fragment definition for "${name}":
325
393
  ${errors}`
326
394
  );
327
395
  }
@@ -329,20 +397,22 @@ ${errors}`
329
397
  return definition;
330
398
  }
331
399
  function compileFragment(definition, filePath) {
400
+ const v1 = isV2Definition(definition) ? normalizeToV1(definition) : definition;
332
401
  return {
333
402
  filePath,
334
- meta: definition.meta,
335
- usage: definition.usage,
336
- props: definition.props,
337
- relations: definition.relations,
338
- variants: definition.variants.map((v) => ({
403
+ meta: v1.meta,
404
+ usage: v1.usage,
405
+ props: v1.props,
406
+ relations: v1.relations,
407
+ variants: v1.variants.map((v) => ({
339
408
  name: v.name,
340
409
  description: v.description,
341
410
  code: v.code,
342
411
  figma: v.figma
343
412
  })),
344
- contract: definition.contract,
345
- _generated: definition._generated
413
+ contract: v1.contract,
414
+ ai: v1.ai,
415
+ _generated: v1._generated
346
416
  };
347
417
  }
348
418
  function defineBlock(definition) {
@@ -1379,7 +1449,11 @@ export {
1379
1449
  blockDefinitionSchema,
1380
1450
  fragmentDefinitionSchema,
1381
1451
  fragmentsConfigSchema,
1452
+ compositionMetadataSchema,
1453
+ fragmentProvenanceSchema,
1454
+ fragmentDefinitionV2Schema,
1382
1455
  recipeDefinitionSchema,
1456
+ normalizeToV1,
1383
1457
  defineFragment,
1384
1458
  compileFragment,
1385
1459
  defineBlock,
@@ -1407,4 +1481,4 @@ export {
1407
1481
  usePreviewVariantRuntime,
1408
1482
  PreviewVariantRuntime
1409
1483
  };
1410
- //# sourceMappingURL=chunk-OQO55NKV.js.map
1484
+ //# sourceMappingURL=chunk-WFS63PCW.js.map