@fragments-sdk/cli 0.14.3 → 0.15.0

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 (135) hide show
  1. package/README.md +0 -3
  2. package/dist/bin.js +4290 -3754
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-TXFCEDOC.js → chunk-2WXKALIG.js} +2 -2
  5. package/dist/{chunk-I34BC3CU.js → chunk-32LIWN2P.js} +1006 -3
  6. package/dist/chunk-32LIWN2P.js.map +1 -0
  7. package/dist/{chunk-55KERLWL.js → chunk-65WSVDV5.js} +314 -89
  8. package/dist/chunk-65WSVDV5.js.map +1 -0
  9. package/dist/chunk-7DZC4YEV.js +294 -0
  10. package/dist/chunk-7DZC4YEV.js.map +1 -0
  11. package/dist/{chunk-LOYS64QS.js → chunk-7WHVW72L.js} +230 -19
  12. package/dist/chunk-7WHVW72L.js.map +1 -0
  13. package/dist/{chunk-PJT5IZ37.js → chunk-BJE3425I.js} +19 -52
  14. package/dist/{chunk-PJT5IZ37.js.map → chunk-BJE3425I.js.map} +1 -1
  15. package/dist/{chunk-5A6X2Y73.js → chunk-CZD3AD4Q.js} +12 -11
  16. package/dist/chunk-CZD3AD4Q.js.map +1 -0
  17. package/dist/{chunk-EYXVAMEX.js → chunk-MN3TJ3D5.js} +72 -3
  18. package/dist/chunk-MN3TJ3D5.js.map +1 -0
  19. package/dist/chunk-QCN35LJU.js +630 -0
  20. package/dist/chunk-QCN35LJU.js.map +1 -0
  21. package/dist/chunk-T47OLCSF.js +36 -0
  22. package/dist/chunk-T47OLCSF.js.map +1 -0
  23. package/dist/{chunk-APTQIBS5.js → chunk-XJQ5BIWI.js} +144 -1049
  24. package/dist/chunk-XJQ5BIWI.js.map +1 -0
  25. package/dist/codebase-scanner-VOTPXRYW.js +22 -0
  26. package/dist/converter-JLINP7CJ.js +34 -0
  27. package/dist/converter-JLINP7CJ.js.map +1 -0
  28. package/dist/core/index.js +43 -1
  29. package/dist/{generate-RYWIPDN2.js → generate-A4FP5426.js} +3 -4
  30. package/dist/{generate-RYWIPDN2.js.map → generate-A4FP5426.js.map} +1 -1
  31. package/dist/govern-scan-UCBZR6D6.js +280 -0
  32. package/dist/govern-scan-UCBZR6D6.js.map +1 -0
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.js +11 -11
  35. package/dist/{init-WRUSW7R5.js → init-HGSM35XA.js} +131 -128
  36. package/dist/init-HGSM35XA.js.map +1 -0
  37. package/dist/{init-cloud-REQ3XLHO.js → init-cloud-MQ6GRJAZ.js} +2 -2
  38. package/dist/mcp-bin.js +5 -36
  39. package/dist/mcp-bin.js.map +1 -1
  40. package/dist/scan-VNNKACG2.js +15 -0
  41. package/dist/{scan-generate-TFZVL3BT.js → scan-generate-TWRHNU5M.js} +335 -46
  42. package/dist/scan-generate-TWRHNU5M.js.map +1 -0
  43. package/dist/scanner-7LAZYPWZ.js +13 -0
  44. package/dist/{service-HKJ6B7P7.js → service-FHQU7YS7.js} +27 -23
  45. package/dist/{snapshot-C5DYIGIV.js → snapshot-KQEQ6XHL.js} +2 -2
  46. package/dist/{static-viewer-DUVC4UIM.js → static-viewer-63PG6FWY.js} +3 -3
  47. package/dist/static-viewer-63PG6FWY.js.map +1 -0
  48. package/dist/{test-JW7JIDFG.js → test-UQYUCZIS.js} +4 -6
  49. package/dist/{test-JW7JIDFG.js.map → test-UQYUCZIS.js.map} +1 -1
  50. package/dist/{tokens-KE73G5JC.js → tokens-6GYKDV6U.js} +6 -5
  51. package/dist/{tokens-KE73G5JC.js.map → tokens-6GYKDV6U.js.map} +1 -1
  52. package/dist/tokens-generate-VTZV5EEW.js +86 -0
  53. package/dist/tokens-generate-VTZV5EEW.js.map +1 -0
  54. package/package.json +6 -6
  55. package/src/bin.ts +210 -48
  56. package/src/build.ts +130 -6
  57. package/src/commands/__fixtures__/shadcn-label-wrapper/package.json +7 -0
  58. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +42 -0
  59. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.tsx +11 -0
  60. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +20 -0
  61. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.tsx +14 -0
  62. package/src/commands/__fixtures__/shadcn-label-wrapper/tsconfig.app.json +23 -0
  63. package/src/commands/__tests__/init.test.ts +113 -0
  64. package/src/commands/__tests__/scan-generate.test.ts +188 -69
  65. package/src/commands/__tests__/verify.test.ts +91 -0
  66. package/src/commands/discover.ts +151 -0
  67. package/src/commands/enhance.ts +3 -1
  68. package/src/commands/govern-scan.ts +386 -0
  69. package/src/commands/govern.ts +2 -2
  70. package/src/commands/init.ts +152 -28
  71. package/src/commands/inspect.ts +290 -0
  72. package/src/commands/migrate-contract.ts +85 -0
  73. package/src/commands/scan-generate.ts +438 -50
  74. package/src/commands/scan.ts +1 -0
  75. package/src/commands/setup.ts +27 -50
  76. package/src/commands/tokens-generate.ts +113 -0
  77. package/src/commands/verify.ts +195 -1
  78. package/src/core/__fixtures__/shadcn-input/input.tsx +7 -0
  79. package/src/core/__fixtures__/shadcn-input/tsconfig.json +14 -0
  80. package/src/core/__fixtures__/shadcn-label/label.tsx +11 -0
  81. package/src/core/__fixtures__/shadcn-label/primitive.tsx +14 -0
  82. package/src/core/__fixtures__/shadcn-label/tsconfig.json +14 -0
  83. package/src/core/__fixtures__/shadcn-radix-label/label.tsx +11 -0
  84. package/src/core/__fixtures__/shadcn-radix-label/node_modules/radix-ui/index.d.ts +12 -0
  85. package/src/core/__fixtures__/shadcn-radix-label/tsconfig.json +14 -0
  86. package/src/core/__tests__/contract-parity.test.ts +316 -0
  87. package/src/core/component-extractor.test.ts +39 -0
  88. package/src/core/component-extractor.ts +92 -1
  89. package/src/core/config.ts +2 -1
  90. package/src/core/discovery.ts +13 -2
  91. package/src/core/drift-verifier.ts +123 -0
  92. package/src/core/extractor-adapter.ts +80 -0
  93. package/src/mcp/__tests__/projectFields.test.ts +1 -1
  94. package/src/mcp/utils.ts +1 -50
  95. package/src/migrate/converter.ts +3 -3
  96. package/src/migrate/fragment-to-contract.ts +253 -0
  97. package/src/migrate/report.ts +1 -1
  98. package/src/scripts/token-benchmark.ts +121 -0
  99. package/src/service/__tests__/props-extractor.test.ts +94 -0
  100. package/src/service/__tests__/token-normalizer.test.ts +690 -0
  101. package/src/service/ast-utils.ts +4 -23
  102. package/src/service/babel-config.ts +23 -0
  103. package/src/service/enhance/converter.ts +61 -0
  104. package/src/service/enhance/props-extractor.ts +25 -8
  105. package/src/service/enhance/scanner.ts +5 -24
  106. package/src/service/snippet-validation.ts +9 -3
  107. package/src/service/token-normalizer.ts +510 -0
  108. package/src/shared/index.ts +1 -0
  109. package/src/shared/project-fields.ts +46 -0
  110. package/src/viewer/__tests__/viewer-integration.test.ts +8 -8
  111. package/src/viewer/preview-adapter.ts +116 -0
  112. package/src/viewer/style-utils.ts +27 -412
  113. package/src/viewer/vite-plugin.ts +2 -2
  114. package/dist/chunk-55KERLWL.js.map +0 -1
  115. package/dist/chunk-5A6X2Y73.js.map +0 -1
  116. package/dist/chunk-APTQIBS5.js.map +0 -1
  117. package/dist/chunk-EYXVAMEX.js.map +0 -1
  118. package/dist/chunk-I34BC3CU.js.map +0 -1
  119. package/dist/chunk-LOYS64QS.js.map +0 -1
  120. package/dist/chunk-ZKTFKHWN.js +0 -324
  121. package/dist/chunk-ZKTFKHWN.js.map +0 -1
  122. package/dist/discovery-VDANZAJ2.js +0 -28
  123. package/dist/init-WRUSW7R5.js.map +0 -1
  124. package/dist/scan-YJHQIRKG.js +0 -14
  125. package/dist/scan-generate-TFZVL3BT.js.map +0 -1
  126. package/dist/viewer-2TZS3NDL.js +0 -2730
  127. package/dist/viewer-2TZS3NDL.js.map +0 -1
  128. package/src/commands/dev.ts +0 -107
  129. /package/dist/{chunk-TXFCEDOC.js.map → chunk-2WXKALIG.js.map} +0 -0
  130. /package/dist/{discovery-VDANZAJ2.js.map → codebase-scanner-VOTPXRYW.js.map} +0 -0
  131. /package/dist/{init-cloud-REQ3XLHO.js.map → init-cloud-MQ6GRJAZ.js.map} +0 -0
  132. /package/dist/{scan-YJHQIRKG.js.map → scan-VNNKACG2.js.map} +0 -0
  133. /package/dist/{service-HKJ6B7P7.js.map → scanner-7LAZYPWZ.js.map} +0 -0
  134. /package/dist/{static-viewer-DUVC4UIM.js.map → service-FHQU7YS7.js.map} +0 -0
  135. /package/dist/{snapshot-C5DYIGIV.js.map → snapshot-KQEQ6XHL.js.map} +0 -0
@@ -2,7 +2,7 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  BRAND,
4
4
  fragmentsConfigSchema
5
- } from "./chunk-I34BC3CU.js";
5
+ } from "./chunk-32LIWN2P.js";
6
6
 
7
7
  // src/core/config.ts
8
8
  import { existsSync } from "fs";
@@ -17,7 +17,9 @@ var STORYBOOK_FILTER_DEFAULTS = {
17
17
  var DEFAULT_CONFIG = {
18
18
  include: [
19
19
  `src/**/*${BRAND.fileExtension}`,
20
- // *.fragment.tsx files
20
+ // *.contract.json files (V2 canonical)
21
+ "src/**/*.fragment.tsx",
22
+ // Legacy fragment files (still supported)
21
23
  "src/**/*.stories.tsx"
22
24
  // Storybook stories (auto-converted)
23
25
  ],
@@ -80,6 +82,293 @@ ${errors}`);
80
82
  }
81
83
  }
82
84
 
85
+ // src/core/discovery.ts
86
+ import { resolve as resolve2, dirname as dirname2 } from "path";
87
+ import { readFile } from "fs/promises";
88
+ import { existsSync as existsSync2 } from "fs";
89
+ import fg from "fast-glob";
90
+ function toPascalCase(name) {
91
+ return name.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
92
+ }
93
+ async function extractPascalCaseExports(filePath) {
94
+ try {
95
+ const content = await readFile(filePath, "utf-8");
96
+ const exports = /* @__PURE__ */ new Set();
97
+ const exportFuncRegex = /export\s+function\s+([A-Z][a-zA-Z0-9]*)/g;
98
+ let match;
99
+ while ((match = exportFuncRegex.exec(content)) !== null) {
100
+ exports.add(match[1]);
101
+ }
102
+ const exportConstRegex = /export\s+const\s+([A-Z][a-zA-Z0-9]*)/g;
103
+ while ((match = exportConstRegex.exec(content)) !== null) {
104
+ exports.add(match[1]);
105
+ }
106
+ const exportBlockRegex = /export\s*\{([^}]+)\}/g;
107
+ while ((match = exportBlockRegex.exec(content)) !== null) {
108
+ const names = match[1].split(",").map((n) => n.trim().split(/\s+as\s+/)[0].trim());
109
+ for (const name of names) {
110
+ if (/^[A-Z]/.test(name)) {
111
+ exports.add(name);
112
+ }
113
+ }
114
+ }
115
+ return Array.from(exports);
116
+ } catch {
117
+ return [];
118
+ }
119
+ }
120
+ async function discoverBlockFiles(configDir, exclude) {
121
+ const patterns = [
122
+ `**/*${BRAND.blockFileExtension}`,
123
+ `**/*${BRAND.recipeFileExtension}`
124
+ ];
125
+ const files = await fg(patterns, {
126
+ cwd: configDir,
127
+ ignore: exclude ?? ["**/node_modules/**", "**/dist/**"],
128
+ absolute: false
129
+ });
130
+ return files.map((relativePath) => ({
131
+ relativePath,
132
+ absolutePath: resolve2(configDir, relativePath)
133
+ }));
134
+ }
135
+ async function discoverFragmentFiles(config, configDir) {
136
+ const defaultExcludes = [
137
+ "**/*.test.stories.*",
138
+ "**/*.stories.test.*",
139
+ "**/*.test.story.*",
140
+ "**/*.story.test.*"
141
+ ];
142
+ const patterns = [
143
+ ...config.include,
144
+ "**/*.contract.json"
145
+ ];
146
+ const files = await fg(patterns, {
147
+ cwd: configDir,
148
+ ignore: [...defaultExcludes, ...config.exclude ?? []],
149
+ absolute: false
150
+ });
151
+ return files.map((relativePath) => ({
152
+ relativePath,
153
+ absolutePath: resolve2(configDir, relativePath)
154
+ }));
155
+ }
156
+ async function discoverComponentFiles(config, configDir) {
157
+ if (!config.components || config.components.length === 0) {
158
+ return [];
159
+ }
160
+ const files = await fg(config.components, {
161
+ cwd: configDir,
162
+ ignore: [
163
+ ...config.exclude ?? [],
164
+ // Exclude fragment files themselves
165
+ ...config.include,
166
+ // Exclude test files
167
+ "**/*.test.*",
168
+ "**/*.spec.*",
169
+ "**/__tests__/**"
170
+ ],
171
+ absolute: false
172
+ });
173
+ return files.map((relativePath) => ({
174
+ relativePath,
175
+ absolutePath: resolve2(configDir, relativePath)
176
+ }));
177
+ }
178
+ function extractComponentName(filePath) {
179
+ const parts = filePath.replace(/\\/g, "/").split("/");
180
+ const fileName = parts[parts.length - 1];
181
+ if (fileName === "index.tsx" || fileName === "index.ts") {
182
+ return parts[parts.length - 2] ?? "Unknown";
183
+ }
184
+ return fileName.replace(/\.(tsx?|jsx?)$/, "");
185
+ }
186
+ var DEFAULT_COMPONENT_PATTERNS = [
187
+ "src/components/**/*.tsx",
188
+ "src/components/**/index.tsx",
189
+ "components/**/*.tsx",
190
+ "lib/components/**/*.tsx",
191
+ "packages/*/src/components/**/*.tsx"
192
+ ];
193
+ var DEFAULT_EXCLUDE_PATTERNS = [
194
+ "**/*.test.*",
195
+ "**/*.spec.*",
196
+ "**/*.stories.*",
197
+ "**/*.story.*",
198
+ "**/__tests__/**",
199
+ "**/__mocks__/**",
200
+ "**/node_modules/**",
201
+ "**/dist/**"
202
+ ];
203
+ async function discoverComponentsFromSource(configDir, patterns, exclude) {
204
+ const searchPatterns = patterns && patterns.length > 0 ? patterns : DEFAULT_COMPONENT_PATTERNS;
205
+ const excludePatterns = [
206
+ ...DEFAULT_EXCLUDE_PATTERNS,
207
+ ...exclude ?? []
208
+ ];
209
+ const files = await fg(searchPatterns, {
210
+ cwd: configDir,
211
+ ignore: excludePatterns,
212
+ absolute: false
213
+ });
214
+ const pascalCaseFiles = [];
215
+ const lowercaseFiles = [];
216
+ for (const file of files) {
217
+ const name = extractComponentName(file);
218
+ if (/^[A-Z]/.test(name)) {
219
+ pascalCaseFiles.push(file);
220
+ } else if (/^[a-z]/.test(name)) {
221
+ lowercaseFiles.push(file);
222
+ }
223
+ }
224
+ const storyPatterns = [
225
+ "**/*.stories.tsx",
226
+ "**/*.stories.ts",
227
+ "**/*.story.tsx",
228
+ "**/*.story.ts"
229
+ ];
230
+ const storyFiles = await fg(storyPatterns, {
231
+ cwd: configDir,
232
+ ignore: ["**/node_modules/**", "**/dist/**"],
233
+ absolute: false
234
+ });
235
+ const storyMap = /* @__PURE__ */ new Map();
236
+ for (const storyFile of storyFiles) {
237
+ const name = extractComponentName(storyFile.replace(/\.stories?\.(tsx?|jsx?)$/, ".tsx"));
238
+ storyMap.set(name, storyFile);
239
+ }
240
+ const components = [];
241
+ for (const file of pascalCaseFiles) {
242
+ const name = extractComponentName(file);
243
+ const absolutePath = resolve2(configDir, file);
244
+ const storyFile = storyMap.get(name);
245
+ components.push({
246
+ name,
247
+ sourcePath: absolutePath,
248
+ relativePath: file,
249
+ storyPath: storyFile ? resolve2(configDir, storyFile) : void 0
250
+ });
251
+ }
252
+ for (const file of lowercaseFiles) {
253
+ const absolutePath = resolve2(configDir, file);
254
+ const fileName = extractComponentName(file);
255
+ const pascalName = toPascalCase(fileName);
256
+ const exports = await extractPascalCaseExports(absolutePath);
257
+ const primaryExport = exports.find((e) => e === pascalName) || exports[0];
258
+ if (primaryExport) {
259
+ const storyFile = storyMap.get(primaryExport) || storyMap.get(fileName);
260
+ components.push({
261
+ name: primaryExport,
262
+ sourcePath: absolutePath,
263
+ relativePath: file,
264
+ storyPath: storyFile ? resolve2(configDir, storyFile) : void 0
265
+ });
266
+ }
267
+ }
268
+ components.sort((a, b) => a.name.localeCompare(b.name));
269
+ return components;
270
+ }
271
+ async function discoverComponentsFromBarrel(barrelPath, configDir) {
272
+ const absoluteBarrelPath = resolve2(configDir, barrelPath);
273
+ if (!existsSync2(absoluteBarrelPath)) {
274
+ return [];
275
+ }
276
+ const content = await readFile(absoluteBarrelPath, "utf-8");
277
+ const components = [];
278
+ const exportRegex = /export\s+(?:\*|{([^}]+)})\s+from\s+['"]([^'"]+)['"]/g;
279
+ let match;
280
+ while ((match = exportRegex.exec(content)) !== null) {
281
+ const exportedNames = match[1];
282
+ const importPath = match[2];
283
+ const barrelDir = dirname2(absoluteBarrelPath);
284
+ let resolvedPath = resolve2(barrelDir, importPath);
285
+ if (!resolvedPath.endsWith(".tsx") && !resolvedPath.endsWith(".ts")) {
286
+ if (existsSync2(`${resolvedPath}.tsx`)) {
287
+ resolvedPath = `${resolvedPath}.tsx`;
288
+ } else if (existsSync2(`${resolvedPath}.ts`)) {
289
+ resolvedPath = `${resolvedPath}.ts`;
290
+ } else if (existsSync2(`${resolvedPath}/index.tsx`)) {
291
+ resolvedPath = `${resolvedPath}/index.tsx`;
292
+ } else if (existsSync2(`${resolvedPath}/index.ts`)) {
293
+ resolvedPath = `${resolvedPath}/index.ts`;
294
+ }
295
+ }
296
+ if (!existsSync2(resolvedPath)) {
297
+ continue;
298
+ }
299
+ if (exportedNames) {
300
+ const names = exportedNames.split(",").map((n) => n.trim().split(/\s+as\s+/)[0].trim());
301
+ for (const name of names) {
302
+ if (/^[A-Z]/.test(name)) {
303
+ const relativePath = resolvedPath.replace(configDir + "/", "");
304
+ components.push({
305
+ name,
306
+ sourcePath: resolvedPath,
307
+ relativePath
308
+ });
309
+ }
310
+ }
311
+ } else {
312
+ const name = extractComponentName(importPath);
313
+ if (/^[A-Z]/.test(name)) {
314
+ const relativePath = resolvedPath.replace(configDir + "/", "");
315
+ components.push({
316
+ name,
317
+ sourcePath: resolvedPath,
318
+ relativePath
319
+ });
320
+ }
321
+ }
322
+ }
323
+ return components;
324
+ }
325
+ var DEFAULT_TOKEN_PATTERNS = [
326
+ "src/**/tokens/**/_variables.scss",
327
+ "src/**/tokens/**/variables.scss",
328
+ "src/**/styles/**/variables.scss",
329
+ "src/**/styles/**/tokens.scss",
330
+ "src/**/styles/**/variables.css",
331
+ "src/**/theme/**/_variables.scss",
332
+ "src/**/theme/**/tokens.css",
333
+ // DTCG token files
334
+ "**/*.tokens.json",
335
+ "**/*.tokens"
336
+ ];
337
+ async function discoverTokenFiles(configDir, patterns, exclude) {
338
+ const searchPatterns = patterns && patterns.length > 0 ? patterns : DEFAULT_TOKEN_PATTERNS;
339
+ const files = await fg(searchPatterns, {
340
+ cwd: configDir,
341
+ ignore: exclude ?? ["**/node_modules/**", "**/dist/**"],
342
+ absolute: false
343
+ });
344
+ return files.map((relativePath) => ({
345
+ relativePath,
346
+ absolutePath: resolve2(configDir, relativePath)
347
+ }));
348
+ }
349
+ async function discoverAllComponents(configDir, options = {}) {
350
+ const componentsMap = /* @__PURE__ */ new Map();
351
+ const sourceComponents = await discoverComponentsFromSource(
352
+ configDir,
353
+ options.patterns,
354
+ options.exclude
355
+ );
356
+ for (const comp of sourceComponents) {
357
+ componentsMap.set(comp.name, comp);
358
+ }
359
+ if (options.barrelFiles && options.barrelFiles.length > 0) {
360
+ for (const barrelFile of options.barrelFiles) {
361
+ const barrelComponents = await discoverComponentsFromBarrel(barrelFile, configDir);
362
+ for (const comp of barrelComponents) {
363
+ if (!componentsMap.has(comp.name)) {
364
+ componentsMap.set(comp.name, comp);
365
+ }
366
+ }
367
+ }
368
+ }
369
+ return Array.from(componentsMap.values()).sort((a, b) => a.name.localeCompare(b.name));
370
+ }
371
+
83
372
  // src/core/generators/typescript-extractor.ts
84
373
  import ts from "typescript";
85
374
  import { readFileSync } from "fs";
@@ -338,8 +627,8 @@ function getJSDocDefault(node) {
338
627
 
339
628
  // src/core/generators/registry.ts
340
629
  import { readFileSync as readFileSync2 } from "fs";
341
- import { relative, dirname as dirname2, basename, join } from "path";
342
- import fg from "fast-glob";
630
+ import { relative, dirname as dirname3, basename as basename2, join } from "path";
631
+ import fg2 from "fast-glob";
343
632
  async function generateRegistry(options) {
344
633
  const {
345
634
  projectRoot,
@@ -357,18 +646,18 @@ async function generateRegistry(options) {
357
646
  } = registryOptions;
358
647
  const errors = [];
359
648
  const warnings = [];
360
- const storyFiles = await fg(storyPatterns, {
649
+ const storyFiles = await fg2(storyPatterns, {
361
650
  cwd: projectRoot,
362
651
  ignore: ["**/node_modules/**"],
363
652
  absolute: true
364
653
  });
365
654
  const storyMap = /* @__PURE__ */ new Map();
366
655
  for (const storyPath of storyFiles) {
367
- const storyDir = dirname2(storyPath);
368
- const storyBase = basename(storyPath).replace(/\.stories\.(tsx?|jsx?)$/, "");
656
+ const storyDir = dirname3(storyPath);
657
+ const storyBase = basename2(storyPath).replace(/\.stories\.(tsx?|jsx?)$/, "");
369
658
  storyMap.set(`${storyDir}/${storyBase}`, storyPath);
370
659
  }
371
- const componentFiles = await fg(componentPatterns, {
660
+ const componentFiles = await fg2(componentPatterns, {
372
661
  cwd: projectRoot,
373
662
  ignore: [
374
663
  "**/node_modules/**",
@@ -384,13 +673,13 @@ async function generateRegistry(options) {
384
673
  BRAND.componentsDir,
385
674
  `*${BRAND.fileExtension}`
386
675
  );
387
- const fragmentFiles = await fg(fragmentPattern, {
676
+ const fragmentFiles = await fg2(fragmentPattern, {
388
677
  cwd: projectRoot,
389
678
  absolute: true
390
679
  });
391
680
  const fragmentMap = /* @__PURE__ */ new Map();
392
681
  for (const fragmentPath of fragmentFiles) {
393
- const fragmentName = basename(fragmentPath).replace(BRAND.fileExtension, "");
682
+ const fragmentName = basename2(fragmentPath).replace(BRAND.fileExtension, "");
394
683
  try {
395
684
  const content = readFileSync2(fragmentPath, "utf-8");
396
685
  const fragment = JSON.parse(content);
@@ -419,8 +708,8 @@ async function generateRegistry(options) {
419
708
  if (publicOnly && !extracted.exports.includes(componentName)) {
420
709
  continue;
421
710
  }
422
- const componentDir = dirname2(filePath);
423
- const baseNameWithoutExt = basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
711
+ const componentDir = dirname3(filePath);
712
+ const baseNameWithoutExt = basename2(filePath).replace(/\.(tsx?|jsx?)$/, "");
424
713
  const storyPath = storyMap.get(`${componentDir}/${baseNameWithoutExt}`);
425
714
  if (requireStory && !storyPath) {
426
715
  continue;
@@ -801,7 +1090,7 @@ function estimateTokens(text) {
801
1090
 
802
1091
  // src/core/loader.ts
803
1092
  import { unlink } from "fs/promises";
804
- import { dirname as dirname3, basename as basename2, join as join2 } from "path";
1093
+ import { dirname as dirname4, basename as basename3, join as join2 } from "path";
805
1094
  import { pathToFileURL } from "url";
806
1095
  import { build } from "esbuild";
807
1096
  var DEFINE_FRAGMENT_SHIM = `
@@ -862,8 +1151,8 @@ async function loadFragmentFile(absolutePath) {
862
1151
  const module = await import(fileUrl);
863
1152
  return unwrapFragmentExport(module.default ?? null);
864
1153
  }
865
- const sourceDir = dirname3(absolutePath);
866
- const baseName = basename2(absolutePath, `.${ext}`);
1154
+ const sourceDir = dirname4(absolutePath);
1155
+ const baseName = basename3(absolutePath, `.${ext}`);
867
1156
  const tempFile = join2(sourceDir, `.${baseName}.fragments-temp-${Date.now()}.mjs`);
868
1157
  try {
869
1158
  await build({
@@ -1322,91 +1611,27 @@ function extractLiteralValue(expr) {
1322
1611
  }
1323
1612
 
1324
1613
  // src/core/previewLoader.ts
1325
- import { existsSync as existsSync3 } from "fs";
1326
- import { join as join3, resolve as resolve2 } from "path";
1327
- var PREVIEW_FILES = [
1328
- "preview.tsx",
1329
- "preview.ts",
1330
- "preview.jsx",
1331
- "preview.js"
1332
- ];
1333
- function findPreviewConfigPath(storybookDir) {
1334
- for (const fileName of PREVIEW_FILES) {
1335
- const filePath = join3(storybookDir, fileName);
1336
- if (existsSync3(filePath)) {
1337
- return filePath;
1338
- }
1339
- }
1340
- return null;
1341
- }
1342
- function findStorybookDir(projectRoot) {
1343
- const possiblePaths = [
1344
- join3(projectRoot, ".storybook"),
1345
- join3(projectRoot, "storybook")
1346
- ];
1347
- for (const dir of possiblePaths) {
1348
- if (existsSync3(dir)) {
1349
- return dir;
1350
- }
1351
- }
1352
- return null;
1353
- }
1354
- function generatePreviewModule(previewPath) {
1355
- if (!previewPath) {
1356
- return `
1357
- export const decorators = [];
1358
- export const parameters = {};
1359
- export const globalTypes = {};
1360
- export const args = {};
1361
- export const argTypes = {};
1362
- export const loaders = [];
1363
-
1364
- export default {
1365
- decorators,
1366
- parameters,
1367
- globalTypes,
1368
- args,
1369
- argTypes,
1370
- loaders,
1371
- };
1372
- `;
1373
- }
1374
- return `
1375
- import * as preview from "${previewPath}";
1376
-
1377
- export const decorators = preview.decorators ?? preview.default?.decorators ?? [];
1378
- export const parameters = preview.parameters ?? preview.default?.parameters ?? {};
1379
- export const globalTypes = preview.globalTypes ?? preview.default?.globalTypes ?? {};
1380
- export const args = preview.args ?? preview.default?.args ?? {};
1381
- export const argTypes = preview.argTypes ?? preview.default?.argTypes ?? {};
1382
- export const loaders = preview.loaders ?? preview.default?.loaders ?? [];
1383
-
1384
- export default {
1385
- decorators,
1386
- parameters,
1387
- globalTypes,
1388
- args,
1389
- argTypes,
1390
- loaders,
1391
- };
1392
- `;
1393
- }
1614
+ import { existsSync as existsSync4 } from "fs";
1615
+ import { join as join3, resolve as resolve3 } from "path";
1394
1616
 
1395
1617
  // src/core/importAnalyzer.ts
1396
1618
  import ts3 from "typescript";
1397
1619
  import { readFileSync as readFileSync3 } from "fs";
1398
- import { dirname as dirname4, basename as basename3 } from "path";
1620
+ import { dirname as dirname5, basename as basename4 } from "path";
1399
1621
 
1400
1622
  export {
1401
1623
  findConfigFile,
1402
1624
  loadConfig,
1625
+ discoverBlockFiles,
1626
+ discoverFragmentFiles,
1627
+ discoverComponentFiles,
1628
+ extractComponentName,
1629
+ discoverTokenFiles,
1630
+ discoverAllComponents,
1403
1631
  loadFragmentFile,
1404
1632
  parseFragmentFile,
1405
- findPreviewConfigPath,
1406
- findStorybookDir,
1407
- generatePreviewModule,
1408
1633
  extractPropsFromFile,
1409
1634
  generateRegistry,
1410
1635
  generateContextMd
1411
1636
  };
1412
- //# sourceMappingURL=chunk-55KERLWL.js.map
1637
+ //# sourceMappingURL=chunk-65WSVDV5.js.map