@fragments-sdk/cli 0.2.2

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 (259) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/dist/bin.d.ts +1 -0
  4. package/dist/bin.js +4783 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/chunk-4FDQSGKX.js +786 -0
  7. package/dist/chunk-4FDQSGKX.js.map +1 -0
  8. package/dist/chunk-7H2MMGYG.js +369 -0
  9. package/dist/chunk-7H2MMGYG.js.map +1 -0
  10. package/dist/chunk-BSCG3IP7.js +619 -0
  11. package/dist/chunk-BSCG3IP7.js.map +1 -0
  12. package/dist/chunk-LY2CFFPY.js +898 -0
  13. package/dist/chunk-LY2CFFPY.js.map +1 -0
  14. package/dist/chunk-MUZ6CM66.js +6636 -0
  15. package/dist/chunk-MUZ6CM66.js.map +1 -0
  16. package/dist/chunk-OAENNG3G.js +1489 -0
  17. package/dist/chunk-OAENNG3G.js.map +1 -0
  18. package/dist/chunk-XHNKNI6J.js +235 -0
  19. package/dist/chunk-XHNKNI6J.js.map +1 -0
  20. package/dist/core-DWKLGY4N.js +68 -0
  21. package/dist/core-DWKLGY4N.js.map +1 -0
  22. package/dist/generate-4LQNJ7SX.js +249 -0
  23. package/dist/generate-4LQNJ7SX.js.map +1 -0
  24. package/dist/index.d.ts +775 -0
  25. package/dist/index.js +41 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/init-EMVI47QG.js +416 -0
  28. package/dist/init-EMVI47QG.js.map +1 -0
  29. package/dist/mcp-bin.d.ts +1 -0
  30. package/dist/mcp-bin.js +1117 -0
  31. package/dist/mcp-bin.js.map +1 -0
  32. package/dist/scan-4YPRF7FV.js +12 -0
  33. package/dist/scan-4YPRF7FV.js.map +1 -0
  34. package/dist/service-QSZMZJBJ.js +208 -0
  35. package/dist/service-QSZMZJBJ.js.map +1 -0
  36. package/dist/static-viewer-MIPGZ4Z7.js +12 -0
  37. package/dist/static-viewer-MIPGZ4Z7.js.map +1 -0
  38. package/dist/test-SQ5ZHXWU.js +1067 -0
  39. package/dist/test-SQ5ZHXWU.js.map +1 -0
  40. package/dist/tokens-HSGMYK64.js +173 -0
  41. package/dist/tokens-HSGMYK64.js.map +1 -0
  42. package/dist/viewer-YRF4SQE4.js +11101 -0
  43. package/dist/viewer-YRF4SQE4.js.map +1 -0
  44. package/package.json +107 -0
  45. package/src/ai.ts +266 -0
  46. package/src/analyze.ts +265 -0
  47. package/src/bin.ts +916 -0
  48. package/src/build.ts +248 -0
  49. package/src/commands/a11y.ts +302 -0
  50. package/src/commands/add.ts +313 -0
  51. package/src/commands/audit.ts +195 -0
  52. package/src/commands/baseline.ts +221 -0
  53. package/src/commands/build.ts +144 -0
  54. package/src/commands/compare.ts +337 -0
  55. package/src/commands/context.ts +107 -0
  56. package/src/commands/dev.ts +107 -0
  57. package/src/commands/enhance.ts +858 -0
  58. package/src/commands/generate.ts +391 -0
  59. package/src/commands/init.ts +531 -0
  60. package/src/commands/link/figma.ts +645 -0
  61. package/src/commands/link/index.ts +10 -0
  62. package/src/commands/link/storybook.ts +267 -0
  63. package/src/commands/list.ts +49 -0
  64. package/src/commands/metrics.ts +114 -0
  65. package/src/commands/reset.ts +242 -0
  66. package/src/commands/scan.ts +537 -0
  67. package/src/commands/storygen.ts +207 -0
  68. package/src/commands/tokens.ts +251 -0
  69. package/src/commands/validate.ts +93 -0
  70. package/src/commands/verify.ts +215 -0
  71. package/src/core/composition.test.ts +262 -0
  72. package/src/core/composition.ts +255 -0
  73. package/src/core/config.ts +84 -0
  74. package/src/core/constants.ts +111 -0
  75. package/src/core/context.ts +380 -0
  76. package/src/core/defineSegment.ts +137 -0
  77. package/src/core/discovery.ts +337 -0
  78. package/src/core/figma.ts +263 -0
  79. package/src/core/fragment-types.ts +214 -0
  80. package/src/core/generators/context.ts +389 -0
  81. package/src/core/generators/index.ts +23 -0
  82. package/src/core/generators/registry.ts +364 -0
  83. package/src/core/generators/typescript-extractor.ts +374 -0
  84. package/src/core/importAnalyzer.ts +217 -0
  85. package/src/core/index.ts +149 -0
  86. package/src/core/loader.ts +155 -0
  87. package/src/core/node.ts +63 -0
  88. package/src/core/parser.ts +551 -0
  89. package/src/core/previewLoader.ts +172 -0
  90. package/src/core/schema/fragment.schema.json +189 -0
  91. package/src/core/schema/registry.schema.json +137 -0
  92. package/src/core/schema.ts +182 -0
  93. package/src/core/storyAdapter.test.ts +571 -0
  94. package/src/core/storyAdapter.ts +761 -0
  95. package/src/core/token-types.ts +287 -0
  96. package/src/core/types.ts +754 -0
  97. package/src/diff.ts +323 -0
  98. package/src/index.ts +43 -0
  99. package/src/mcp/__tests__/projectFields.test.ts +130 -0
  100. package/src/mcp/bin.ts +36 -0
  101. package/src/mcp/index.ts +8 -0
  102. package/src/mcp/server.ts +1310 -0
  103. package/src/mcp/utils.ts +54 -0
  104. package/src/mcp-bin.ts +36 -0
  105. package/src/migrate/__tests__/argTypes/argTypes.test.ts +189 -0
  106. package/src/migrate/__tests__/args/args.test.ts +452 -0
  107. package/src/migrate/__tests__/meta/meta.test.ts +198 -0
  108. package/src/migrate/__tests__/stories/stories.test.ts +278 -0
  109. package/src/migrate/__tests__/utils/utils.test.ts +371 -0
  110. package/src/migrate/__tests__/values/values.test.ts +303 -0
  111. package/src/migrate/bin.ts +108 -0
  112. package/src/migrate/converter.ts +658 -0
  113. package/src/migrate/detect.ts +196 -0
  114. package/src/migrate/index.ts +45 -0
  115. package/src/migrate/migrate.ts +163 -0
  116. package/src/migrate/parser.ts +1136 -0
  117. package/src/migrate/report.ts +624 -0
  118. package/src/migrate/types.ts +169 -0
  119. package/src/screenshot.ts +249 -0
  120. package/src/service/__tests__/ast-utils.test.ts +426 -0
  121. package/src/service/__tests__/enhance-scanner.test.ts +200 -0
  122. package/src/service/__tests__/figma/figma.test.ts +652 -0
  123. package/src/service/__tests__/metrics-store.test.ts +409 -0
  124. package/src/service/__tests__/patch-generator.test.ts +186 -0
  125. package/src/service/__tests__/props-extractor.test.ts +365 -0
  126. package/src/service/__tests__/token-registry.test.ts +267 -0
  127. package/src/service/analytics.ts +659 -0
  128. package/src/service/ast-utils.ts +444 -0
  129. package/src/service/browser-pool.ts +339 -0
  130. package/src/service/capture.ts +267 -0
  131. package/src/service/diff.ts +279 -0
  132. package/src/service/enhance/aggregator.ts +489 -0
  133. package/src/service/enhance/cache.ts +275 -0
  134. package/src/service/enhance/codebase-scanner.ts +357 -0
  135. package/src/service/enhance/context-generator.ts +529 -0
  136. package/src/service/enhance/doc-extractor.ts +523 -0
  137. package/src/service/enhance/index.ts +131 -0
  138. package/src/service/enhance/props-extractor.ts +665 -0
  139. package/src/service/enhance/scanner.ts +445 -0
  140. package/src/service/enhance/storybook-parser.ts +552 -0
  141. package/src/service/enhance/types.ts +346 -0
  142. package/src/service/enhance/variant-renderer.ts +479 -0
  143. package/src/service/figma.ts +1008 -0
  144. package/src/service/index.ts +249 -0
  145. package/src/service/metrics-store.ts +333 -0
  146. package/src/service/patch-generator.ts +349 -0
  147. package/src/service/report.ts +854 -0
  148. package/src/service/storage.ts +401 -0
  149. package/src/service/token-fixes.ts +281 -0
  150. package/src/service/token-parser.ts +504 -0
  151. package/src/service/token-registry.ts +721 -0
  152. package/src/service/utils.ts +172 -0
  153. package/src/setup.ts +241 -0
  154. package/src/shared/command-wrapper.ts +81 -0
  155. package/src/shared/dev-server-client.ts +199 -0
  156. package/src/shared/index.ts +8 -0
  157. package/src/shared/segment-loader.ts +59 -0
  158. package/src/shared/types.ts +147 -0
  159. package/src/static-viewer.ts +715 -0
  160. package/src/test/discovery.ts +172 -0
  161. package/src/test/index.ts +281 -0
  162. package/src/test/reporters/console.ts +194 -0
  163. package/src/test/reporters/json.ts +190 -0
  164. package/src/test/reporters/junit.ts +186 -0
  165. package/src/test/runner.ts +598 -0
  166. package/src/test/types.ts +245 -0
  167. package/src/test/watch.ts +200 -0
  168. package/src/validators.ts +152 -0
  169. package/src/viewer/__tests__/jsx-parser.test.ts +502 -0
  170. package/src/viewer/__tests__/render-utils.test.ts +232 -0
  171. package/src/viewer/__tests__/style-utils.test.ts +404 -0
  172. package/src/viewer/bin.ts +86 -0
  173. package/src/viewer/cli/health.ts +256 -0
  174. package/src/viewer/cli/index.ts +33 -0
  175. package/src/viewer/cli/scan.ts +124 -0
  176. package/src/viewer/cli/utils.ts +174 -0
  177. package/src/viewer/components/AccessibilityPanel.tsx +1404 -0
  178. package/src/viewer/components/ActionCapture.tsx +172 -0
  179. package/src/viewer/components/ActionsPanel.tsx +371 -0
  180. package/src/viewer/components/App.tsx +638 -0
  181. package/src/viewer/components/BottomPanel.tsx +224 -0
  182. package/src/viewer/components/CodePanel.tsx +589 -0
  183. package/src/viewer/components/CommandPalette.tsx +336 -0
  184. package/src/viewer/components/ComponentGraph.tsx +394 -0
  185. package/src/viewer/components/ComponentHeader.tsx +85 -0
  186. package/src/viewer/components/ContractPanel.tsx +234 -0
  187. package/src/viewer/components/ErrorBoundary.tsx +85 -0
  188. package/src/viewer/components/FigmaEmbed.tsx +231 -0
  189. package/src/viewer/components/FragmentEditor.tsx +485 -0
  190. package/src/viewer/components/HealthDashboard.tsx +452 -0
  191. package/src/viewer/components/HmrStatusIndicator.tsx +71 -0
  192. package/src/viewer/components/Icons.tsx +417 -0
  193. package/src/viewer/components/InteractionsPanel.tsx +720 -0
  194. package/src/viewer/components/IsolatedPreviewFrame.tsx +321 -0
  195. package/src/viewer/components/IsolatedRender.tsx +111 -0
  196. package/src/viewer/components/KeyboardShortcutsHelp.tsx +89 -0
  197. package/src/viewer/components/LandingPage.tsx +441 -0
  198. package/src/viewer/components/Layout.tsx +22 -0
  199. package/src/viewer/components/LeftSidebar.tsx +391 -0
  200. package/src/viewer/components/MultiViewportPreview.tsx +429 -0
  201. package/src/viewer/components/PreviewArea.tsx +404 -0
  202. package/src/viewer/components/PreviewFrameHost.tsx +310 -0
  203. package/src/viewer/components/PreviewPane.tsx +150 -0
  204. package/src/viewer/components/PreviewToolbar.tsx +176 -0
  205. package/src/viewer/components/PropsEditor.tsx +512 -0
  206. package/src/viewer/components/PropsTable.tsx +98 -0
  207. package/src/viewer/components/RelationsSection.tsx +57 -0
  208. package/src/viewer/components/ResizablePanel.tsx +328 -0
  209. package/src/viewer/components/RightSidebar.tsx +118 -0
  210. package/src/viewer/components/ScreenshotButton.tsx +90 -0
  211. package/src/viewer/components/Sidebar.tsx +169 -0
  212. package/src/viewer/components/SkeletonLoader.tsx +156 -0
  213. package/src/viewer/components/StoryRenderer.tsx +128 -0
  214. package/src/viewer/components/ThemeProvider.tsx +96 -0
  215. package/src/viewer/components/Toast.tsx +67 -0
  216. package/src/viewer/components/TokenStylePanel.tsx +708 -0
  217. package/src/viewer/components/UsageSection.tsx +95 -0
  218. package/src/viewer/components/VariantMatrix.tsx +350 -0
  219. package/src/viewer/components/VariantRenderer.tsx +131 -0
  220. package/src/viewer/components/VariantTabs.tsx +84 -0
  221. package/src/viewer/components/ViewportSelector.tsx +165 -0
  222. package/src/viewer/components/_future/CreatePage.tsx +836 -0
  223. package/src/viewer/composition-renderer.ts +381 -0
  224. package/src/viewer/constants/index.ts +1 -0
  225. package/src/viewer/constants/ui.ts +185 -0
  226. package/src/viewer/entry.tsx +299 -0
  227. package/src/viewer/hooks/index.ts +2 -0
  228. package/src/viewer/hooks/useA11yCache.ts +383 -0
  229. package/src/viewer/hooks/useA11yService.ts +498 -0
  230. package/src/viewer/hooks/useActions.ts +138 -0
  231. package/src/viewer/hooks/useAppState.ts +124 -0
  232. package/src/viewer/hooks/useFigmaIntegration.ts +132 -0
  233. package/src/viewer/hooks/useHmrStatus.ts +109 -0
  234. package/src/viewer/hooks/useKeyboardShortcuts.ts +222 -0
  235. package/src/viewer/hooks/usePreviewBridge.ts +347 -0
  236. package/src/viewer/hooks/useScrollSpy.ts +78 -0
  237. package/src/viewer/hooks/useUrlState.ts +330 -0
  238. package/src/viewer/hooks/useViewSettings.ts +125 -0
  239. package/src/viewer/index.html +28 -0
  240. package/src/viewer/index.ts +14 -0
  241. package/src/viewer/intelligence/healthReport.ts +505 -0
  242. package/src/viewer/intelligence/styleDrift.ts +340 -0
  243. package/src/viewer/intelligence/usageScanner.ts +309 -0
  244. package/src/viewer/jsx-parser.ts +485 -0
  245. package/src/viewer/postcss.config.js +6 -0
  246. package/src/viewer/preview-frame-entry.tsx +25 -0
  247. package/src/viewer/preview-frame.html +109 -0
  248. package/src/viewer/render-template.html +68 -0
  249. package/src/viewer/render-utils.ts +170 -0
  250. package/src/viewer/server.ts +276 -0
  251. package/src/viewer/style-utils.ts +414 -0
  252. package/src/viewer/styles/globals.css +355 -0
  253. package/src/viewer/tailwind.config.js +37 -0
  254. package/src/viewer/types/a11y.ts +197 -0
  255. package/src/viewer/utils/a11y-fixes.ts +471 -0
  256. package/src/viewer/utils/actionExport.ts +372 -0
  257. package/src/viewer/utils/colorSchemes.ts +201 -0
  258. package/src/viewer/utils/detectRelationships.ts +256 -0
  259. package/src/viewer/vite-plugin.ts +2143 -0
@@ -0,0 +1,1489 @@
1
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ BRAND,
4
+ segmentsConfigSchema
5
+ } from "./chunk-XHNKNI6J.js";
6
+
7
+ // src/core/config.ts
8
+ import { existsSync } from "fs";
9
+ import { resolve, dirname } from "path";
10
+ import { createJiti } from "jiti";
11
+ var DEFAULT_CONFIG = {
12
+ include: [
13
+ `src/**/*${BRAND.fileExtension}`,
14
+ // *.segment.tsx files
15
+ "src/**/*.stories.tsx"
16
+ // Storybook stories (auto-converted)
17
+ ],
18
+ exclude: ["**/node_modules/**"],
19
+ components: ["src/**/index.tsx", "src/**/*.tsx"],
20
+ framework: "react"
21
+ };
22
+ function findConfigFile(startDir = process.cwd()) {
23
+ let currentDir = startDir;
24
+ while (currentDir !== dirname(currentDir)) {
25
+ const configPath = resolve(currentDir, BRAND.configFile);
26
+ if (existsSync(configPath)) {
27
+ return configPath;
28
+ }
29
+ const legacyConfigPath = resolve(currentDir, BRAND.legacyConfigFile);
30
+ if (existsSync(legacyConfigPath)) {
31
+ return legacyConfigPath;
32
+ }
33
+ currentDir = dirname(currentDir);
34
+ }
35
+ return null;
36
+ }
37
+ async function loadConfig(configPath) {
38
+ const resolvedPath = configPath ?? findConfigFile();
39
+ if (!resolvedPath) {
40
+ return {
41
+ config: DEFAULT_CONFIG,
42
+ configDir: process.cwd()
43
+ };
44
+ }
45
+ try {
46
+ const jiti = createJiti(import.meta.url, {
47
+ interopDefault: true
48
+ });
49
+ const rawConfig = await jiti.import(resolvedPath);
50
+ const result = segmentsConfigSchema.safeParse(rawConfig);
51
+ if (!result.success) {
52
+ const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
53
+ throw new Error(`Invalid config in ${resolvedPath}:
54
+ ${errors}`);
55
+ }
56
+ return {
57
+ config: { ...DEFAULT_CONFIG, ...result.data },
58
+ configDir: dirname(resolvedPath)
59
+ };
60
+ } catch (error) {
61
+ if (error instanceof Error && error.message.includes("Invalid config")) {
62
+ throw error;
63
+ }
64
+ throw new Error(`Failed to load config from ${resolvedPath}: ${error}`);
65
+ }
66
+ }
67
+
68
+ // src/core/discovery.ts
69
+ import { resolve as resolve2, dirname as dirname2 } from "path";
70
+ import { readFile } from "fs/promises";
71
+ import { existsSync as existsSync2 } from "fs";
72
+ import fg from "fast-glob";
73
+ async function discoverRecipeFiles(configDir, exclude) {
74
+ const pattern = `**/*${BRAND.recipeFileExtension}`;
75
+ const files = await fg(pattern, {
76
+ cwd: configDir,
77
+ ignore: exclude ?? ["**/node_modules/**", "**/dist/**"],
78
+ absolute: false
79
+ });
80
+ return files.map((relativePath) => ({
81
+ relativePath,
82
+ absolutePath: resolve2(configDir, relativePath)
83
+ }));
84
+ }
85
+ async function discoverSegmentFiles(config, configDir) {
86
+ const files = await fg(config.include, {
87
+ cwd: configDir,
88
+ ignore: config.exclude ?? [],
89
+ absolute: false
90
+ });
91
+ return files.map((relativePath) => ({
92
+ relativePath,
93
+ absolutePath: resolve2(configDir, relativePath)
94
+ }));
95
+ }
96
+ async function discoverComponentFiles(config, configDir) {
97
+ if (!config.components || config.components.length === 0) {
98
+ return [];
99
+ }
100
+ const files = await fg(config.components, {
101
+ cwd: configDir,
102
+ ignore: [
103
+ ...config.exclude ?? [],
104
+ // Exclude segment files themselves
105
+ ...config.include,
106
+ // Exclude test files
107
+ "**/*.test.*",
108
+ "**/*.spec.*",
109
+ "**/__tests__/**"
110
+ ],
111
+ absolute: false
112
+ });
113
+ return files.map((relativePath) => ({
114
+ relativePath,
115
+ absolutePath: resolve2(configDir, relativePath)
116
+ }));
117
+ }
118
+ function extractComponentName(filePath) {
119
+ const parts = filePath.replace(/\\/g, "/").split("/");
120
+ const fileName = parts[parts.length - 1];
121
+ if (fileName === "index.tsx" || fileName === "index.ts") {
122
+ return parts[parts.length - 2] ?? "Unknown";
123
+ }
124
+ return fileName.replace(/\.(tsx?|jsx?)$/, "");
125
+ }
126
+ var DEFAULT_COMPONENT_PATTERNS = [
127
+ "src/components/**/*.tsx",
128
+ "src/components/**/index.tsx",
129
+ "components/**/*.tsx",
130
+ "lib/components/**/*.tsx",
131
+ "packages/*/src/components/**/*.tsx"
132
+ ];
133
+ var DEFAULT_EXCLUDE_PATTERNS = [
134
+ "**/*.test.*",
135
+ "**/*.spec.*",
136
+ "**/*.stories.*",
137
+ "**/*.story.*",
138
+ "**/__tests__/**",
139
+ "**/__mocks__/**",
140
+ "**/node_modules/**",
141
+ "**/dist/**"
142
+ ];
143
+ async function discoverComponentsFromSource(configDir, patterns, exclude) {
144
+ const searchPatterns = patterns && patterns.length > 0 ? patterns : DEFAULT_COMPONENT_PATTERNS;
145
+ const excludePatterns = [
146
+ ...DEFAULT_EXCLUDE_PATTERNS,
147
+ ...exclude ?? []
148
+ ];
149
+ const files = await fg(searchPatterns, {
150
+ cwd: configDir,
151
+ ignore: excludePatterns,
152
+ absolute: false
153
+ });
154
+ const componentFiles = files.filter((file) => {
155
+ const name = extractComponentName(file);
156
+ return /^[A-Z]/.test(name);
157
+ });
158
+ const storyPatterns = [
159
+ "**/*.stories.tsx",
160
+ "**/*.stories.ts",
161
+ "**/*.story.tsx",
162
+ "**/*.story.ts"
163
+ ];
164
+ const storyFiles = await fg(storyPatterns, {
165
+ cwd: configDir,
166
+ ignore: ["**/node_modules/**", "**/dist/**"],
167
+ absolute: false
168
+ });
169
+ const storyMap = /* @__PURE__ */ new Map();
170
+ for (const storyFile of storyFiles) {
171
+ const name = extractComponentName(storyFile.replace(/\.stories?\.(tsx?|jsx?)$/, ".tsx"));
172
+ storyMap.set(name, storyFile);
173
+ }
174
+ const components = [];
175
+ for (const file of componentFiles) {
176
+ const name = extractComponentName(file);
177
+ const absolutePath = resolve2(configDir, file);
178
+ const storyFile = storyMap.get(name);
179
+ components.push({
180
+ name,
181
+ sourcePath: absolutePath,
182
+ relativePath: file,
183
+ storyPath: storyFile ? resolve2(configDir, storyFile) : void 0
184
+ });
185
+ }
186
+ components.sort((a, b) => a.name.localeCompare(b.name));
187
+ return components;
188
+ }
189
+ async function discoverComponentsFromBarrel(barrelPath, configDir) {
190
+ const absoluteBarrelPath = resolve2(configDir, barrelPath);
191
+ if (!existsSync2(absoluteBarrelPath)) {
192
+ return [];
193
+ }
194
+ const content = await readFile(absoluteBarrelPath, "utf-8");
195
+ const components = [];
196
+ const exportRegex = /export\s+(?:\*|{([^}]+)})\s+from\s+['"]([^'"]+)['"]/g;
197
+ let match;
198
+ while ((match = exportRegex.exec(content)) !== null) {
199
+ const exportedNames = match[1];
200
+ const importPath = match[2];
201
+ const barrelDir = dirname2(absoluteBarrelPath);
202
+ let resolvedPath = resolve2(barrelDir, importPath);
203
+ if (!resolvedPath.endsWith(".tsx") && !resolvedPath.endsWith(".ts")) {
204
+ if (existsSync2(`${resolvedPath}.tsx`)) {
205
+ resolvedPath = `${resolvedPath}.tsx`;
206
+ } else if (existsSync2(`${resolvedPath}.ts`)) {
207
+ resolvedPath = `${resolvedPath}.ts`;
208
+ } else if (existsSync2(`${resolvedPath}/index.tsx`)) {
209
+ resolvedPath = `${resolvedPath}/index.tsx`;
210
+ } else if (existsSync2(`${resolvedPath}/index.ts`)) {
211
+ resolvedPath = `${resolvedPath}/index.ts`;
212
+ }
213
+ }
214
+ if (!existsSync2(resolvedPath)) {
215
+ continue;
216
+ }
217
+ if (exportedNames) {
218
+ const names = exportedNames.split(",").map((n) => n.trim().split(/\s+as\s+/)[0].trim());
219
+ for (const name of names) {
220
+ if (/^[A-Z]/.test(name)) {
221
+ const relativePath = resolvedPath.replace(configDir + "/", "");
222
+ components.push({
223
+ name,
224
+ sourcePath: resolvedPath,
225
+ relativePath
226
+ });
227
+ }
228
+ }
229
+ } else {
230
+ const name = extractComponentName(importPath);
231
+ if (/^[A-Z]/.test(name)) {
232
+ const relativePath = resolvedPath.replace(configDir + "/", "");
233
+ components.push({
234
+ name,
235
+ sourcePath: resolvedPath,
236
+ relativePath
237
+ });
238
+ }
239
+ }
240
+ }
241
+ return components;
242
+ }
243
+ async function discoverAllComponents(configDir, options = {}) {
244
+ const componentsMap = /* @__PURE__ */ new Map();
245
+ const sourceComponents = await discoverComponentsFromSource(
246
+ configDir,
247
+ options.patterns,
248
+ options.exclude
249
+ );
250
+ for (const comp of sourceComponents) {
251
+ componentsMap.set(comp.name, comp);
252
+ }
253
+ if (options.barrelFiles && options.barrelFiles.length > 0) {
254
+ for (const barrelFile of options.barrelFiles) {
255
+ const barrelComponents = await discoverComponentsFromBarrel(barrelFile, configDir);
256
+ for (const comp of barrelComponents) {
257
+ if (!componentsMap.has(comp.name)) {
258
+ componentsMap.set(comp.name, comp);
259
+ }
260
+ }
261
+ }
262
+ }
263
+ return Array.from(componentsMap.values()).sort((a, b) => a.name.localeCompare(b.name));
264
+ }
265
+
266
+ // src/core/generators/typescript-extractor.ts
267
+ import ts from "typescript";
268
+ import { readFileSync } from "fs";
269
+ function extractPropsFromFile(filePath) {
270
+ const sourceText = readFileSync(filePath, "utf-8");
271
+ return extractPropsFromSource(sourceText, filePath);
272
+ }
273
+ function extractPropsFromSource(sourceText, fileName = "component.tsx") {
274
+ const sourceFile = ts.createSourceFile(
275
+ fileName,
276
+ sourceText,
277
+ ts.ScriptTarget.Latest,
278
+ true,
279
+ fileName.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS
280
+ );
281
+ const result = {
282
+ componentName: "",
283
+ props: {},
284
+ exports: [],
285
+ imports: []
286
+ };
287
+ const propsInterfaces = /* @__PURE__ */ new Map();
288
+ const componentExports = [];
289
+ const importedModules = [];
290
+ ts.forEachChild(sourceFile, (node) => {
291
+ if (ts.isImportDeclaration(node)) {
292
+ const moduleSpecifier = node.moduleSpecifier;
293
+ if (ts.isStringLiteral(moduleSpecifier)) {
294
+ importedModules.push(moduleSpecifier.text);
295
+ }
296
+ }
297
+ if (ts.isInterfaceDeclaration(node)) {
298
+ const name = node.name.text;
299
+ if (name.endsWith("Props")) {
300
+ propsInterfaces.set(name, node);
301
+ }
302
+ }
303
+ if (ts.isTypeAliasDeclaration(node)) {
304
+ const name = node.name.text;
305
+ if (name.endsWith("Props")) {
306
+ propsInterfaces.set(name, node);
307
+ }
308
+ }
309
+ if (ts.isFunctionDeclaration(node) && node.name) {
310
+ const hasExport = node.modifiers?.some(
311
+ (m) => m.kind === ts.SyntaxKind.ExportKeyword
312
+ );
313
+ if (hasExport) {
314
+ componentExports.push(node.name.text);
315
+ }
316
+ }
317
+ if (ts.isVariableStatement(node)) {
318
+ const hasExport = node.modifiers?.some(
319
+ (m) => m.kind === ts.SyntaxKind.ExportKeyword
320
+ );
321
+ if (hasExport) {
322
+ for (const decl of node.declarationList.declarations) {
323
+ if (ts.isIdentifier(decl.name)) {
324
+ componentExports.push(decl.name.text);
325
+ }
326
+ }
327
+ }
328
+ }
329
+ if (ts.isExportDeclaration(node) && node.exportClause) {
330
+ if (ts.isNamedExports(node.exportClause)) {
331
+ for (const element of node.exportClause.elements) {
332
+ componentExports.push(element.name.text);
333
+ }
334
+ }
335
+ }
336
+ });
337
+ result.exports = componentExports;
338
+ result.imports = importedModules;
339
+ const mainComponent = componentExports.find(
340
+ (name) => /^[A-Z]/.test(name) && !name.endsWith("Props")
341
+ );
342
+ if (!mainComponent) {
343
+ return null;
344
+ }
345
+ result.componentName = mainComponent;
346
+ const propsInterfaceName = `${mainComponent}Props`;
347
+ const propsInterface = propsInterfaces.get(propsInterfaceName);
348
+ if (propsInterface) {
349
+ result.propsInterfaceName = propsInterfaceName;
350
+ result.props = extractPropsFromInterface(propsInterface, sourceFile);
351
+ }
352
+ return result;
353
+ }
354
+ function extractPropsFromInterface(node, sourceFile) {
355
+ const props = {};
356
+ if (ts.isInterfaceDeclaration(node)) {
357
+ for (const member of node.members) {
358
+ if (ts.isPropertySignature(member) && member.name) {
359
+ const propName = member.name.getText(sourceFile);
360
+ const prop = extractPropFromMember(member, sourceFile);
361
+ if (prop) {
362
+ props[propName] = prop;
363
+ }
364
+ }
365
+ }
366
+ }
367
+ if (ts.isTypeAliasDeclaration(node)) {
368
+ const typeNode = node.type;
369
+ if (ts.isTypeLiteralNode(typeNode)) {
370
+ for (const member of typeNode.members) {
371
+ if (ts.isPropertySignature(member) && member.name) {
372
+ const propName = member.name.getText(sourceFile);
373
+ const prop = extractPropFromMember(member, sourceFile);
374
+ if (prop) {
375
+ props[propName] = prop;
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ return props;
382
+ }
383
+ function extractPropFromMember(member, sourceFile) {
384
+ const entry = {};
385
+ entry.required = !member.questionToken;
386
+ if (member.type) {
387
+ const typeInfo = parseTypeNode(member.type, sourceFile);
388
+ entry.type = typeInfo.type;
389
+ entry.typeKind = typeInfo.typeKind;
390
+ if (typeInfo.options) {
391
+ entry.options = typeInfo.options;
392
+ }
393
+ }
394
+ const jsDocComment = getJSDocComment(member);
395
+ if (jsDocComment) {
396
+ entry.description = jsDocComment;
397
+ }
398
+ const defaultValue = getJSDocDefault(member);
399
+ if (defaultValue !== void 0) {
400
+ entry.default = defaultValue;
401
+ }
402
+ return entry;
403
+ }
404
+ function parseTypeNode(typeNode, sourceFile) {
405
+ if (typeNode.kind === ts.SyntaxKind.StringKeyword) {
406
+ return { type: "string", typeKind: "string" };
407
+ }
408
+ if (typeNode.kind === ts.SyntaxKind.NumberKeyword) {
409
+ return { type: "number", typeKind: "number" };
410
+ }
411
+ if (typeNode.kind === ts.SyntaxKind.BooleanKeyword) {
412
+ return { type: "boolean", typeKind: "boolean" };
413
+ }
414
+ if (ts.isUnionTypeNode(typeNode)) {
415
+ const options = [];
416
+ let allLiterals = true;
417
+ for (const subType of typeNode.types) {
418
+ if (ts.isLiteralTypeNode(subType)) {
419
+ if (ts.isStringLiteral(subType.literal)) {
420
+ options.push(subType.literal.text);
421
+ } else if (subType.literal.kind === ts.SyntaxKind.TrueKeyword) {
422
+ options.push("true");
423
+ } else if (subType.literal.kind === ts.SyntaxKind.FalseKeyword) {
424
+ options.push("false");
425
+ } else {
426
+ allLiterals = false;
427
+ }
428
+ } else {
429
+ allLiterals = false;
430
+ }
431
+ }
432
+ if (allLiterals && options.length > 0) {
433
+ return {
434
+ type: options.map((o) => `"${o}"`).join(" | "),
435
+ typeKind: "enum",
436
+ options
437
+ };
438
+ }
439
+ return {
440
+ type: typeNode.getText(sourceFile),
441
+ typeKind: "union"
442
+ };
443
+ }
444
+ if (ts.isFunctionTypeNode(typeNode)) {
445
+ return {
446
+ type: typeNode.getText(sourceFile),
447
+ typeKind: "function"
448
+ };
449
+ }
450
+ if (ts.isArrayTypeNode(typeNode)) {
451
+ return {
452
+ type: typeNode.getText(sourceFile),
453
+ typeKind: "array"
454
+ };
455
+ }
456
+ if (ts.isTypeReferenceNode(typeNode)) {
457
+ const typeName = typeNode.typeName.getText(sourceFile);
458
+ if (typeName === "ReactNode" || typeName === "React.ReactNode") {
459
+ return { type: "ReactNode", typeKind: "node" };
460
+ }
461
+ if (typeName === "ReactElement" || typeName === "React.ReactElement") {
462
+ return { type: "ReactElement", typeKind: "element" };
463
+ }
464
+ if (typeName === "JSX.Element") {
465
+ return { type: "JSX.Element", typeKind: "element" };
466
+ }
467
+ return {
468
+ type: typeNode.getText(sourceFile),
469
+ typeKind: "object"
470
+ };
471
+ }
472
+ if (ts.isTypeLiteralNode(typeNode)) {
473
+ return {
474
+ type: typeNode.getText(sourceFile),
475
+ typeKind: "object"
476
+ };
477
+ }
478
+ return {
479
+ type: typeNode.getText(sourceFile),
480
+ typeKind: "unknown"
481
+ };
482
+ }
483
+ function getJSDocComment(node) {
484
+ const jsDocTags = ts.getJSDocTags(node);
485
+ const jsDoc = node.jsDoc;
486
+ if (jsDoc && jsDoc.length > 0) {
487
+ const comment = jsDoc[0].comment;
488
+ if (typeof comment === "string") {
489
+ return comment;
490
+ }
491
+ if (Array.isArray(comment)) {
492
+ return comment.map((c) => typeof c === "string" ? c : c.text).join("");
493
+ }
494
+ }
495
+ return void 0;
496
+ }
497
+ function getJSDocDefault(node) {
498
+ const jsDocTags = ts.getJSDocTags(node);
499
+ for (const tag of jsDocTags) {
500
+ if (tag.tagName.text === "default") {
501
+ const comment = tag.comment;
502
+ if (typeof comment === "string") {
503
+ try {
504
+ return JSON.parse(comment);
505
+ } catch {
506
+ return comment;
507
+ }
508
+ }
509
+ }
510
+ }
511
+ return void 0;
512
+ }
513
+
514
+ // src/core/generators/registry.ts
515
+ import { readFileSync as readFileSync2 } from "fs";
516
+ import { relative, dirname as dirname3, basename as basename2, join } from "path";
517
+ import fg2 from "fast-glob";
518
+ async function generateRegistry(options) {
519
+ const {
520
+ projectRoot,
521
+ componentPatterns = ["src/**/*.tsx", "src/**/*.ts"],
522
+ storyPatterns = ["src/**/*.stories.tsx", "src/**/*.stories.ts"],
523
+ fragmentsDir = join(projectRoot, BRAND.dataDir),
524
+ registryOptions = {}
525
+ } = options;
526
+ const {
527
+ requireStory = false,
528
+ publicOnly = false,
529
+ categoryDepth = 1,
530
+ includeProps = false,
531
+ embedFragments = false
532
+ } = registryOptions;
533
+ const errors = [];
534
+ const warnings = [];
535
+ const storyFiles = await fg2(storyPatterns, {
536
+ cwd: projectRoot,
537
+ ignore: ["**/node_modules/**"],
538
+ absolute: true
539
+ });
540
+ const storyMap = /* @__PURE__ */ new Map();
541
+ for (const storyPath of storyFiles) {
542
+ const storyDir = dirname3(storyPath);
543
+ const storyBase = basename2(storyPath).replace(/\.stories\.(tsx?|jsx?)$/, "");
544
+ storyMap.set(`${storyDir}/${storyBase}`, storyPath);
545
+ }
546
+ const componentFiles = await fg2(componentPatterns, {
547
+ cwd: projectRoot,
548
+ ignore: [
549
+ "**/node_modules/**",
550
+ "**/*.stories.*",
551
+ "**/*.test.*",
552
+ "**/*.spec.*",
553
+ "**/*.d.ts"
554
+ ],
555
+ absolute: true
556
+ });
557
+ const fragmentPattern = join(
558
+ BRAND.dataDir,
559
+ BRAND.componentsDir,
560
+ `*${BRAND.fileExtension}`
561
+ );
562
+ const fragmentFiles = await fg2(fragmentPattern, {
563
+ cwd: projectRoot,
564
+ absolute: true
565
+ });
566
+ const fragmentMap = /* @__PURE__ */ new Map();
567
+ for (const fragmentPath of fragmentFiles) {
568
+ const fragmentName = basename2(fragmentPath).replace(BRAND.fileExtension, "");
569
+ try {
570
+ const content = readFileSync2(fragmentPath, "utf-8");
571
+ const fragment = JSON.parse(content);
572
+ fragmentMap.set(fragmentName, {
573
+ path: relative(projectRoot, fragmentPath),
574
+ fragment
575
+ });
576
+ } catch (e) {
577
+ errors.push({
578
+ file: fragmentPath,
579
+ error: `Failed to parse fragment: ${e instanceof Error ? e.message : String(e)}`
580
+ });
581
+ }
582
+ }
583
+ const components = {};
584
+ const indexComponents = {};
585
+ const categories = {};
586
+ for (const filePath of componentFiles) {
587
+ try {
588
+ const extracted = extractPropsFromFile(filePath);
589
+ if (!extracted || !extracted.componentName) {
590
+ continue;
591
+ }
592
+ const componentName = extracted.componentName;
593
+ const relativePath = relative(projectRoot, filePath);
594
+ if (publicOnly && !extracted.exports.includes(componentName)) {
595
+ continue;
596
+ }
597
+ const componentDir = dirname3(filePath);
598
+ const baseNameWithoutExt = basename2(filePath).replace(/\.(tsx?|jsx?)$/, "");
599
+ const storyPath = storyMap.get(`${componentDir}/${baseNameWithoutExt}`);
600
+ if (requireStory && !storyPath) {
601
+ continue;
602
+ }
603
+ const fragmentData = fragmentMap.get(componentName);
604
+ const category = fragmentData?.fragment?.meta?.status ? void 0 : getCategoryFromPath(relativePath, categoryDepth);
605
+ const hasEnrichment = fragmentData ? hasRealEnrichment(fragmentData.fragment) : false;
606
+ const entry = {
607
+ path: relativePath
608
+ };
609
+ if (storyPath) {
610
+ entry.storyPath = relative(projectRoot, storyPath);
611
+ }
612
+ if (fragmentData) {
613
+ entry.fragmentPath = fragmentData.path;
614
+ if (hasEnrichment) {
615
+ entry.hasEnrichment = true;
616
+ }
617
+ if (fragmentData.fragment.description) {
618
+ entry.description = fragmentData.fragment.description;
619
+ }
620
+ if (fragmentData.fragment.meta?.status) {
621
+ entry.status = fragmentData.fragment.meta.status;
622
+ }
623
+ if (embedFragments) {
624
+ entry.fragment = fragmentData.fragment;
625
+ }
626
+ }
627
+ if (category) {
628
+ entry.category = category;
629
+ if (!categories[category]) {
630
+ categories[category] = [];
631
+ }
632
+ categories[category].push(componentName);
633
+ }
634
+ if (includeProps && extracted.props) {
635
+ entry.props = extracted.props;
636
+ }
637
+ if (extracted.exports.length > 1) {
638
+ entry.exports = extracted.exports;
639
+ }
640
+ components[componentName] = entry;
641
+ indexComponents[componentName] = relativePath;
642
+ } catch (e) {
643
+ errors.push({
644
+ file: filePath,
645
+ error: `Failed to extract component: ${e instanceof Error ? e.message : String(e)}`
646
+ });
647
+ }
648
+ }
649
+ const componentCount = Object.keys(components).length;
650
+ const registry = {
651
+ $schema: "https://fragments.dev/schema/registry-v1.json",
652
+ version: "1.0",
653
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
654
+ componentCount,
655
+ components,
656
+ categories
657
+ };
658
+ const index = {
659
+ version: "1.0",
660
+ generatedAt: registry.generatedAt,
661
+ components: indexComponents,
662
+ categories
663
+ };
664
+ return { registry, index, errors, warnings };
665
+ }
666
+ function getCategoryFromPath(relativePath, depth = 1) {
667
+ const parts = relativePath.split("/");
668
+ const componentsIndex = parts.findIndex((p) => p === "components");
669
+ if (componentsIndex === -1) {
670
+ return void 0;
671
+ }
672
+ const afterComponents = parts.slice(componentsIndex + 1);
673
+ if (afterComponents.length <= 1) {
674
+ return void 0;
675
+ }
676
+ const folderName = afterComponents[0];
677
+ const fileName = afterComponents[afterComponents.length - 1].replace(/\.(tsx?|jsx?)$/, "");
678
+ if (afterComponents.length === 2 && folderName === fileName) {
679
+ return void 0;
680
+ }
681
+ const categoryParts = afterComponents.slice(0, Math.min(depth, afterComponents.length - 1));
682
+ const lastCategoryPart = categoryParts[categoryParts.length - 1];
683
+ if (lastCategoryPart === fileName) {
684
+ categoryParts.pop();
685
+ }
686
+ if (categoryParts.length === 0) {
687
+ return void 0;
688
+ }
689
+ return categoryParts.join("/");
690
+ }
691
+ function hasRealEnrichment(fragment) {
692
+ if (fragment.description && fragment.description.length > 20) {
693
+ return true;
694
+ }
695
+ if (fragment.usage?.when && fragment.usage.when.length > 0) {
696
+ return true;
697
+ }
698
+ if (fragment.usage?.doNot && fragment.usage.doNot.length > 0) {
699
+ return true;
700
+ }
701
+ if (fragment.usage?.patterns && fragment.usage.patterns.length > 0) {
702
+ return true;
703
+ }
704
+ if (fragment.accessibility?.requirements && fragment.accessibility.requirements.length > 0) {
705
+ return true;
706
+ }
707
+ if (fragment.figma?.nodeId || fragment.figma?.variants) {
708
+ return true;
709
+ }
710
+ if (fragment.related?.similar && fragment.related.similar.length > 0) {
711
+ return true;
712
+ }
713
+ return false;
714
+ }
715
+
716
+ // src/core/generators/context.ts
717
+ function generateContextMd(registry, options = {}) {
718
+ const {
719
+ format = "markdown",
720
+ compact = false,
721
+ include = { props: true, relations: true, code: false }
722
+ } = options;
723
+ if (format === "json") {
724
+ return generateJsonContext(registry, include, compact);
725
+ }
726
+ return generateMarkdownContext(registry, include, compact);
727
+ }
728
+ function generateMarkdownContext(registry, include, compact) {
729
+ const lines = [];
730
+ const componentNames = Object.keys(registry.components).sort();
731
+ const componentCount = componentNames.length;
732
+ lines.push("# Component Library Context");
733
+ lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]} | Components: ${componentCount}`);
734
+ lines.push("");
735
+ lines.push("## Quick Reference");
736
+ lines.push("");
737
+ lines.push("| Component | Path | Category | Status |");
738
+ lines.push("|-----------|------|----------|--------|");
739
+ for (const name of componentNames) {
740
+ const entry = registry.components[name];
741
+ const status = entry.status || "stable";
742
+ const category = entry.category || "-";
743
+ lines.push(`| ${name} | ${entry.path} | ${category} | ${status} |`);
744
+ }
745
+ lines.push("");
746
+ if (compact) {
747
+ const content2 = lines.join("\n");
748
+ return {
749
+ content: content2,
750
+ tokenEstimate: estimateTokens(content2),
751
+ componentCount
752
+ };
753
+ }
754
+ lines.push("---");
755
+ lines.push("");
756
+ for (const name of componentNames) {
757
+ const entry = registry.components[name];
758
+ const fragment = entry.fragment;
759
+ lines.push(`## ${name}`);
760
+ lines.push(`**Path:** \`${entry.path}\``);
761
+ if (entry.category) {
762
+ lines.push(`**Category:** ${entry.category} | **Status:** ${entry.status || "stable"}`);
763
+ }
764
+ lines.push("");
765
+ if (entry.description || fragment?.description) {
766
+ lines.push("### Description");
767
+ lines.push(entry.description || fragment?.description || "");
768
+ lines.push("");
769
+ }
770
+ if (fragment?.usage) {
771
+ if (fragment.usage.when && fragment.usage.when.length > 0) {
772
+ lines.push("### When to Use");
773
+ for (const when of fragment.usage.when) {
774
+ lines.push(`- ${when}`);
775
+ }
776
+ lines.push("");
777
+ }
778
+ if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {
779
+ lines.push("### Do Not");
780
+ for (const doNotItem of fragment.usage.doNot) {
781
+ if (typeof doNotItem === "string") {
782
+ lines.push(`- ${doNotItem}`);
783
+ } else {
784
+ const item = doNotItem;
785
+ if (item.instead) {
786
+ const alternativePath = resolveComponentPath(item.instead, registry);
787
+ if (alternativePath) {
788
+ lines.push(`- ${item.text} \u2192 use **${item.instead}** (\`${alternativePath}\`)`);
789
+ } else {
790
+ lines.push(`- ${item.text} \u2192 use **${item.instead}**`);
791
+ }
792
+ } else {
793
+ lines.push(`- ${item.text}`);
794
+ }
795
+ }
796
+ }
797
+ lines.push("");
798
+ }
799
+ if (include.code && fragment.usage.patterns && fragment.usage.patterns.length > 0) {
800
+ lines.push("### Patterns");
801
+ for (const pattern of fragment.usage.patterns) {
802
+ lines.push(`**${pattern.name}**`);
803
+ if (pattern.description) {
804
+ lines.push(pattern.description);
805
+ }
806
+ lines.push("```tsx");
807
+ lines.push(pattern.code);
808
+ lines.push("```");
809
+ lines.push("");
810
+ }
811
+ }
812
+ }
813
+ if (include.props && entry.props && Object.keys(entry.props).length > 0) {
814
+ lines.push("### Props");
815
+ lines.push("| Prop | Type | Default | Description |");
816
+ lines.push("|------|------|---------|-------------|");
817
+ for (const [propName, prop] of Object.entries(entry.props)) {
818
+ const type = formatPropType(prop);
819
+ const defaultVal = prop.default !== void 0 ? `\`${JSON.stringify(prop.default)}\`` : "-";
820
+ const desc = prop.description || "-";
821
+ const required = prop.required ? " (required)" : "";
822
+ lines.push(`| ${propName}${required} | ${type} | ${defaultVal} | ${desc} |`);
823
+ }
824
+ lines.push("");
825
+ }
826
+ if (fragment?.accessibility) {
827
+ lines.push("### Accessibility");
828
+ if (fragment.accessibility.role) {
829
+ lines.push(`**Role:** ${fragment.accessibility.role}`);
830
+ }
831
+ if (fragment.accessibility.requirements && fragment.accessibility.requirements.length > 0) {
832
+ for (const req of fragment.accessibility.requirements) {
833
+ lines.push(`- ${req}`);
834
+ }
835
+ }
836
+ if (fragment.accessibility.keyboard) {
837
+ lines.push("");
838
+ lines.push("**Keyboard:**");
839
+ for (const [key, action] of Object.entries(fragment.accessibility.keyboard)) {
840
+ lines.push(`- \`${key}\`: ${action}`);
841
+ }
842
+ }
843
+ lines.push("");
844
+ }
845
+ if (include.relations && fragment?.related) {
846
+ lines.push("### Related");
847
+ if (fragment.related.similar && fragment.related.similar.length > 0) {
848
+ const resolved = fragment.related.similar.map((comp) => {
849
+ const path = resolveComponentPath(comp, registry);
850
+ return path ? `${comp} (\`${path}\`)` : comp;
851
+ });
852
+ lines.push(`- **Similar:** ${resolved.join(", ")}`);
853
+ }
854
+ if (fragment.related.composedWith && fragment.related.composedWith.length > 0) {
855
+ const resolved = fragment.related.composedWith.map((comp) => {
856
+ const path = resolveComponentPath(comp, registry);
857
+ return path ? `${comp} (\`${path}\`)` : comp;
858
+ });
859
+ lines.push(`- **Composed with:** ${resolved.join(", ")}`);
860
+ }
861
+ if (fragment.related.usedIn && fragment.related.usedIn.length > 0) {
862
+ const resolved = fragment.related.usedIn.map((comp) => {
863
+ const path = resolveComponentPath(comp, registry);
864
+ return path ? `${comp} (\`${path}\`)` : comp;
865
+ });
866
+ lines.push(`- **Used in:** ${resolved.join(", ")}`);
867
+ }
868
+ lines.push("");
869
+ }
870
+ lines.push("---");
871
+ lines.push("");
872
+ }
873
+ const content = lines.join("\n");
874
+ return {
875
+ content,
876
+ tokenEstimate: estimateTokens(content),
877
+ componentCount
878
+ };
879
+ }
880
+ function generateJsonContext(registry, include, compact) {
881
+ const componentNames = Object.keys(registry.components).sort();
882
+ const componentCount = componentNames.length;
883
+ const components = {};
884
+ for (const name of componentNames) {
885
+ const entry = registry.components[name];
886
+ const fragment = entry.fragment;
887
+ const component = {
888
+ path: entry.path
889
+ };
890
+ if (entry.category) component.category = entry.category;
891
+ if (entry.status) component.status = entry.status;
892
+ if (entry.description || fragment?.description) {
893
+ component.description = entry.description || fragment?.description;
894
+ }
895
+ if (!compact && fragment?.usage) {
896
+ if (fragment.usage.when && fragment.usage.when.length > 0) {
897
+ component.whenToUse = fragment.usage.when;
898
+ }
899
+ if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {
900
+ component.doNot = fragment.usage.doNot.map((item) => {
901
+ if (typeof item === "string") {
902
+ return { text: item };
903
+ }
904
+ const doNotItem = item;
905
+ const result = {
906
+ text: doNotItem.text
907
+ };
908
+ if (doNotItem.instead) {
909
+ result.instead = doNotItem.instead;
910
+ result.insteadPath = resolveComponentPath(doNotItem.instead, registry);
911
+ }
912
+ return result;
913
+ });
914
+ }
915
+ }
916
+ if (!compact && include.props && entry.props) {
917
+ component.props = {};
918
+ for (const [propName, prop] of Object.entries(entry.props)) {
919
+ component.props[propName] = {
920
+ type: formatPropType(prop)
921
+ };
922
+ if (prop.required) component.props[propName].required = true;
923
+ if (prop.default !== void 0) component.props[propName].default = prop.default;
924
+ if (prop.description) component.props[propName].description = prop.description;
925
+ }
926
+ }
927
+ if (!compact && include.relations && fragment?.related) {
928
+ component.related = {};
929
+ if (fragment.related.similar) {
930
+ component.related.similar = fragment.related.similar.map((name2) => ({
931
+ name: name2,
932
+ path: resolveComponentPath(name2, registry)
933
+ }));
934
+ }
935
+ if (fragment.related.composedWith) {
936
+ component.related.composedWith = fragment.related.composedWith.map((name2) => ({
937
+ name: name2,
938
+ path: resolveComponentPath(name2, registry)
939
+ }));
940
+ }
941
+ if (fragment.related.usedIn) {
942
+ component.related.usedIn = fragment.related.usedIn.map((name2) => ({
943
+ name: name2,
944
+ path: resolveComponentPath(name2, registry)
945
+ }));
946
+ }
947
+ }
948
+ components[name] = component;
949
+ }
950
+ const output = {
951
+ version: "1.0",
952
+ generatedAt: registry.generatedAt,
953
+ componentCount,
954
+ categories: registry.categories,
955
+ components
956
+ };
957
+ const content = JSON.stringify(output, null, 2);
958
+ return {
959
+ content,
960
+ tokenEstimate: estimateTokens(content),
961
+ componentCount
962
+ };
963
+ }
964
+ function resolveComponentPath(componentName, registry) {
965
+ return registry.components[componentName]?.path;
966
+ }
967
+ function formatPropType(prop) {
968
+ if (prop.options && prop.options.length > 0) {
969
+ return prop.options.map((o) => `"${o}"`).join(" \\| ");
970
+ }
971
+ return prop.type || "unknown";
972
+ }
973
+ function estimateTokens(text) {
974
+ return Math.ceil(text.length / 4);
975
+ }
976
+
977
+ // src/core/loader.ts
978
+ import { unlink } from "fs/promises";
979
+ import { dirname as dirname4, basename as basename3, join as join2 } from "path";
980
+ import { pathToFileURL } from "url";
981
+ import { build } from "esbuild";
982
+ var DEFINE_SEGMENT_SHIM = `
983
+ export function defineSegment(def) {
984
+ return def;
985
+ }
986
+ export function defineFragment(def) {
987
+ return def;
988
+ }
989
+ export function defineRecipe(def) {
990
+ return def;
991
+ }
992
+ `;
993
+ function createSegmentsCoreShimPlugin() {
994
+ return {
995
+ name: BRAND.vitePluginNamespace,
996
+ setup(build2) {
997
+ build2.onResolve({ filter: /^@fragments\/core$/ }, (args) => {
998
+ return {
999
+ path: args.path,
1000
+ namespace: BRAND.vitePluginNamespace
1001
+ };
1002
+ });
1003
+ build2.onLoad({ filter: /.*/, namespace: BRAND.vitePluginNamespace }, () => {
1004
+ return {
1005
+ contents: DEFINE_SEGMENT_SHIM,
1006
+ loader: "js"
1007
+ };
1008
+ });
1009
+ }
1010
+ };
1011
+ }
1012
+ async function loadSegmentFile(absolutePath) {
1013
+ const ext = absolutePath.split(".").pop()?.toLowerCase();
1014
+ const needsTransform = ext === "tsx" || ext === "ts" || ext === "jsx";
1015
+ if (!needsTransform) {
1016
+ const fileUrl = pathToFileURL(absolutePath).href;
1017
+ const module = await import(fileUrl);
1018
+ return module.default ?? null;
1019
+ }
1020
+ const sourceDir = dirname4(absolutePath);
1021
+ const baseName = basename3(absolutePath, `.${ext}`);
1022
+ const tempFile = join2(sourceDir, `.${baseName}.segments-temp-${Date.now()}.cjs`);
1023
+ try {
1024
+ await build({
1025
+ entryPoints: [absolutePath],
1026
+ outfile: tempFile,
1027
+ bundle: true,
1028
+ format: "cjs",
1029
+ // Use CommonJS to avoid ESM issues with lodash, etc.
1030
+ target: "es2022",
1031
+ jsx: "automatic",
1032
+ platform: "node",
1033
+ plugins: [createSegmentsCoreShimPlugin()],
1034
+ // Externalize all node_modules - we only need segment metadata, not component code
1035
+ packages: "external",
1036
+ // Also explicitly list patterns for nested imports
1037
+ external: [
1038
+ // React and its subpaths
1039
+ "react",
1040
+ "react-dom",
1041
+ "react/*",
1042
+ "react-dom/*"
1043
+ ],
1044
+ // Don't emit sourcemaps for temp files
1045
+ sourcemap: false,
1046
+ // Suppress warnings
1047
+ logLevel: "silent",
1048
+ // Use loader to ignore style imports
1049
+ loader: {
1050
+ ".scss": "empty",
1051
+ ".css": "empty",
1052
+ ".svg": "empty",
1053
+ ".png": "empty",
1054
+ ".jpg": "empty",
1055
+ ".jpeg": "empty",
1056
+ ".gif": "empty",
1057
+ ".woff": "empty",
1058
+ ".woff2": "empty",
1059
+ ".ttf": "empty",
1060
+ ".eot": "empty"
1061
+ }
1062
+ });
1063
+ const fileUrl = pathToFileURL(tempFile).href;
1064
+ const module = await import(fileUrl);
1065
+ return module.default ?? null;
1066
+ } finally {
1067
+ try {
1068
+ await unlink(tempFile);
1069
+ } catch {
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ // src/core/parser.ts
1075
+ import ts2 from "typescript";
1076
+ function parseSegmentFile(fileContent, filePath) {
1077
+ const warnings = [];
1078
+ const sourceFile = ts2.createSourceFile(
1079
+ filePath ?? "segment.tsx",
1080
+ fileContent,
1081
+ ts2.ScriptTarget.Latest,
1082
+ true,
1083
+ ts2.ScriptKind.TSX
1084
+ );
1085
+ const imports = extractImports(sourceFile);
1086
+ const defineSegmentCall = findDefineSegmentCall(sourceFile);
1087
+ if (!defineSegmentCall) {
1088
+ warnings.push("No defineSegment() call found");
1089
+ return {
1090
+ componentImport: null,
1091
+ componentName: null,
1092
+ meta: {},
1093
+ usage: { when: [], whenNot: [] },
1094
+ props: {},
1095
+ variants: [],
1096
+ relations: [],
1097
+ warnings
1098
+ };
1099
+ }
1100
+ const arg = defineSegmentCall.arguments[0];
1101
+ if (!arg || !ts2.isObjectLiteralExpression(arg)) {
1102
+ warnings.push("defineSegment() argument is not an object literal");
1103
+ return {
1104
+ componentImport: null,
1105
+ componentName: null,
1106
+ meta: {},
1107
+ usage: { when: [], whenNot: [] },
1108
+ props: {},
1109
+ variants: [],
1110
+ relations: [],
1111
+ warnings
1112
+ };
1113
+ }
1114
+ const componentProp = findProperty(arg, "component");
1115
+ let componentName = null;
1116
+ let componentImport = null;
1117
+ if (componentProp && ts2.isIdentifier(componentProp)) {
1118
+ componentName = componentProp.text;
1119
+ componentImport = imports.get(componentName) ?? null;
1120
+ }
1121
+ const meta = extractMeta(arg, warnings);
1122
+ const usage = extractUsage(arg, warnings);
1123
+ const props = extractProps(arg, warnings);
1124
+ const variants = extractVariants(arg, sourceFile, warnings);
1125
+ const relations = extractRelations(arg, warnings);
1126
+ return {
1127
+ componentImport,
1128
+ componentName,
1129
+ meta,
1130
+ usage,
1131
+ props,
1132
+ variants,
1133
+ relations,
1134
+ warnings
1135
+ };
1136
+ }
1137
+ function extractImports(sourceFile) {
1138
+ const imports = /* @__PURE__ */ new Map();
1139
+ ts2.forEachChild(sourceFile, (node) => {
1140
+ if (ts2.isImportDeclaration(node)) {
1141
+ const moduleSpecifier = node.moduleSpecifier;
1142
+ if (ts2.isStringLiteral(moduleSpecifier)) {
1143
+ const modulePath = moduleSpecifier.text;
1144
+ const importClause = node.importClause;
1145
+ if (importClause) {
1146
+ if (importClause.name) {
1147
+ imports.set(importClause.name.text, modulePath);
1148
+ }
1149
+ const namedBindings = importClause.namedBindings;
1150
+ if (namedBindings && ts2.isNamedImports(namedBindings)) {
1151
+ for (const element of namedBindings.elements) {
1152
+ imports.set(element.name.text, modulePath);
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ }
1158
+ });
1159
+ return imports;
1160
+ }
1161
+ function findDefineSegmentCall(sourceFile) {
1162
+ let result = null;
1163
+ function visit(node) {
1164
+ if (ts2.isCallExpression(node)) {
1165
+ const expression = node.expression;
1166
+ if (ts2.isIdentifier(expression) && expression.text === "defineSegment") {
1167
+ result = node;
1168
+ return;
1169
+ }
1170
+ }
1171
+ ts2.forEachChild(node, visit);
1172
+ }
1173
+ visit(sourceFile);
1174
+ return result;
1175
+ }
1176
+ function findProperty(obj, name) {
1177
+ for (const prop of obj.properties) {
1178
+ if (ts2.isPropertyAssignment(prop)) {
1179
+ const propName = prop.name;
1180
+ if (ts2.isIdentifier(propName) && propName.text === name) {
1181
+ return prop.initializer;
1182
+ }
1183
+ }
1184
+ }
1185
+ return null;
1186
+ }
1187
+ function extractMeta(arg, warnings) {
1188
+ const metaProp = findProperty(arg, "meta");
1189
+ if (!metaProp || !ts2.isObjectLiteralExpression(metaProp)) {
1190
+ warnings.push("No meta object found");
1191
+ return {};
1192
+ }
1193
+ const meta = {};
1194
+ const name = extractStringProperty(metaProp, "name");
1195
+ if (name) meta.name = name;
1196
+ const description = extractStringProperty(metaProp, "description");
1197
+ if (description) meta.description = description;
1198
+ const category = extractStringProperty(metaProp, "category");
1199
+ if (category) meta.category = category;
1200
+ const status = extractStringProperty(metaProp, "status");
1201
+ if (status) meta.status = status;
1202
+ const since = extractStringProperty(metaProp, "since");
1203
+ if (since) meta.since = since;
1204
+ const figma = extractStringProperty(metaProp, "figma");
1205
+ if (figma) meta.figma = figma;
1206
+ const tags = extractStringArray(metaProp, "tags");
1207
+ if (tags.length > 0) meta.tags = tags;
1208
+ return meta;
1209
+ }
1210
+ function extractUsage(arg, warnings) {
1211
+ const usageProp = findProperty(arg, "usage");
1212
+ if (!usageProp || !ts2.isObjectLiteralExpression(usageProp)) {
1213
+ return { when: [], whenNot: [] };
1214
+ }
1215
+ return {
1216
+ when: extractStringArray(usageProp, "when"),
1217
+ whenNot: extractStringArray(usageProp, "whenNot"),
1218
+ guidelines: extractStringArray(usageProp, "guidelines"),
1219
+ accessibility: extractStringArray(usageProp, "accessibility")
1220
+ };
1221
+ }
1222
+ function extractProps(arg, warnings) {
1223
+ const propsProp = findProperty(arg, "props");
1224
+ if (!propsProp || !ts2.isObjectLiteralExpression(propsProp)) {
1225
+ return {};
1226
+ }
1227
+ const props = {};
1228
+ for (const prop of propsProp.properties) {
1229
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
1230
+ const propName = prop.name.text;
1231
+ const propValue = prop.initializer;
1232
+ if (ts2.isObjectLiteralExpression(propValue)) {
1233
+ props[propName] = extractPropDefinition(propValue);
1234
+ }
1235
+ }
1236
+ }
1237
+ return props;
1238
+ }
1239
+ function extractPropDefinition(obj) {
1240
+ const def = {};
1241
+ const type = extractStringProperty(obj, "type");
1242
+ if (type) def.type = type;
1243
+ const description = extractStringProperty(obj, "description");
1244
+ if (description) def.description = description;
1245
+ const values = extractStringArray(obj, "values");
1246
+ if (values.length > 0) def.values = values;
1247
+ const required = extractBooleanProperty(obj, "required");
1248
+ if (required !== null) def.required = required;
1249
+ const defaultProp = findProperty(obj, "default");
1250
+ if (defaultProp) {
1251
+ def.default = extractLiteralValue(defaultProp);
1252
+ }
1253
+ const constraints = extractStringArray(obj, "constraints");
1254
+ if (constraints.length > 0) def.constraints = constraints;
1255
+ return def;
1256
+ }
1257
+ function extractVariants(arg, sourceFile, warnings) {
1258
+ const variantsProp = findProperty(arg, "variants");
1259
+ if (!variantsProp || !ts2.isArrayLiteralExpression(variantsProp)) {
1260
+ return [];
1261
+ }
1262
+ const variants = [];
1263
+ for (const element of variantsProp.elements) {
1264
+ if (ts2.isObjectLiteralExpression(element)) {
1265
+ const name = extractStringProperty(element, "name");
1266
+ const description = extractStringProperty(element, "description");
1267
+ if (name) {
1268
+ const variant = {
1269
+ name,
1270
+ description: description ?? ""
1271
+ };
1272
+ const codeProp = findProperty(element, "code");
1273
+ if (codeProp && ts2.isStringLiteral(codeProp)) {
1274
+ variant.code = codeProp.text;
1275
+ }
1276
+ const renderProp = findProperty(element, "render");
1277
+ if (renderProp && !variant.code) {
1278
+ variant.code = extractRenderCode(renderProp, sourceFile);
1279
+ }
1280
+ const figma = extractStringProperty(element, "figma");
1281
+ if (figma) {
1282
+ variant.figma = figma;
1283
+ }
1284
+ const argsProp = findProperty(element, "args");
1285
+ if (argsProp && ts2.isObjectLiteralExpression(argsProp)) {
1286
+ const argsValue = extractLiteralValue(argsProp);
1287
+ if (argsValue && typeof argsValue === "object" && !Array.isArray(argsValue)) {
1288
+ variant.args = argsValue;
1289
+ }
1290
+ }
1291
+ variants.push(variant);
1292
+ }
1293
+ }
1294
+ }
1295
+ return variants;
1296
+ }
1297
+ function extractRenderCode(renderProp, sourceFile) {
1298
+ if (ts2.isArrowFunction(renderProp)) {
1299
+ const body = renderProp.body;
1300
+ const start = body.getStart(sourceFile);
1301
+ const end = body.getEnd();
1302
+ let code = sourceFile.text.substring(start, end).trim();
1303
+ if (code.startsWith("(") && code.endsWith(")")) {
1304
+ code = code.slice(1, -1).trim();
1305
+ }
1306
+ return code;
1307
+ }
1308
+ return void 0;
1309
+ }
1310
+ function extractRelations(arg, warnings) {
1311
+ const relationsProp = findProperty(arg, "relations");
1312
+ if (!relationsProp || !ts2.isArrayLiteralExpression(relationsProp)) {
1313
+ return [];
1314
+ }
1315
+ const relations = [];
1316
+ for (const element of relationsProp.elements) {
1317
+ if (ts2.isObjectLiteralExpression(element)) {
1318
+ const component = extractStringProperty(element, "component");
1319
+ const relationship = extractStringProperty(element, "relationship");
1320
+ const note = extractStringProperty(element, "note");
1321
+ if (component && relationship) {
1322
+ relations.push({
1323
+ component,
1324
+ relationship,
1325
+ note: note ?? ""
1326
+ });
1327
+ }
1328
+ }
1329
+ }
1330
+ return relations;
1331
+ }
1332
+ function extractStringProperty(obj, name) {
1333
+ const prop = findProperty(obj, name);
1334
+ if (prop && ts2.isStringLiteral(prop)) {
1335
+ return prop.text;
1336
+ }
1337
+ if (prop && ts2.isNoSubstitutionTemplateLiteral(prop)) {
1338
+ return prop.text;
1339
+ }
1340
+ return null;
1341
+ }
1342
+ function extractBooleanProperty(obj, name) {
1343
+ const prop = findProperty(obj, name);
1344
+ if (prop) {
1345
+ if (prop.kind === ts2.SyntaxKind.TrueKeyword) return true;
1346
+ if (prop.kind === ts2.SyntaxKind.FalseKeyword) return false;
1347
+ }
1348
+ return null;
1349
+ }
1350
+ function extractStringArray(obj, name) {
1351
+ const prop = findProperty(obj, name);
1352
+ if (!prop || !ts2.isArrayLiteralExpression(prop)) {
1353
+ return [];
1354
+ }
1355
+ const result = [];
1356
+ for (const element of prop.elements) {
1357
+ if (ts2.isStringLiteral(element)) {
1358
+ result.push(element.text);
1359
+ } else if (ts2.isNoSubstitutionTemplateLiteral(element)) {
1360
+ result.push(element.text);
1361
+ }
1362
+ }
1363
+ return result;
1364
+ }
1365
+ function extractLiteralValue(expr) {
1366
+ if (ts2.isStringLiteral(expr)) {
1367
+ return expr.text;
1368
+ }
1369
+ if (ts2.isNumericLiteral(expr)) {
1370
+ return Number(expr.text);
1371
+ }
1372
+ if (expr.kind === ts2.SyntaxKind.TrueKeyword) {
1373
+ return true;
1374
+ }
1375
+ if (expr.kind === ts2.SyntaxKind.FalseKeyword) {
1376
+ return false;
1377
+ }
1378
+ if (expr.kind === ts2.SyntaxKind.NullKeyword) {
1379
+ return null;
1380
+ }
1381
+ if (ts2.isArrayLiteralExpression(expr)) {
1382
+ return expr.elements.map(extractLiteralValue);
1383
+ }
1384
+ if (ts2.isObjectLiteralExpression(expr)) {
1385
+ const obj = {};
1386
+ for (const prop of expr.properties) {
1387
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
1388
+ obj[prop.name.text] = extractLiteralValue(prop.initializer);
1389
+ }
1390
+ }
1391
+ return obj;
1392
+ }
1393
+ return void 0;
1394
+ }
1395
+
1396
+ // src/core/previewLoader.ts
1397
+ import { existsSync as existsSync4 } from "fs";
1398
+ import { join as join3, resolve as resolve3 } from "path";
1399
+ var PREVIEW_FILES = [
1400
+ "preview.tsx",
1401
+ "preview.ts",
1402
+ "preview.jsx",
1403
+ "preview.js"
1404
+ ];
1405
+ function findPreviewConfigPath(storybookDir) {
1406
+ for (const fileName of PREVIEW_FILES) {
1407
+ const filePath = join3(storybookDir, fileName);
1408
+ if (existsSync4(filePath)) {
1409
+ return filePath;
1410
+ }
1411
+ }
1412
+ return null;
1413
+ }
1414
+ function findStorybookDir(projectRoot) {
1415
+ const possiblePaths = [
1416
+ join3(projectRoot, ".storybook"),
1417
+ join3(projectRoot, "storybook")
1418
+ ];
1419
+ for (const dir of possiblePaths) {
1420
+ if (existsSync4(dir)) {
1421
+ return dir;
1422
+ }
1423
+ }
1424
+ return null;
1425
+ }
1426
+ function generatePreviewModule(previewPath) {
1427
+ if (!previewPath) {
1428
+ return `
1429
+ export const decorators = [];
1430
+ export const parameters = {};
1431
+ export const globalTypes = {};
1432
+ export const args = {};
1433
+ export const argTypes = {};
1434
+ export const loaders = [];
1435
+
1436
+ export default {
1437
+ decorators,
1438
+ parameters,
1439
+ globalTypes,
1440
+ args,
1441
+ argTypes,
1442
+ loaders,
1443
+ };
1444
+ `;
1445
+ }
1446
+ return `
1447
+ import * as preview from "${previewPath}";
1448
+
1449
+ export const decorators = preview.decorators ?? preview.default?.decorators ?? [];
1450
+ export const parameters = preview.parameters ?? preview.default?.parameters ?? {};
1451
+ export const globalTypes = preview.globalTypes ?? preview.default?.globalTypes ?? {};
1452
+ export const args = preview.args ?? preview.default?.args ?? {};
1453
+ export const argTypes = preview.argTypes ?? preview.default?.argTypes ?? {};
1454
+ export const loaders = preview.loaders ?? preview.default?.loaders ?? [];
1455
+
1456
+ export default {
1457
+ decorators,
1458
+ parameters,
1459
+ globalTypes,
1460
+ args,
1461
+ argTypes,
1462
+ loaders,
1463
+ };
1464
+ `;
1465
+ }
1466
+
1467
+ // src/core/importAnalyzer.ts
1468
+ import ts3 from "typescript";
1469
+ import { readFileSync as readFileSync3 } from "fs";
1470
+ import { dirname as dirname5, basename as basename4 } from "path";
1471
+
1472
+ export {
1473
+ findConfigFile,
1474
+ loadConfig,
1475
+ discoverRecipeFiles,
1476
+ discoverSegmentFiles,
1477
+ discoverComponentFiles,
1478
+ extractComponentName,
1479
+ discoverAllComponents,
1480
+ loadSegmentFile,
1481
+ parseSegmentFile,
1482
+ findPreviewConfigPath,
1483
+ findStorybookDir,
1484
+ generatePreviewModule,
1485
+ extractPropsFromFile,
1486
+ generateRegistry,
1487
+ generateContextMd
1488
+ };
1489
+ //# sourceMappingURL=chunk-OAENNG3G.js.map