@fragments-sdk/cli 0.9.1 → 0.10.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 (108) hide show
  1. package/dist/bin.d.ts +1 -0
  2. package/dist/bin.js +435 -67
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-D7372LQX.js → chunk-5G3VZH43.js} +8 -12
  5. package/dist/chunk-5G3VZH43.js.map +1 -0
  6. package/dist/chunk-D2CDBRNU.js +2 -0
  7. package/dist/{chunk-YMPGYEWK.js → chunk-D5PYOXEI.js} +2 -2
  8. package/dist/{chunk-BW3ZATBW.js → chunk-HRFUSSZI.js} +27 -10
  9. package/dist/chunk-HRFUSSZI.js.map +1 -0
  10. package/dist/{chunk-GF6OVPIN.js → chunk-OQO55NKV.js} +405 -34
  11. package/dist/chunk-OQO55NKV.js.map +1 -0
  12. package/dist/{chunk-TOIE7VXF.js → chunk-PW7QTQA6.js} +2 -2
  13. package/dist/{chunk-AWYCDRPG.js → chunk-WXSR2II7.js} +2 -2
  14. package/dist/chunk-WXSR2II7.js.map +1 -0
  15. package/dist/{chunk-5GT62FCB.js → chunk-ZM4ZQZWZ.js} +5 -5
  16. package/dist/core/index.d.ts +1 -2194
  17. package/dist/core/index.js +22 -27
  18. package/dist/{discovery-Z4RDDFVR.js → discovery-NEOY4MPN.js} +3 -3
  19. package/dist/{generate-LQA2R7FN.js → generate-FBHSXR3D.js} +5 -7
  20. package/dist/{generate-LQA2R7FN.js.map → generate-FBHSXR3D.js.map} +1 -1
  21. package/dist/index.d.ts +3 -5
  22. package/dist/index.js +7 -9
  23. package/dist/index.js.map +1 -1
  24. package/dist/{init-2GEGVIUQ.js → init-NDQXUWDU.js} +58 -6
  25. package/dist/init-NDQXUWDU.js.map +1 -0
  26. package/dist/mcp-bin.js +5 -8
  27. package/dist/mcp-bin.js.map +1 -1
  28. package/dist/scan-CJF2DOQW.js +14 -0
  29. package/dist/scan-generate-SJAN5MVI.js +691 -0
  30. package/dist/scan-generate-SJAN5MVI.js.map +1 -0
  31. package/dist/{service-XP2EAJXD.js → service-TQYWY65E.js} +4 -6
  32. package/dist/{static-viewer-XCS7UJTO.js → static-viewer-NUBFPKWH.js} +4 -6
  33. package/dist/{test-TD6TJNVY.js → test-Z5LVO724.js} +4 -5
  34. package/dist/{test-TD6TJNVY.js.map → test-Z5LVO724.js.map} +1 -1
  35. package/dist/{tokens-2EXPCVP3.js → tokens-CE46OTMD.js} +6 -8
  36. package/dist/{tokens-2EXPCVP3.js.map → tokens-CE46OTMD.js.map} +1 -1
  37. package/dist/{viewer-RFA2KVBG.js → viewer-DNMNC5VS.js} +16 -19
  38. package/dist/viewer-DNMNC5VS.js.map +1 -0
  39. package/package.json +2 -1
  40. package/src/bin.ts +33 -1
  41. package/src/build.ts +1 -1
  42. package/src/commands/__tests__/scan-generate.test.ts +308 -0
  43. package/src/commands/init.ts +72 -5
  44. package/src/commands/perf.ts +1 -1
  45. package/src/commands/scan-generate.ts +1013 -0
  46. package/src/commands/setup.ts +499 -0
  47. package/src/core/auto-props.ts +1 -1
  48. package/src/core/bundle-measurer.ts +2 -2
  49. package/src/core/config.ts +2 -3
  50. package/src/core/discovery.ts +2 -2
  51. package/src/core/generators/context.ts +1 -1
  52. package/src/core/generators/registry.ts +3 -3
  53. package/src/core/generators/typescript-extractor.ts +1 -1
  54. package/src/core/graph-extractor.ts +1 -1
  55. package/src/core/index.ts +3 -205
  56. package/src/core/loader.ts +40 -10
  57. package/src/core/parser.ts +1 -1
  58. package/src/core/previewLoader.ts +1 -1
  59. package/src/index.ts +2 -2
  60. package/src/service/snippet-validation.test.ts +1 -1
  61. package/src/service/snippet-validation.ts +2 -2
  62. package/src/viewer/__tests__/viewer-integration.test.ts +3 -9
  63. package/src/viewer/assets/fragments_logo.png +0 -0
  64. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +2 -10
  65. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +4 -1
  66. package/src/viewer/vite-plugin.ts +1 -1
  67. package/dist/chunk-AWYCDRPG.js.map +0 -1
  68. package/dist/chunk-BW3ZATBW.js.map +0 -1
  69. package/dist/chunk-D7372LQX.js.map +0 -1
  70. package/dist/chunk-EKLMXTWU.js +0 -80
  71. package/dist/chunk-EKLMXTWU.js.map +0 -1
  72. package/dist/chunk-EZYXYWNF.js +0 -131
  73. package/dist/chunk-EZYXYWNF.js.map +0 -1
  74. package/dist/chunk-GF6OVPIN.js.map +0 -1
  75. package/dist/chunk-NVSPGSKB.js +0 -203
  76. package/dist/chunk-NVSPGSKB.js.map +0 -1
  77. package/dist/defineFragment-CBMS7Bab.d.ts +0 -685
  78. package/dist/init-2GEGVIUQ.js.map +0 -1
  79. package/dist/scan-JGS65S7P.js +0 -16
  80. package/dist/storyFilters-3LUYAFZF.js +0 -15
  81. package/dist/viewer-RFA2KVBG.js.map +0 -1
  82. package/src/core/__tests__/preview-runtime.test.tsx +0 -111
  83. package/src/core/composition.test.ts +0 -262
  84. package/src/core/composition.ts +0 -318
  85. package/src/core/constants.ts +0 -114
  86. package/src/core/context.ts +0 -2
  87. package/src/core/defineFragment.ts +0 -141
  88. package/src/core/figma.ts +0 -263
  89. package/src/core/fragment-types.ts +0 -214
  90. package/src/core/performance-presets.ts +0 -142
  91. package/src/core/preview-runtime.tsx +0 -144
  92. package/src/core/schema.ts +0 -229
  93. package/src/core/storyAdapter.test.ts +0 -571
  94. package/src/core/storyAdapter.ts +0 -761
  95. package/src/core/storyFilters.test.ts +0 -350
  96. package/src/core/storyFilters.ts +0 -253
  97. package/src/core/storybook-csf.ts +0 -11
  98. package/src/core/token-parser.ts +0 -321
  99. package/src/core/token-types.ts +0 -287
  100. package/src/core/types.ts +0 -784
  101. /package/dist/{discovery-Z4RDDFVR.js.map → chunk-D2CDBRNU.js.map} +0 -0
  102. /package/dist/{chunk-YMPGYEWK.js.map → chunk-D5PYOXEI.js.map} +0 -0
  103. /package/dist/{chunk-TOIE7VXF.js.map → chunk-PW7QTQA6.js.map} +0 -0
  104. /package/dist/{chunk-5GT62FCB.js.map → chunk-ZM4ZQZWZ.js.map} +0 -0
  105. /package/dist/{scan-JGS65S7P.js.map → discovery-NEOY4MPN.js.map} +0 -0
  106. /package/dist/{service-XP2EAJXD.js.map → scan-CJF2DOQW.js.map} +0 -0
  107. /package/dist/{static-viewer-XCS7UJTO.js.map → service-TQYWY65E.js.map} +0 -0
  108. /package/dist/{storyFilters-3LUYAFZF.js.map → static-viewer-NUBFPKWH.js.map} +0 -0
@@ -1,10 +1,88 @@
1
1
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
- import {
3
- blockDefinitionSchema,
4
- fragmentDefinitionSchema
5
- } from "./chunk-NVSPGSKB.js";
6
2
 
7
- // src/core/performance-presets.ts
3
+ // ../core/dist/index.js
4
+ import { z } from "zod";
5
+ import { createElement } from "react";
6
+ import {
7
+ toId as storybookToId,
8
+ storyNameFromExport as storybookStoryNameFromExport,
9
+ isExportStory as storybookIsExportStory
10
+ } from "@storybook/csf";
11
+ import { generateContext, filterPlaceholders, PLACEHOLDER_PATTERNS } from "@fragments-sdk/context/generate";
12
+ import { ComponentGraphEngine } from "@fragments-sdk/context/graph";
13
+ import { useEffect, useState } from "react";
14
+ import { Fragment, jsx } from "react/jsx-runtime";
15
+ var BRAND = {
16
+ /** Display name (e.g., "Fragments") */
17
+ name: "Fragments",
18
+ /** Lowercase name for file paths and CLI (e.g., "fragments") */
19
+ nameLower: "fragments",
20
+ /** File extension for fragment definition files (e.g., ".fragment.tsx") */
21
+ fileExtension: ".fragment.tsx",
22
+ /** Legacy file extension for segments (still supported for migration) */
23
+ legacyFileExtension: ".segment.tsx",
24
+ /** JSON file extension for compiled output */
25
+ jsonExtension: ".fragment.json",
26
+ /** Default output file name (e.g., "fragments.json") */
27
+ outFile: "fragments.json",
28
+ /** Config file name (e.g., "fragments.config.ts") */
29
+ configFile: "fragments.config.ts",
30
+ /** Legacy config file name (still supported for migration) */
31
+ legacyConfigFile: "segments.config.ts",
32
+ /** CLI command name (e.g., "fragments") */
33
+ cliCommand: "fragments",
34
+ /** Package scope (e.g., "@fragments") */
35
+ packageScope: "@fragments",
36
+ /** Directory for storing fragments, registry, and cache */
37
+ dataDir: ".fragments",
38
+ /** Components subdirectory within .fragments/ */
39
+ componentsDir: "components",
40
+ /** Registry file name */
41
+ registryFile: "registry.json",
42
+ /** Context file name (AI-ready markdown) */
43
+ contextFile: "context.md",
44
+ /** Screenshots subdirectory */
45
+ screenshotsDir: "screenshots",
46
+ /** Cache subdirectory (gitignored) */
47
+ cacheDir: "cache",
48
+ /** Diff output subdirectory (gitignored) */
49
+ diffDir: "diff",
50
+ /** Manifest filename */
51
+ manifestFile: "manifest.json",
52
+ /** Prefix for localStorage keys (e.g., "fragments-") */
53
+ storagePrefix: "fragments-",
54
+ /** Static viewer HTML file name */
55
+ viewerHtmlFile: "fragments-viewer.html",
56
+ /** MCP tool name prefix (e.g., "fragments_") */
57
+ mcpToolPrefix: "fragments_",
58
+ /** File extension for block definition files */
59
+ blockFileExtension: ".block.ts",
60
+ /** @deprecated Use blockFileExtension instead */
61
+ recipeFileExtension: ".recipe.ts",
62
+ /** Vite plugin namespace */
63
+ vitePluginNamespace: "fragments-core-shim"
64
+ };
65
+ var DEFAULTS = {
66
+ /** Default viewport dimensions */
67
+ viewport: {
68
+ width: 1280,
69
+ height: 800
70
+ },
71
+ /** Default diff threshold (percentage) */
72
+ diffThreshold: 5,
73
+ /** Browser pool size */
74
+ poolSize: 3,
75
+ /** Idle timeout before browser shutdown (ms) - 5 minutes */
76
+ idleTimeoutMs: 5 * 60 * 1e3,
77
+ /** Delay after render before capture (ms) */
78
+ captureDelayMs: 100,
79
+ /** Font loading timeout (ms) */
80
+ fontTimeoutMs: 3e3,
81
+ /** Default theme */
82
+ theme: "light",
83
+ /** Dev server port */
84
+ port: 6006
85
+ };
8
86
  var PRESETS = {
9
87
  strict: { bundleSize: 8 * 1024 },
10
88
  // 8KB gzipped
@@ -56,8 +134,187 @@ function budgetBar(percent, width = 20) {
56
134
  const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
57
135
  return percent > 100 ? `\x1B[31m${bar}\x1B[0m` : `\x1B[32m${bar}\x1B[0m`;
58
136
  }
59
-
60
- // src/core/defineFragment.ts
137
+ var figmaStringMappingSchema = z.object({
138
+ __type: z.literal("figma-string"),
139
+ figmaProperty: z.string().min(1)
140
+ });
141
+ var figmaBooleanMappingSchema = z.object({
142
+ __type: z.literal("figma-boolean"),
143
+ figmaProperty: z.string().min(1),
144
+ valueMapping: z.object({ true: z.unknown(), false: z.unknown() }).optional()
145
+ });
146
+ var figmaEnumMappingSchema = z.object({
147
+ __type: z.literal("figma-enum"),
148
+ figmaProperty: z.string().min(1),
149
+ valueMapping: z.record(z.unknown())
150
+ });
151
+ var figmaInstanceMappingSchema = z.object({
152
+ __type: z.literal("figma-instance"),
153
+ figmaProperty: z.string().min(1)
154
+ });
155
+ var figmaChildrenMappingSchema = z.object({
156
+ __type: z.literal("figma-children"),
157
+ layers: z.array(z.string().min(1))
158
+ });
159
+ var figmaTextContentMappingSchema = z.object({
160
+ __type: z.literal("figma-text-content"),
161
+ layer: z.string().min(1)
162
+ });
163
+ var figmaPropMappingSchema = z.discriminatedUnion("__type", [
164
+ figmaStringMappingSchema,
165
+ figmaBooleanMappingSchema,
166
+ figmaEnumMappingSchema,
167
+ figmaInstanceMappingSchema,
168
+ figmaChildrenMappingSchema,
169
+ figmaTextContentMappingSchema
170
+ ]);
171
+ var fragmentMetaSchema = z.object({
172
+ name: z.string().min(1),
173
+ description: z.string().min(1),
174
+ category: z.string().min(1),
175
+ tags: z.array(z.string()).optional(),
176
+ status: z.enum(["stable", "beta", "deprecated", "experimental"]).optional(),
177
+ since: z.string().optional(),
178
+ dependencies: z.array(z.object({
179
+ name: z.string().min(1),
180
+ version: z.string().min(1),
181
+ reason: z.string().optional()
182
+ })).optional(),
183
+ figma: z.string().url().optional(),
184
+ figmaProps: z.record(figmaPropMappingSchema).optional()
185
+ });
186
+ var fragmentUsageSchema = z.object({
187
+ when: z.array(z.string()),
188
+ whenNot: z.array(z.string()),
189
+ guidelines: z.array(z.string()).optional(),
190
+ accessibility: z.array(z.string()).optional()
191
+ });
192
+ var propTypeSchema = z.enum([
193
+ "string",
194
+ "number",
195
+ "boolean",
196
+ "enum",
197
+ "function",
198
+ "node",
199
+ "element",
200
+ "object",
201
+ "array",
202
+ "union",
203
+ "custom"
204
+ ]);
205
+ var propDefinitionSchema = z.object({
206
+ type: propTypeSchema,
207
+ values: z.array(z.string()).readonly().optional(),
208
+ default: z.unknown().optional(),
209
+ description: z.string().optional(),
210
+ required: z.boolean().optional(),
211
+ constraints: z.array(z.string()).optional(),
212
+ typeDetails: z.record(z.unknown()).optional()
213
+ });
214
+ var relationshipTypeSchema = z.enum([
215
+ "alternative",
216
+ "sibling",
217
+ "parent",
218
+ "child",
219
+ "composition",
220
+ "complementary",
221
+ "used-by"
222
+ ]);
223
+ var componentRelationSchema = z.object({
224
+ component: z.string().min(1),
225
+ relationship: relationshipTypeSchema,
226
+ note: z.string().min(1)
227
+ });
228
+ var fragmentVariantSchema = z.object({
229
+ name: z.string().min(1),
230
+ description: z.string().min(1),
231
+ render: z.function().returns(z.unknown()),
232
+ code: z.string().optional(),
233
+ figma: z.string().url().optional()
234
+ });
235
+ var fragmentBanSchema = z.object({
236
+ pattern: z.string().min(1),
237
+ message: z.string().min(1)
238
+ });
239
+ var fragmentContractSchema = z.object({
240
+ propsSummary: z.array(z.string()).optional(),
241
+ a11yRules: z.array(z.string()).optional(),
242
+ bans: z.array(fragmentBanSchema).optional(),
243
+ scenarioTags: z.array(z.string()).optional(),
244
+ performanceBudget: z.number().positive().optional()
245
+ });
246
+ var fragmentGeneratedSchema = z.object({
247
+ source: z.enum(["storybook", "manual", "ai"]),
248
+ sourceFile: z.string().optional(),
249
+ confidence: z.number().min(0).max(1).optional(),
250
+ timestamp: z.string().datetime().optional()
251
+ });
252
+ var aiMetadataSchema = z.object({
253
+ compositionPattern: z.enum(["compound", "simple", "controlled", "wrapper"]).optional(),
254
+ subComponents: z.array(z.string()).optional(),
255
+ requiredChildren: z.array(z.string()).optional(),
256
+ commonPatterns: z.array(z.string()).optional()
257
+ });
258
+ var blockDefinitionSchema = z.object({
259
+ name: z.string().min(1),
260
+ description: z.string().min(1),
261
+ category: z.string().min(1),
262
+ components: z.array(z.string().min(1)).min(1),
263
+ code: z.string().min(1),
264
+ tags: z.array(z.string()).optional()
265
+ });
266
+ var fragmentDefinitionSchema = z.object({
267
+ component: z.any(),
268
+ // Allow any component type (function, class, forwardRef, etc.)
269
+ meta: fragmentMetaSchema,
270
+ usage: fragmentUsageSchema,
271
+ props: z.record(propDefinitionSchema),
272
+ relations: z.array(componentRelationSchema).optional(),
273
+ variants: z.array(fragmentVariantSchema),
274
+ // Allow empty variants array
275
+ contract: fragmentContractSchema.optional(),
276
+ ai: aiMetadataSchema.optional(),
277
+ _generated: fragmentGeneratedSchema.optional()
278
+ });
279
+ var fragmentsConfigSchema = z.object({
280
+ include: z.array(z.string()).min(1),
281
+ exclude: z.array(z.string()).optional(),
282
+ components: z.array(z.string()).optional(),
283
+ outFile: z.string().optional(),
284
+ framework: z.enum(["react", "vue", "svelte"]).optional(),
285
+ figmaFile: z.string().url().optional(),
286
+ figmaToken: z.string().optional(),
287
+ screenshots: z.object({}).passthrough().optional(),
288
+ service: z.object({}).passthrough().optional(),
289
+ registry: z.object({}).passthrough().optional(),
290
+ tokens: z.object({
291
+ include: z.array(z.string()).min(1)
292
+ }).passthrough().optional(),
293
+ snippets: z.object({
294
+ mode: z.enum(["warn", "error"]).optional(),
295
+ scope: z.enum(["snippet", "snippet+render"]).optional(),
296
+ requireFullSnippet: z.boolean().optional(),
297
+ allowedExternalModules: z.array(z.string().min(1)).optional()
298
+ }).optional(),
299
+ performance: z.union([
300
+ z.enum(["strict", "standard", "relaxed"]),
301
+ z.object({
302
+ preset: z.enum(["strict", "standard", "relaxed"]).optional(),
303
+ budgets: z.object({
304
+ bundleSize: z.number().positive().optional()
305
+ }).optional()
306
+ })
307
+ ]).optional(),
308
+ storybook: z.object({
309
+ exclude: z.array(z.string()).optional(),
310
+ include: z.array(z.string()).optional(),
311
+ excludeDeprecated: z.boolean().optional(),
312
+ excludeTests: z.boolean().optional(),
313
+ excludeSvgIcons: z.boolean().optional(),
314
+ excludeSubComponents: z.boolean().optional()
315
+ }).optional()
316
+ });
317
+ var recipeDefinitionSchema = blockDefinitionSchema;
61
318
  function defineFragment(definition) {
62
319
  if (process.env.NODE_ENV !== "production") {
63
320
  const result = fragmentDefinitionSchema.safeParse(definition);
@@ -114,21 +371,9 @@ function compileBlock(definition, filePath) {
114
371
  };
115
372
  }
116
373
  var compileRecipe = compileBlock;
117
-
118
- // src/core/storyAdapter.ts
119
- import { createElement } from "react";
120
-
121
- // src/core/storybook-csf.ts
122
- import {
123
- toId as storybookToId,
124
- storyNameFromExport as storybookStoryNameFromExport,
125
- isExportStory as storybookIsExportStory
126
- } from "@storybook/csf";
127
374
  var toId = (...args) => storybookToId(...args);
128
375
  var storyNameFromExport = (...args) => storybookStoryNameFromExport(...args);
129
376
  var isExportStory = (...args) => storybookIsExportStory(...args);
130
-
131
- // src/core/storyAdapter.ts
132
377
  var globalPreviewConfig = {};
133
378
  function setPreviewConfig(config) {
134
379
  globalPreviewConfig = config;
@@ -467,11 +712,126 @@ function applyDecorators(renderFn, decorators, context) {
467
712
  }
468
713
  return storyFn();
469
714
  }
470
-
471
- // src/core/context.ts
472
- import { generateContext, filterPlaceholders, PLACEHOLDER_PATTERNS } from "@fragments-sdk/context/generate";
473
-
474
- // src/core/figma.ts
715
+ var EXCLUDED_TAGS = /* @__PURE__ */ new Set(["hidden", "internal", "no-fragment"]);
716
+ var SVG_ICON_RE = /^Svg[A-Z]/;
717
+ var TEST_TITLE_RE = /\/tests?$/i;
718
+ var TEST_FILE_RE = /\.test\.stories\./;
719
+ var DEPRECATED_TITLE_RE = /\bDeprecated\b/i;
720
+ function checkStoryExclusion(opts) {
721
+ const { config } = opts;
722
+ if (isForceIncluded(opts.componentName, config)) {
723
+ return { excluded: false };
724
+ }
725
+ if (isConfigExcluded(opts.componentName, config)) {
726
+ return {
727
+ excluded: true,
728
+ reason: "config-excluded",
729
+ detail: `'${opts.componentName}' matches storybook.exclude pattern`
730
+ };
731
+ }
732
+ if (config.excludeDeprecated !== false && opts.storybookTitle && DEPRECATED_TITLE_RE.test(opts.storybookTitle)) {
733
+ return {
734
+ excluded: true,
735
+ reason: "deprecated",
736
+ detail: `Title "${opts.storybookTitle}" contains "Deprecated"`
737
+ };
738
+ }
739
+ if (config.excludeTests !== false) {
740
+ if (opts.storybookTitle && TEST_TITLE_RE.test(opts.storybookTitle)) {
741
+ return {
742
+ excluded: true,
743
+ reason: "test-story",
744
+ detail: `Title "${opts.storybookTitle}" ends with /test(s)`
745
+ };
746
+ }
747
+ if (TEST_FILE_RE.test(opts.filePath)) {
748
+ return {
749
+ excluded: true,
750
+ reason: "test-story",
751
+ detail: `File path matches *.test.stories.*`
752
+ };
753
+ }
754
+ }
755
+ if (config.excludeSvgIcons !== false) {
756
+ const names = [opts.componentName, opts.componentDisplayName, opts.componentFunctionName].filter(Boolean);
757
+ for (const name of names) {
758
+ if (SVG_ICON_RE.test(name)) {
759
+ return {
760
+ excluded: true,
761
+ reason: "svg-icon",
762
+ detail: `Component name "${name}" matches Svg[A-Z] pattern`
763
+ };
764
+ }
765
+ }
766
+ }
767
+ if (opts.tags?.length) {
768
+ const hit = opts.tags.find((t) => EXCLUDED_TAGS.has(t));
769
+ if (hit) {
770
+ return {
771
+ excluded: true,
772
+ reason: "tag-excluded",
773
+ detail: `Tag "${hit}" is in the exclusion set`
774
+ };
775
+ }
776
+ }
777
+ if (opts.variantCount === 0) {
778
+ return {
779
+ excluded: true,
780
+ reason: "empty-variants",
781
+ detail: "Zero renderable story exports"
782
+ };
783
+ }
784
+ return { excluded: false };
785
+ }
786
+ function detectSubComponentPaths(storyFiles) {
787
+ const byDir = /* @__PURE__ */ new Map();
788
+ for (const file of storyFiles) {
789
+ const parts = file.relativePath.split("/");
790
+ if (parts.length < 2) continue;
791
+ const fileName = parts[parts.length - 1];
792
+ const baseMatch = fileName.match(/^([^.]+)\.stories\./);
793
+ if (!baseMatch) continue;
794
+ const dir = parts.slice(0, -1).join("/");
795
+ const baseName = baseMatch[1];
796
+ if (!byDir.has(dir)) byDir.set(dir, []);
797
+ byDir.get(dir).push({ relativePath: file.relativePath, baseName });
798
+ }
799
+ const subComponentMap = /* @__PURE__ */ new Map();
800
+ for (const [dir, files] of byDir) {
801
+ if (files.length <= 1) continue;
802
+ const dirName = dir.split("/").pop();
803
+ const primary = files.find((f) => f.baseName === dirName);
804
+ if (!primary) continue;
805
+ for (const file of files) {
806
+ if (file.relativePath === primary.relativePath) continue;
807
+ subComponentMap.set(file.relativePath, primary.baseName);
808
+ }
809
+ }
810
+ return subComponentMap;
811
+ }
812
+ function isForceIncluded(name, config) {
813
+ if (!config.include?.length) return false;
814
+ return config.include.some((pattern) => matchesPattern(name, pattern));
815
+ }
816
+ function isConfigExcluded(name, config) {
817
+ if (!config.exclude?.length) return false;
818
+ return config.exclude.some((pattern) => matchesPattern(name, pattern));
819
+ }
820
+ function matchesPattern(name, pattern) {
821
+ if (!pattern.includes("*")) {
822
+ return name === pattern;
823
+ }
824
+ const parts = pattern.split("*");
825
+ if (parts.length === 2) {
826
+ const [prefix, suffix] = parts;
827
+ if (prefix && suffix) return name.startsWith(prefix) && name.endsWith(suffix);
828
+ if (prefix) return name.startsWith(prefix);
829
+ if (suffix) return name.endsWith(suffix);
830
+ return true;
831
+ }
832
+ const escaped = parts.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*");
833
+ return new RegExp(`^${escaped}$`).test(name);
834
+ }
475
835
  function string(figmaProperty) {
476
836
  return {
477
837
  __type: "figma-string",
@@ -550,8 +910,6 @@ function resolveFigmaMapping(mapping, figmaValues) {
550
910
  return void 0;
551
911
  }
552
912
  }
553
-
554
- // src/core/token-parser.ts
555
913
  var NAMING_RULES = [
556
914
  { pattern: /--\w+-font-/, category: "typography" },
557
915
  { pattern: /--\w+-line-height-/, category: "typography" },
@@ -729,9 +1087,6 @@ function parseTokenFile(content, filePath) {
729
1087
  total: tokens.length
730
1088
  };
731
1089
  }
732
-
733
- // src/core/composition.ts
734
- import { ComponentGraphEngine } from "@fragments-sdk/context/graph";
735
1090
  var CATEGORY_AFFINITIES = {
736
1091
  forms: ["feedback"],
737
1092
  actions: ["feedback"]
@@ -921,10 +1276,6 @@ function findBestCategoryCandidate(fragments, category, selectedSet, suggestedSe
921
1276
  }
922
1277
  return best;
923
1278
  }
924
-
925
- // src/core/preview-runtime.tsx
926
- import { useEffect, useState } from "react";
927
- import { Fragment, jsx } from "react/jsx-runtime";
928
1279
  var EMPTY_STATE = {
929
1280
  content: null,
930
1281
  isLoading: false,
@@ -1008,11 +1359,27 @@ function PreviewVariantRuntime({
1008
1359
  }
1009
1360
 
1010
1361
  export {
1362
+ BRAND,
1363
+ DEFAULTS,
1011
1364
  PRESET_NAMES,
1012
1365
  resolvePerformanceConfig,
1013
1366
  classifyComplexity,
1014
1367
  formatBytes,
1015
1368
  budgetBar,
1369
+ figmaPropMappingSchema,
1370
+ fragmentMetaSchema,
1371
+ fragmentUsageSchema,
1372
+ propDefinitionSchema,
1373
+ componentRelationSchema,
1374
+ fragmentVariantSchema,
1375
+ fragmentBanSchema,
1376
+ fragmentContractSchema,
1377
+ fragmentGeneratedSchema,
1378
+ aiMetadataSchema,
1379
+ blockDefinitionSchema,
1380
+ fragmentDefinitionSchema,
1381
+ fragmentsConfigSchema,
1382
+ recipeDefinitionSchema,
1016
1383
  defineFragment,
1017
1384
  compileFragment,
1018
1385
  defineBlock,
@@ -1025,6 +1392,10 @@ export {
1025
1392
  setPreviewConfig,
1026
1393
  getPreviewConfig,
1027
1394
  storyModuleToFragment,
1395
+ checkStoryExclusion,
1396
+ detectSubComponentPaths,
1397
+ isForceIncluded,
1398
+ isConfigExcluded,
1028
1399
  generateContext,
1029
1400
  figma,
1030
1401
  isFigmaPropMapping,
@@ -1036,4 +1407,4 @@ export {
1036
1407
  usePreviewVariantRuntime,
1037
1408
  PreviewVariantRuntime
1038
1409
  };
1039
- //# sourceMappingURL=chunk-GF6OVPIN.js.map
1410
+ //# sourceMappingURL=chunk-OQO55NKV.js.map