@fragments-sdk/cli 0.7.0 → 0.7.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 (171) hide show
  1. package/dist/bin.js +245 -245
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-XHUDJNN3.js → chunk-32VIEOQY.js} +18 -18
  4. package/dist/chunk-32VIEOQY.js.map +1 -0
  5. package/dist/{chunk-CVXKXVOY.js → chunk-5ITIP3ES.js} +27 -27
  6. package/dist/chunk-5ITIP3ES.js.map +1 -0
  7. package/dist/{chunk-RVRTRESS.js → chunk-DQHWLAUV.js} +29 -29
  8. package/dist/chunk-DQHWLAUV.js.map +1 -0
  9. package/dist/{chunk-TJ34N7C7.js → chunk-GCZMFLDI.js} +30 -32
  10. package/dist/chunk-GCZMFLDI.js.map +1 -0
  11. package/dist/{chunk-6JBGU74P.js → chunk-GHYYFAQN.js} +23 -23
  12. package/dist/chunk-GHYYFAQN.js.map +1 -0
  13. package/dist/{chunk-NWQ4CJOQ.js → chunk-GKX2HPZ6.js} +40 -40
  14. package/dist/chunk-GKX2HPZ6.js.map +1 -0
  15. package/dist/{chunk-7OPWMLOE.js → chunk-U6VTHBNI.js} +110 -110
  16. package/dist/chunk-U6VTHBNI.js.map +1 -0
  17. package/dist/{core-W2HYIQW6.js → core-SFHPYR5H.js} +24 -26
  18. package/dist/{generate-LMTISDIJ.js → generate-54GJAWUY.js} +5 -5
  19. package/dist/generate-54GJAWUY.js.map +1 -0
  20. package/dist/index.d.ts +23 -27
  21. package/dist/index.js +10 -10
  22. package/dist/{init-7CHRKQ7P.js → init-EIM5WNMP.js} +5 -5
  23. package/dist/{init-7CHRKQ7P.js.map → init-EIM5WNMP.js.map} +1 -1
  24. package/dist/mcp-bin.js +73 -73
  25. package/dist/mcp-bin.js.map +1 -1
  26. package/dist/scan-KQBKUS64.js +12 -0
  27. package/dist/{service-T2L7VLTE.js → service-ED2LNCTU.js} +6 -6
  28. package/dist/{static-viewer-GBR7YNF3.js → static-viewer-Q4F4QP5M.js} +4 -4
  29. package/dist/{test-OJRXNDO2.js → test-6VN2DA3S.js} +19 -19
  30. package/dist/test-6VN2DA3S.js.map +1 -0
  31. package/dist/{tokens-3BWDESVM.js → tokens-P2B7ZAM3.js} +5 -5
  32. package/dist/{viewer-SUFOISZM.js → viewer-GM7IQPPB.js} +199 -199
  33. package/dist/viewer-GM7IQPPB.js.map +1 -0
  34. package/package.json +2 -2
  35. package/src/ai.ts +5 -5
  36. package/src/analyze.ts +11 -11
  37. package/src/bin.ts +1 -1
  38. package/src/build.ts +33 -33
  39. package/src/commands/a11y.ts +6 -6
  40. package/src/commands/add.ts +11 -11
  41. package/src/commands/audit.ts +4 -4
  42. package/src/commands/baseline.ts +3 -3
  43. package/src/commands/build.ts +8 -8
  44. package/src/commands/compare.ts +20 -20
  45. package/src/commands/context.ts +16 -16
  46. package/src/commands/enhance.ts +36 -36
  47. package/src/commands/generate.ts +1 -1
  48. package/src/commands/graph.ts +3 -3
  49. package/src/commands/init.ts +1 -1
  50. package/src/commands/link/figma.ts +82 -82
  51. package/src/commands/link/index.ts +3 -3
  52. package/src/commands/link/storybook.ts +9 -9
  53. package/src/commands/list.ts +2 -2
  54. package/src/commands/reset.ts +15 -15
  55. package/src/commands/scan.ts +27 -27
  56. package/src/commands/storygen.ts +24 -24
  57. package/src/commands/validate.ts +2 -2
  58. package/src/commands/verify.ts +8 -8
  59. package/src/core/auto-props.ts +4 -4
  60. package/src/core/composition.test.ts +36 -36
  61. package/src/core/composition.ts +19 -19
  62. package/src/core/config.ts +6 -6
  63. package/src/core/{defineSegment.ts → defineFragment.ts} +16 -22
  64. package/src/core/discovery.ts +6 -6
  65. package/src/core/figma.ts +2 -2
  66. package/src/core/graph-extractor.test.ts +77 -77
  67. package/src/core/graph-extractor.ts +32 -32
  68. package/src/core/importAnalyzer.ts +1 -1
  69. package/src/core/index.ts +22 -23
  70. package/src/core/loader.ts +22 -22
  71. package/src/core/node.ts +5 -5
  72. package/src/core/parser.ts +31 -31
  73. package/src/core/previewLoader.ts +1 -1
  74. package/src/core/schema.ts +16 -16
  75. package/src/core/storyAdapter.test.ts +87 -87
  76. package/src/core/storyAdapter.ts +16 -16
  77. package/src/core/types.ts +21 -26
  78. package/src/diff.ts +22 -22
  79. package/src/index.ts +2 -2
  80. package/src/mcp/server.ts +80 -80
  81. package/src/migrate/__tests__/utils/utils.test.ts +3 -3
  82. package/src/migrate/bin.ts +4 -4
  83. package/src/migrate/converter.ts +16 -16
  84. package/src/migrate/index.ts +3 -3
  85. package/src/migrate/migrate.ts +3 -3
  86. package/src/migrate/parser.ts +8 -8
  87. package/src/migrate/report.ts +2 -2
  88. package/src/migrate/types.ts +4 -4
  89. package/src/screenshot.ts +22 -22
  90. package/src/service/__tests__/props-extractor.test.ts +15 -15
  91. package/src/service/analytics.ts +39 -39
  92. package/src/service/enhance/codebase-scanner.ts +1 -1
  93. package/src/service/enhance/index.ts +1 -1
  94. package/src/service/enhance/props-extractor.ts +2 -2
  95. package/src/service/enhance/types.ts +2 -2
  96. package/src/service/index.ts +2 -2
  97. package/src/service/metrics-store.ts +1 -1
  98. package/src/service/patch-generator.ts +1 -1
  99. package/src/setup.ts +52 -52
  100. package/src/shared/dev-server-client.ts +7 -7
  101. package/src/shared/fragment-loader.ts +59 -0
  102. package/src/shared/index.ts +1 -1
  103. package/src/shared/types.ts +4 -4
  104. package/src/static-viewer.ts +35 -35
  105. package/src/test/discovery.ts +6 -6
  106. package/src/test/index.ts +5 -5
  107. package/src/test/reporters/console.ts +1 -1
  108. package/src/test/reporters/junit.ts +1 -1
  109. package/src/test/runner.ts +7 -7
  110. package/src/test/types.ts +3 -3
  111. package/src/test/watch.ts +9 -9
  112. package/src/validators.ts +26 -26
  113. package/src/viewer/__tests__/render-utils.test.ts +28 -28
  114. package/src/viewer/__tests__/viewer-integration.test.ts +4 -4
  115. package/src/viewer/cli/health.ts +26 -26
  116. package/src/viewer/components/App.tsx +79 -79
  117. package/src/viewer/components/BottomPanel.tsx +17 -17
  118. package/src/viewer/components/CodePanel.tsx +3 -3
  119. package/src/viewer/components/CommandPalette.tsx +11 -11
  120. package/src/viewer/components/ComponentGraph.tsx +28 -28
  121. package/src/viewer/components/ComponentHeader.tsx +2 -2
  122. package/src/viewer/components/ContractPanel.tsx +6 -6
  123. package/src/viewer/components/FigmaEmbed.tsx +9 -9
  124. package/src/viewer/components/HealthDashboard.tsx +17 -17
  125. package/src/viewer/components/InteractionsPanel.tsx +2 -2
  126. package/src/viewer/components/IsolatedPreviewFrame.tsx +6 -6
  127. package/src/viewer/components/IsolatedRender.tsx +10 -10
  128. package/src/viewer/components/LeftSidebar.tsx +28 -28
  129. package/src/viewer/components/MultiViewportPreview.tsx +14 -14
  130. package/src/viewer/components/PreviewArea.tsx +11 -11
  131. package/src/viewer/components/PreviewFrameHost.tsx +51 -51
  132. package/src/viewer/components/RightSidebar.tsx +9 -9
  133. package/src/viewer/components/Sidebar.tsx +17 -17
  134. package/src/viewer/components/StoryRenderer.tsx +2 -2
  135. package/src/viewer/components/TokenStylePanel.tsx +1 -1
  136. package/src/viewer/components/UsageSection.tsx +2 -2
  137. package/src/viewer/components/VariantMatrix.tsx +11 -11
  138. package/src/viewer/components/VariantRenderer.tsx +3 -3
  139. package/src/viewer/components/VariantTabs.tsx +2 -2
  140. package/src/viewer/components/_future/CreatePage.tsx +6 -6
  141. package/src/viewer/composition-renderer.ts +11 -11
  142. package/src/viewer/entry.tsx +40 -40
  143. package/src/viewer/hooks/useFigmaIntegration.ts +1 -1
  144. package/src/viewer/hooks/usePreviewBridge.ts +5 -5
  145. package/src/viewer/hooks/useUrlState.ts +6 -6
  146. package/src/viewer/index.ts +2 -2
  147. package/src/viewer/intelligence/healthReport.ts +17 -17
  148. package/src/viewer/intelligence/styleDrift.ts +1 -1
  149. package/src/viewer/intelligence/usageScanner.ts +1 -1
  150. package/src/viewer/render-template.html +1 -1
  151. package/src/viewer/render-utils.ts +21 -21
  152. package/src/viewer/server.ts +18 -18
  153. package/src/viewer/utils/detectRelationships.ts +22 -22
  154. package/src/viewer/vite-plugin.ts +213 -213
  155. package/dist/chunk-6JBGU74P.js.map +0 -1
  156. package/dist/chunk-7OPWMLOE.js.map +0 -1
  157. package/dist/chunk-CVXKXVOY.js.map +0 -1
  158. package/dist/chunk-NWQ4CJOQ.js.map +0 -1
  159. package/dist/chunk-RVRTRESS.js.map +0 -1
  160. package/dist/chunk-TJ34N7C7.js.map +0 -1
  161. package/dist/chunk-XHUDJNN3.js.map +0 -1
  162. package/dist/generate-LMTISDIJ.js.map +0 -1
  163. package/dist/scan-WY23TJCP.js +0 -12
  164. package/dist/test-OJRXNDO2.js.map +0 -1
  165. package/dist/viewer-SUFOISZM.js.map +0 -1
  166. package/src/shared/segment-loader.ts +0 -59
  167. /package/dist/{core-W2HYIQW6.js.map → core-SFHPYR5H.js.map} +0 -0
  168. /package/dist/{scan-WY23TJCP.js.map → scan-KQBKUS64.js.map} +0 -0
  169. /package/dist/{service-T2L7VLTE.js.map → service-ED2LNCTU.js.map} +0 -0
  170. /package/dist/{static-viewer-GBR7YNF3.js.map → static-viewer-Q4F4QP5M.js.map} +0 -0
  171. /package/dist/{tokens-3BWDESVM.js.map → tokens-P2B7ZAM3.js.map} +0 -0
package/dist/bin.js CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
3
3
  import {
4
+ buildFragments,
4
5
  buildFragmentsDir,
5
- buildSegments,
6
6
  runAnalyzeCommand,
7
7
  runDiffCommand,
8
8
  runScreenshotCommand,
9
9
  validateAll,
10
10
  validateCoverage,
11
11
  validateSchema
12
- } from "./chunk-7OPWMLOE.js";
12
+ } from "./chunk-U6VTHBNI.js";
13
13
  import {
14
14
  scan
15
- } from "./chunk-XHUDJNN3.js";
15
+ } from "./chunk-32VIEOQY.js";
16
16
  import {
17
17
  FigmaClient,
18
18
  StorageManager,
@@ -28,18 +28,18 @@ import {
28
28
  renderAllComponentVariants,
29
29
  scanCodebase,
30
30
  shutdownSharedPool
31
- } from "./chunk-NWQ4CJOQ.js";
31
+ } from "./chunk-GKX2HPZ6.js";
32
32
  import {
33
- discoverSegmentFiles,
33
+ discoverFragmentFiles,
34
34
  loadConfig,
35
- loadSegmentFile
36
- } from "./chunk-CVXKXVOY.js";
35
+ loadFragmentFile
36
+ } from "./chunk-5ITIP3ES.js";
37
37
  import {
38
38
  generateContext
39
- } from "./chunk-TJ34N7C7.js";
39
+ } from "./chunk-GCZMFLDI.js";
40
40
  import {
41
41
  BRAND
42
- } from "./chunk-6JBGU74P.js";
42
+ } from "./chunk-GHYYFAQN.js";
43
43
 
44
44
  // src/bin.ts
45
45
  import { Command } from "commander";
@@ -116,7 +116,7 @@ ${BRAND.name} Build (from source)
116
116
  });
117
117
  return {
118
118
  success: scanResult.success,
119
- segmentCount: scanResult.componentCount,
119
+ fragmentCount: scanResult.componentCount,
120
120
  outputPath: scanResult.outputPath,
121
121
  errors: scanResult.errors.map((e) => ({ file: e.component, error: e.error }))
122
122
  };
@@ -129,14 +129,14 @@ ${BRAND.name} Build (from source)
129
129
  ${BRAND.name} Build
130
130
  `));
131
131
  const errors = [];
132
- let segmentCount;
132
+ let fragmentCount;
133
133
  let outputPath;
134
134
  let componentCount;
135
135
  let registryPath;
136
136
  let contextPath;
137
137
  if (!options.registryOnly) {
138
138
  console.log(pc2.dim("Compiling fragments...\n"));
139
- const result = await buildSegments(config, configDir);
139
+ const result = await buildFragments(config, configDir);
140
140
  if (result.errors.length > 0) {
141
141
  console.log(pc2.yellow("Build completed with errors:\n"));
142
142
  for (const error of result.errors) {
@@ -152,9 +152,9 @@ ${BRAND.name} Build
152
152
  }
153
153
  console.log();
154
154
  }
155
- segmentCount = result.segmentCount;
155
+ fragmentCount = result.fragmentCount;
156
156
  outputPath = result.outputPath;
157
- console.log(pc2.green(`\u2713 Built ${result.segmentCount} fragment(s)`));
157
+ console.log(pc2.green(`\u2713 Built ${result.fragmentCount} fragment(s)`));
158
158
  console.log(pc2.dim(` Output: ${result.outputPath}
159
159
  `));
160
160
  }
@@ -186,7 +186,7 @@ ${BRAND.name} Build
186
186
  }
187
187
  return {
188
188
  success: errors.length === 0,
189
- segmentCount,
189
+ fragmentCount,
190
190
  outputPath,
191
191
  componentCount,
192
192
  registryPath,
@@ -207,28 +207,28 @@ async function context(options = {}) {
207
207
  includeRelations = false,
208
208
  tokensOnly = false
209
209
  } = options;
210
- let segments;
210
+ let fragments;
211
211
  if (options.input) {
212
212
  const inputPath = resolve(process.cwd(), options.input);
213
213
  const content2 = await readFile(inputPath, "utf-8");
214
214
  const data = JSON.parse(content2);
215
- segments = Object.values(data.segments);
215
+ fragments = Object.values(data.fragments);
216
216
  } else {
217
217
  const { config, configDir } = await loadConfig(options.config);
218
- const result = await buildSegments(config, configDir);
219
- if (result.errors.length > 0 && result.segmentCount === 0) {
220
- console.error(pc3.red("Error: No segments found. Run `segments build` first or fix errors."));
218
+ const result = await buildFragments(config, configDir);
219
+ if (result.errors.length > 0 && result.fragmentCount === 0) {
220
+ console.error(pc3.red("Error: No fragments found. Run `fragments build` first or fix errors."));
221
221
  return { success: false, tokenEstimate: 0 };
222
222
  }
223
223
  const content2 = await readFile(result.outputPath, "utf-8");
224
224
  const data = JSON.parse(content2);
225
- segments = Object.values(data.segments);
225
+ fragments = Object.values(data.fragments);
226
226
  }
227
- if (segments.length === 0) {
228
- console.error(pc3.red("No segments found."));
227
+ if (fragments.length === 0) {
228
+ console.error(pc3.red("No fragments found."));
229
229
  return { success: false, tokenEstimate: 0 };
230
230
  }
231
- const { content, tokenEstimate } = generateContext(segments, {
231
+ const { content, tokenEstimate } = generateContext(fragments, {
232
232
  format,
233
233
  compact,
234
234
  include: {
@@ -254,7 +254,7 @@ async function context(options = {}) {
254
254
  import pc4 from "picocolors";
255
255
  async function list(options = {}) {
256
256
  const { config, configDir } = await loadConfig(options.config);
257
- const files = await discoverSegmentFiles(config, configDir);
257
+ const files = await discoverFragmentFiles(config, configDir);
258
258
  console.log(pc4.cyan(`
259
259
  ${BRAND.name} - Discovered Fragments
260
260
  `));
@@ -293,7 +293,7 @@ ${BRAND.name} Reset
293
293
  }
294
294
  } catch {
295
295
  }
296
- const defaultOutFile = join(projectRoot, "segments.json");
296
+ const defaultOutFile = join(projectRoot, "fragments.json");
297
297
  try {
298
298
  const fileStat = await stat(defaultOutFile);
299
299
  if (fileStat.isFile()) {
@@ -301,10 +301,10 @@ ${BRAND.name} Reset
301
301
  }
302
302
  } catch {
303
303
  }
304
- let segmentPatterns = [`**/*${BRAND.fileExtension}`];
304
+ let fragmentPatterns = [`**/*${BRAND.fileExtension}`];
305
305
  try {
306
306
  const { config } = await loadConfig();
307
- if (config.outFile && config.outFile !== "segments.json") {
307
+ if (config.outFile && config.outFile !== "fragments.json") {
308
308
  const customOutFile = join(projectRoot, config.outFile);
309
309
  try {
310
310
  const fileStat = await stat(customOutFile);
@@ -315,12 +315,12 @@ ${BRAND.name} Reset
315
315
  }
316
316
  }
317
317
  if (config.include && config.include.length > 0) {
318
- segmentPatterns = config.include;
318
+ fragmentPatterns = config.include;
319
319
  }
320
320
  } catch {
321
321
  }
322
322
  console.log(pc5.dim("Scanning for generated files...\n"));
323
- for (const pattern of segmentPatterns) {
323
+ for (const pattern of fragmentPatterns) {
324
324
  const matches = await fg(pattern, {
325
325
  cwd: projectRoot,
326
326
  ignore: ["**/node_modules/**"],
@@ -351,22 +351,22 @@ ${BRAND.name} Reset
351
351
  const relativePath = relative(projectRoot, dir);
352
352
  console.log(` \u{1F4C1} ${relativePath}/`);
353
353
  }
354
- const segmentFiles = filesToDelete.filter((f) => f.endsWith(BRAND.fileExtension));
354
+ const fragmentFiles = filesToDelete.filter((f) => f.endsWith(BRAND.fileExtension));
355
355
  const mdxFilesFound = filesToDelete.filter((f) => f.endsWith(".mdx"));
356
356
  const otherFiles = filesToDelete.filter(
357
357
  (f) => !f.endsWith(BRAND.fileExtension) && !f.endsWith(".mdx")
358
358
  );
359
- if (segmentFiles.length > 0) {
360
- console.log(` \u{1F4C4} ${segmentFiles.length} segment file(s) (*${BRAND.fileExtension})`);
361
- if (segmentFiles.length <= 5) {
362
- for (const f of segmentFiles) {
359
+ if (fragmentFiles.length > 0) {
360
+ console.log(` \u{1F4C4} ${fragmentFiles.length} fragment file(s) (*${BRAND.fileExtension})`);
361
+ if (fragmentFiles.length <= 5) {
362
+ for (const f of fragmentFiles) {
363
363
  console.log(pc5.dim(` ${relative(projectRoot, f)}`));
364
364
  }
365
365
  } else {
366
- for (const f of segmentFiles.slice(0, 3)) {
366
+ for (const f of fragmentFiles.slice(0, 3)) {
367
367
  console.log(pc5.dim(` ${relative(projectRoot, f)}`));
368
368
  }
369
- console.log(pc5.dim(` ... and ${segmentFiles.length - 3} more`));
369
+ console.log(pc5.dim(` ... and ${fragmentFiles.length - 3} more`));
370
370
  }
371
371
  }
372
372
  if (mdxFilesFound.length > 0) {
@@ -565,8 +565,8 @@ function parseMeta(content, filePath, warnings) {
565
565
  const selectedTitle = componentPathTitle ?? titleMatches[0];
566
566
  if (selectedTitle) {
567
567
  result.title = selectedTitle;
568
- const segments = result.title.split("/");
569
- result.componentName = segments[segments.length - 1];
568
+ const fragments = result.title.split("/");
569
+ result.componentName = fragments[fragments.length - 1];
570
570
  }
571
571
  const componentMatch = content.match(/component:\s*(\w+)/);
572
572
  if (componentMatch) {
@@ -1127,9 +1127,9 @@ function storyNameToTitle(name) {
1127
1127
  return name.replace(/([A-Z])/g, " $1").trim().replace(/\s+/g, " ");
1128
1128
  }
1129
1129
  function extractCategory(title) {
1130
- const segments = title.split("/");
1131
- if (segments.length >= 2) {
1132
- const category = segments[segments.length - 2];
1130
+ const fragments = title.split("/");
1131
+ if (fragments.length >= 2) {
1132
+ const category = fragments[fragments.length - 2];
1133
1133
  return category.toLowerCase();
1134
1134
  }
1135
1135
  return "components";
@@ -1139,14 +1139,14 @@ function extractCategory(title) {
1139
1139
  function sanitizeComponentName(name) {
1140
1140
  return name.split(/[\s-_]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("").replace(/[^a-zA-Z0-9]/g, "");
1141
1141
  }
1142
- function convertToSegment(parsed) {
1142
+ function convertToFragment(parsed) {
1143
1143
  const warnings = [...parsed.warnings];
1144
1144
  const todos = [];
1145
1145
  const category = extractCategory(parsed.meta.title);
1146
1146
  const componentName = sanitizeComponentName(parsed.meta.componentName);
1147
1147
  if (!parsed.meta.componentImport) {
1148
1148
  warnings.push(`No importable component found - story may define component locally`);
1149
- const outputFile2 = parsed.filePath.replace(/\.stories\.(tsx?|jsx?|mdx)$/, ".segment.tsx");
1149
+ const outputFile2 = parsed.filePath.replace(/\.stories\.(tsx?|jsx?|mdx)$/, ".fragment.tsx");
1150
1150
  return {
1151
1151
  sourceFile: parsed.filePath,
1152
1152
  outputFile: outputFile2,
@@ -1174,7 +1174,7 @@ function convertToSegment(parsed) {
1174
1174
  }
1175
1175
  }
1176
1176
  const skippedVariants = variants.filter((v) => v.needsManualReview && v.skipReason).map((v) => ({ name: v.name, reason: v.skipReason }));
1177
- const code = generateSegmentCode({
1177
+ const code = generateFragmentCode({
1178
1178
  componentName,
1179
1179
  componentImport: parsed.meta.componentImport,
1180
1180
  description: parsed.meta.description,
@@ -1191,7 +1191,7 @@ function convertToSegment(parsed) {
1191
1191
  skippedVariants: skippedVariants.length > 0 ? skippedVariants : void 0
1192
1192
  }
1193
1193
  });
1194
- const outputFile = parsed.filePath.replace(/\.stories\.(tsx?|jsx?|mdx)$/, ".segment.tsx");
1194
+ const outputFile = parsed.filePath.replace(/\.stories\.(tsx?|jsx?|mdx)$/, ".fragment.tsx");
1195
1195
  return {
1196
1196
  sourceFile: parsed.filePath,
1197
1197
  outputFile,
@@ -1408,7 +1408,7 @@ function formatValueForObject(value) {
1408
1408
  }
1409
1409
  return JSON.stringify(value);
1410
1410
  }
1411
- function generateSegmentCode(options) {
1411
+ function generateFragmentCode(options) {
1412
1412
  const {
1413
1413
  componentName,
1414
1414
  componentImport,
@@ -1439,10 +1439,10 @@ ${generated.skippedVariants.map((sv) => ` { name: "${escapeString(sv.name)}
1439
1439
  },
1440
1440
  `;
1441
1441
  }
1442
- return `import { defineSegment } from "@fragments/core";
1442
+ return `import { defineFragment } from "@fragments/core";
1443
1443
  import { ${componentName} } from "${componentImport}";
1444
1444
 
1445
- export default defineSegment({
1445
+ export default defineFragment({
1446
1446
  component: ${componentName},
1447
1447
 
1448
1448
  meta: {
@@ -1627,21 +1627,21 @@ async function discoverStoryFiles(projectRoot, patterns) {
1627
1627
  }
1628
1628
 
1629
1629
  // src/setup.ts
1630
- async function isSegmentsJsonStale(configDir, outFile) {
1630
+ async function isFragmentsJsonStale(configDir, outFile) {
1631
1631
  const fs2 = await import("fs/promises");
1632
1632
  const path = await import("path");
1633
1633
  const fg4 = await import("fast-glob");
1634
- const segmentsJsonPath = path.join(configDir, outFile);
1634
+ const fragmentsJsonPath = path.join(configDir, outFile);
1635
1635
  try {
1636
- const segmentsJsonStat = await fs2.stat(segmentsJsonPath);
1637
- const segmentFiles = await fg4.default(`**/*${BRAND.fileExtension}`, {
1636
+ const fragmentsJsonStat = await fs2.stat(fragmentsJsonPath);
1637
+ const fragmentFiles = await fg4.default(`**/*${BRAND.fileExtension}`, {
1638
1638
  cwd: configDir,
1639
1639
  ignore: ["**/node_modules/**"],
1640
1640
  absolute: true
1641
1641
  });
1642
- for (const file of segmentFiles) {
1642
+ for (const file of fragmentFiles) {
1643
1643
  const stat3 = await fs2.stat(file);
1644
- if (stat3.mtimeMs > segmentsJsonStat.mtimeMs) {
1644
+ if (stat3.mtimeMs > fragmentsJsonStat.mtimeMs) {
1645
1645
  return { stale: true, missing: false };
1646
1646
  }
1647
1647
  }
@@ -1650,16 +1650,16 @@ async function isSegmentsJsonStale(configDir, outFile) {
1650
1650
  return { stale: false, missing: true };
1651
1651
  }
1652
1652
  }
1653
- async function loadSegmentInfo(segmentFiles) {
1653
+ async function loadFragmentInfo(fragmentFiles) {
1654
1654
  const fs2 = await import("fs/promises");
1655
- const segments = [];
1656
- for (const file of segmentFiles) {
1655
+ const fragments = [];
1656
+ for (const file of fragmentFiles) {
1657
1657
  try {
1658
1658
  const content = await fs2.readFile(file.absolutePath, "utf-8");
1659
1659
  const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
1660
1660
  const hasFigma = /meta:\s*\{[^}]*figma:\s*['"]https?:/.test(content);
1661
1661
  if (nameMatch) {
1662
- segments.push({
1662
+ fragments.push({
1663
1663
  name: nameMatch[1],
1664
1664
  filePath: file.absolutePath,
1665
1665
  hasFigma
@@ -1668,14 +1668,14 @@ async function loadSegmentInfo(segmentFiles) {
1668
1668
  } catch {
1669
1669
  }
1670
1670
  }
1671
- return segments;
1671
+ return fragments;
1672
1672
  }
1673
1673
  async function runSetup(options = {}) {
1674
1674
  const fs2 = await import("fs/promises");
1675
1675
  const path = await import("path");
1676
1676
  const result = {
1677
- segmentFilesCreated: 0,
1678
- segmentsBuilt: 0,
1677
+ fragmentFilesCreated: 0,
1678
+ fragmentsBuilt: 0,
1679
1679
  figmaLinked: 0,
1680
1680
  errors: []
1681
1681
  };
@@ -1685,8 +1685,8 @@ async function runSetup(options = {}) {
1685
1685
  try {
1686
1686
  const { config, configDir } = await loadConfig(options.configPath);
1687
1687
  log(pc6.dim("Checking for fragment files..."));
1688
- let segmentFiles = await discoverSegmentFiles(config, configDir);
1689
- if (segmentFiles.length === 0 && !options.skipStorybook) {
1688
+ let fragmentFiles = await discoverFragmentFiles(config, configDir);
1689
+ if (fragmentFiles.length === 0 && !options.skipStorybook) {
1690
1690
  log(pc6.yellow("\n No fragment files found"));
1691
1691
  const sbConfig = await detectStorybookConfig(configDir);
1692
1692
  if (sbConfig) {
@@ -1698,40 +1698,40 @@ async function runSetup(options = {}) {
1698
1698
  for (const storyFile of storyFiles) {
1699
1699
  try {
1700
1700
  const parsed = await parseStoryFile(storyFile);
1701
- const segmentResult = convertToSegment(parsed);
1702
- await fs2.mkdir(path.dirname(segmentResult.outputFile), { recursive: true });
1703
- await fs2.writeFile(segmentResult.outputFile, segmentResult.code);
1701
+ const fragmentResult = convertToFragment(parsed);
1702
+ await fs2.mkdir(path.dirname(fragmentResult.outputFile), { recursive: true });
1703
+ await fs2.writeFile(fragmentResult.outputFile, fragmentResult.code);
1704
1704
  converted++;
1705
1705
  } catch {
1706
1706
  }
1707
1707
  }
1708
- result.segmentFilesCreated = converted;
1708
+ result.fragmentFilesCreated = converted;
1709
1709
  log(pc6.green(` Generated ${converted} fragment file(s)`));
1710
- segmentFiles = await discoverSegmentFiles(config, configDir);
1710
+ fragmentFiles = await discoverFragmentFiles(config, configDir);
1711
1711
  }
1712
1712
  } else {
1713
1713
  log(pc6.dim(" No Storybook config found"));
1714
1714
  log(pc6.dim(` Run ${pc6.cyan(`${BRAND.cliCommand} add <ComponentName>`)} to create your first fragment`));
1715
1715
  }
1716
- } else if (segmentFiles.length > 0) {
1717
- log(pc6.green(` Found ${segmentFiles.length} fragment file(s)`));
1716
+ } else if (fragmentFiles.length > 0) {
1717
+ log(pc6.green(` Found ${fragmentFiles.length} fragment file(s)`));
1718
1718
  }
1719
- if (segmentFiles.length > 0 && !options.skipBuild) {
1719
+ if (fragmentFiles.length > 0 && !options.skipBuild) {
1720
1720
  const outFile = config.outFile || BRAND.outFile;
1721
- const { stale, missing } = await isSegmentsJsonStale(configDir, outFile);
1721
+ const { stale, missing } = await isFragmentsJsonStale(configDir, outFile);
1722
1722
  if (missing || stale) {
1723
1723
  const reason = missing ? "Building" : "Rebuilding";
1724
1724
  log(pc6.dim(`
1725
1725
  ${reason} ${BRAND.outFile}...`));
1726
1726
  try {
1727
- const buildResult = await buildSegments(config, configDir);
1728
- result.segmentsBuilt = buildResult.segmentCount;
1727
+ const buildResult = await buildFragments(config, configDir);
1728
+ result.fragmentsBuilt = buildResult.fragmentCount;
1729
1729
  if (buildResult.errors.length > 0) {
1730
1730
  for (const err of buildResult.errors) {
1731
1731
  result.errors.push(`${err.file}: ${err.error}`);
1732
1732
  }
1733
1733
  }
1734
- log(pc6.green(` Built ${buildResult.segmentCount} fragment(s)`));
1734
+ log(pc6.green(` Built ${buildResult.fragmentCount} fragment(s)`));
1735
1735
  } catch (error) {
1736
1736
  result.errors.push(`Build failed: ${error instanceof Error ? error.message : "Unknown error"}`);
1737
1737
  }
@@ -1741,14 +1741,14 @@ ${reason} ${BRAND.outFile}...`));
1741
1741
  }
1742
1742
  }
1743
1743
  if (!options.skipFigma && config.figmaFile && process.env.FIGMA_ACCESS_TOKEN) {
1744
- const segments = await loadSegmentInfo(segmentFiles);
1745
- const linkedCount = segments.filter((s) => s.hasFigma).length;
1746
- if (linkedCount === 0 && segments.length > 0) {
1744
+ const fragments = await loadFragmentInfo(fragmentFiles);
1745
+ const linkedCount = fragments.filter((s) => s.hasFigma).length;
1746
+ if (linkedCount === 0 && fragments.length > 0) {
1747
1747
  log(pc6.dim("\n Figma configured but no fragments linked"));
1748
1748
  log(pc6.dim(` Run ${pc6.cyan(`${BRAND.cliCommand} link figma --auto`)} to auto-link components`));
1749
1749
  } else if (linkedCount > 0) {
1750
1750
  log(pc6.dim(`
1751
- ${linkedCount}/${segments.length} fragment(s) linked to Figma`));
1751
+ ${linkedCount}/${fragments.length} fragment(s) linked to Figma`));
1752
1752
  }
1753
1753
  } else if (!options.skipFigma && config.figmaFile && !process.env.FIGMA_ACCESS_TOKEN) {
1754
1754
  log(pc6.dim("\n Figma file configured but FIGMA_ACCESS_TOKEN not set"));
@@ -1785,7 +1785,7 @@ ${BRAND.name} Dev Server
1785
1785
  }
1786
1786
  }
1787
1787
  }
1788
- const { createDevServer } = await import("./viewer-SUFOISZM.js");
1788
+ const { createDevServer } = await import("./viewer-GM7IQPPB.js");
1789
1789
  console.log(pc7.dim("\nStarting dev server..."));
1790
1790
  const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
1791
1791
  try {
@@ -1871,7 +1871,7 @@ ${BRAND.name} Design Verification
1871
1871
  let passed = 0;
1872
1872
  let failed = 0;
1873
1873
  for (const comp of componentsToCompare) {
1874
- const response = await fetch(`${baseUrl}/segments/compare`, {
1874
+ const response = await fetch(`${baseUrl}/fragments/compare`, {
1875
1875
  method: "POST",
1876
1876
  headers: { "Content-Type": "application/json" },
1877
1877
  body: JSON.stringify({
@@ -1921,35 +1921,35 @@ ${pc8.green(`${passed} passed`)}, ${pc8.red(`${failed} failed`)}
1921
1921
  }
1922
1922
  async function compareAll(baseUrl, threshold, output) {
1923
1923
  console.log(pc8.dim("Comparing all components with Figma links...\n"));
1924
- const contextResp = await fetch(`${baseUrl}/segments/context?format=json`);
1924
+ const contextResp = await fetch(`${baseUrl}/fragments/context?format=json`);
1925
1925
  if (!contextResp.ok) {
1926
- throw new Error("Failed to fetch segments. Make sure dev server is running.");
1926
+ throw new Error("Failed to fetch fragments. Make sure dev server is running.");
1927
1927
  }
1928
1928
  const contextText = await contextResp.text();
1929
- let segments = [];
1929
+ let fragments = [];
1930
1930
  try {
1931
1931
  const contextData = JSON.parse(contextText);
1932
- segments = contextData.components || [];
1932
+ fragments = contextData.components || [];
1933
1933
  } catch {
1934
- segments = [];
1934
+ fragments = [];
1935
1935
  }
1936
- if (segments.length === 0) {
1936
+ if (fragments.length === 0) {
1937
1937
  console.log(pc8.yellow("No components found with Figma links."));
1938
- console.log(pc8.dim("Add figma field to your segment definitions:"));
1938
+ console.log(pc8.dim("Add figma field to your fragment definitions:"));
1939
1939
  console.log(pc8.dim(' meta: { figma: "https://figma.com/file/..." }'));
1940
1940
  return { success: true, passed: 0, failed: 0, skipped: 0 };
1941
1941
  }
1942
1942
  let passed = 0;
1943
1943
  let failed = 0;
1944
1944
  let skipped = 0;
1945
- for (const seg of segments) {
1945
+ for (const seg of fragments) {
1946
1946
  if (!seg.figma) {
1947
1947
  skipped++;
1948
1948
  console.log(`${pc8.dim("\u23ED\uFE0F")} ${pc8.dim(seg.name)} ${pc8.dim("(no figma link)")}`);
1949
1949
  continue;
1950
1950
  }
1951
1951
  try {
1952
- const response = await fetch(`${baseUrl}/segments/compare`, {
1952
+ const response = await fetch(`${baseUrl}/fragments/compare`, {
1953
1953
  method: "POST",
1954
1954
  headers: { "Content-Type": "application/json" },
1955
1955
  body: JSON.stringify({
@@ -1995,27 +1995,27 @@ ${pc8.green(`${passed} passed`)}, ${pc8.red(`${failed} failed`)}, ${pc8.dim(`${s
1995
1995
  }
1996
1996
  async function selectComponents(baseUrl) {
1997
1997
  console.log(pc8.dim("Fetching components with Figma links...\n"));
1998
- const contextResp = await fetch(`${baseUrl}/segments/context?format=json`);
1998
+ const contextResp = await fetch(`${baseUrl}/fragments/context?format=json`);
1999
1999
  if (!contextResp.ok) {
2000
- throw new Error("Failed to fetch segments. Make sure dev server is running.");
2000
+ throw new Error("Failed to fetch fragments. Make sure dev server is running.");
2001
2001
  }
2002
2002
  const contextText = await contextResp.text();
2003
- let segments = [];
2003
+ let fragments = [];
2004
2004
  try {
2005
2005
  const contextData = JSON.parse(contextText);
2006
- segments = (contextData.components || []).filter((s) => s.figma);
2006
+ fragments = (contextData.components || []).filter((s) => s.figma);
2007
2007
  } catch {
2008
- segments = [];
2008
+ fragments = [];
2009
2009
  }
2010
- if (segments.length === 0) {
2010
+ if (fragments.length === 0) {
2011
2011
  console.log(pc8.yellow("No components found with Figma links."));
2012
- console.log(pc8.dim("Add figma field to your segment definitions:"));
2012
+ console.log(pc8.dim("Add figma field to your fragment definitions:"));
2013
2013
  console.log(pc8.dim(' meta: { figma: "https://figma.com/file/..." }'));
2014
2014
  return [];
2015
2015
  }
2016
2016
  const { checkbox } = await import("@inquirer/prompts");
2017
2017
  try {
2018
- const choices = segments.map((seg) => ({
2018
+ const choices = fragments.map((seg) => ({
2019
2019
  name: seg.name,
2020
2020
  value: seg.name,
2021
2021
  checked: true
@@ -2066,7 +2066,7 @@ var DevServerClient = class {
2066
2066
  try {
2067
2067
  const controller = new AbortController();
2068
2068
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
2069
- const response = await fetch(`${this.baseUrl}/segments/context?format=json`, {
2069
+ const response = await fetch(`${this.baseUrl}/fragments/context?format=json`, {
2070
2070
  signal: controller.signal
2071
2071
  });
2072
2072
  clearTimeout(timeoutId);
@@ -2076,10 +2076,10 @@ var DevServerClient = class {
2076
2076
  }
2077
2077
  }
2078
2078
  /**
2079
- * Get all segments from the context endpoint
2079
+ * Get all fragments from the context endpoint
2080
2080
  */
2081
- async getSegments() {
2082
- const response = await this.fetch("/segments/context?format=json");
2081
+ async getFragments() {
2082
+ const response = await this.fetch("/fragments/context?format=json");
2083
2083
  const data = await response.json();
2084
2084
  const components = data.components || {};
2085
2085
  return Object.entries(components).map(([name, info]) => ({
@@ -2094,7 +2094,7 @@ var DevServerClient = class {
2094
2094
  * Get compliance data for a component
2095
2095
  */
2096
2096
  async getCompliance(request) {
2097
- const response = await this.fetch("/segments/compliance", {
2097
+ const response = await this.fetch("/fragments/compliance", {
2098
2098
  method: "POST",
2099
2099
  headers: { "Content-Type": "application/json" },
2100
2100
  body: JSON.stringify(request)
@@ -2198,12 +2198,12 @@ ${BRAND.name} Compliance Verification
2198
2198
  `http://localhost:${port}`
2199
2199
  );
2200
2200
  }
2201
- let segments = await client.getSegments();
2201
+ let fragments = await client.getFragments();
2202
2202
  if (component) {
2203
- segments = segments.filter(
2203
+ fragments = fragments.filter(
2204
2204
  (s) => s.name.toLowerCase() === component.toLowerCase()
2205
2205
  );
2206
- if (segments.length === 0) {
2206
+ if (fragments.length === 0) {
2207
2207
  const error = { error: `Component "${component}" not found` };
2208
2208
  if (ci) {
2209
2209
  console.log(JSON.stringify(error));
@@ -2213,7 +2213,7 @@ ${BRAND.name} Compliance Verification
2213
2213
  process.exit(1);
2214
2214
  }
2215
2215
  }
2216
- for (const seg of segments) {
2216
+ for (const seg of fragments) {
2217
2217
  try {
2218
2218
  const complianceResult = await client.getCompliance({
2219
2219
  component: seg.name
@@ -2316,8 +2316,8 @@ ${BRAND.name} Design System Audit
2316
2316
  `http://localhost:${port}`
2317
2317
  );
2318
2318
  }
2319
- const segments = await client.getSegments();
2320
- if (segments.length === 0) {
2319
+ const fragments = await client.getFragments();
2320
+ if (fragments.length === 0) {
2321
2321
  if (json) {
2322
2322
  console.log(JSON.stringify({ error: "No fragments found", components: [] }));
2323
2323
  } else {
@@ -2336,10 +2336,10 @@ ${BRAND.name} Design System Audit
2336
2336
  };
2337
2337
  }
2338
2338
  if (!json) {
2339
- console.log(pc11.dim(`Auditing ${segments.length} component(s)...
2339
+ console.log(pc11.dim(`Auditing ${fragments.length} component(s)...
2340
2340
  `));
2341
2341
  }
2342
- for (const seg of segments) {
2342
+ for (const seg of fragments) {
2343
2343
  try {
2344
2344
  const complianceResult = await client.getCompliance({
2345
2345
  component: seg.name
@@ -3057,8 +3057,8 @@ ${BRAND.name} Accessibility Report
3057
3057
  `http://localhost:${port}`
3058
3058
  );
3059
3059
  }
3060
- const segments = await client.getSegments();
3061
- if (segments.length === 0) {
3060
+ const fragments = await client.getFragments();
3061
+ if (fragments.length === 0) {
3062
3062
  if (isJsonOutput) {
3063
3063
  console.log(JSON.stringify({ error: "No fragments found", components: [] }));
3064
3064
  } else {
@@ -3077,9 +3077,9 @@ ${BRAND.name} Accessibility Report
3077
3077
  passed: true
3078
3078
  };
3079
3079
  }
3080
- const componentsToCheck = component ? segments.filter((s) => s.name.toLowerCase() === component.toLowerCase()) : segments;
3080
+ const componentsToCheck = component ? fragments.filter((s) => s.name.toLowerCase() === component.toLowerCase()) : fragments;
3081
3081
  if (component && componentsToCheck.length === 0) {
3082
- const error = `Component '${component}' not found. Available: ${segments.map((s) => s.name).join(", ")}`;
3082
+ const error = `Component '${component}' not found. Available: ${fragments.map((s) => s.name).join(", ")}`;
3083
3083
  if (isJsonOutput) {
3084
3084
  console.log(JSON.stringify({ error }));
3085
3085
  } else {
@@ -3230,9 +3230,9 @@ async function storygen(options = {}) {
3230
3230
  console.log(pc13.cyan(`
3231
3231
  ${BRAND.name} Story Generator
3232
3232
  `));
3233
- const segmentFiles = await discoverSegmentFiles(config, configDir);
3234
- if (segmentFiles.length === 0) {
3235
- console.log(pc13.yellow("No segment files found.\n"));
3233
+ const fragmentFiles = await discoverFragmentFiles(config, configDir);
3234
+ if (fragmentFiles.length === 0) {
3235
+ console.log(pc13.yellow("No fragment files found.\n"));
3236
3236
  return { success: true, generated: 0, outputDir: output };
3237
3237
  }
3238
3238
  const outputDir = resolve3(configDir, output);
@@ -3240,10 +3240,10 @@ ${BRAND.name} Story Generator
3240
3240
  let generated = 0;
3241
3241
  const generateStory = async (file) => {
3242
3242
  try {
3243
- const segment = await loadSegmentFile(file.absolutePath);
3244
- if (!segment) return false;
3245
- const storyContent = generateCSF3Story(segment, file.relativePath);
3246
- const storyName = `${segment.meta.name}.stories.tsx`;
3243
+ const fragment = await loadFragmentFile(file.absolutePath);
3244
+ if (!fragment) return false;
3245
+ const storyContent = generateCSF3Story(fragment, file.relativePath);
3246
+ const storyName = `${fragment.meta.name}.stories.tsx`;
3247
3247
  const storyPath = join5(outputDir, storyName);
3248
3248
  await writeFile3(storyPath, storyContent);
3249
3249
  console.log(`${pc13.green("\u2713")} Generated ${storyName}`);
@@ -3255,7 +3255,7 @@ ${BRAND.name} Story Generator
3255
3255
  };
3256
3256
  console.log(pc13.dim(`Generating stories to ${relative3(process.cwd(), outputDir)}/
3257
3257
  `));
3258
- for (const file of segmentFiles) {
3258
+ for (const file of fragmentFiles) {
3259
3259
  if (await generateStory(file)) {
3260
3260
  generated++;
3261
3261
  }
@@ -3264,15 +3264,15 @@ ${BRAND.name} Story Generator
3264
3264
  console.log(pc13.green(`\u2713 Generated ${generated} story file(s)
3265
3265
  `));
3266
3266
  if (watch) {
3267
- console.log(pc13.dim("Watching for segment changes... (Ctrl+C to stop)\n"));
3267
+ console.log(pc13.dim("Watching for fragment changes... (Ctrl+C to stop)\n"));
3268
3268
  const chokidar = await import("chokidar");
3269
- const patterns = segmentFiles.map((f) => f.absolutePath);
3269
+ const patterns = fragmentFiles.map((f) => f.absolutePath);
3270
3270
  const watcher = chokidar.watch(patterns, {
3271
3271
  ignoreInitial: true,
3272
3272
  awaitWriteFinish: { stabilityThreshold: 100 }
3273
3273
  });
3274
3274
  watcher.on("change", async (changedPath) => {
3275
- const file = segmentFiles.find((f) => f.absolutePath === changedPath);
3275
+ const file = fragmentFiles.find((f) => f.absolutePath === changedPath);
3276
3276
  if (file) {
3277
3277
  console.log(pc13.dim(`
3278
3278
  Changed: ${relative3(process.cwd(), changedPath)}`));
@@ -3282,10 +3282,10 @@ Changed: ${relative3(process.cwd(), changedPath)}`));
3282
3282
  watcher.on("add", async (addedPath) => {
3283
3283
  console.log(pc13.dim(`
3284
3284
  Added: ${relative3(process.cwd(), addedPath)}`));
3285
- const newFiles = await discoverSegmentFiles(config, configDir);
3285
+ const newFiles = await discoverFragmentFiles(config, configDir);
3286
3286
  const file = newFiles.find((f) => f.absolutePath === addedPath);
3287
3287
  if (file) {
3288
- segmentFiles.push(file);
3288
+ fragmentFiles.push(file);
3289
3289
  await generateStory(file);
3290
3290
  }
3291
3291
  });
@@ -3294,8 +3294,8 @@ Added: ${relative3(process.cwd(), addedPath)}`));
3294
3294
  }
3295
3295
  return { success: true, generated, outputDir };
3296
3296
  }
3297
- function generateCSF3Story(segment, relativePath) {
3298
- const { meta, variants, props, usage } = segment;
3297
+ function generateCSF3Story(fragment, relativePath) {
3298
+ const { meta, variants, props, usage } = fragment;
3299
3299
  const componentName = meta.name;
3300
3300
  const argTypes = [];
3301
3301
  if (props) {
@@ -3335,11 +3335,11 @@ ${usage.whenNot?.map((w) => `- ${w}`).join("\n") || ""}` : "";
3335
3335
  return `/**
3336
3336
  * Auto-generated Storybook stories from ${relativePath}
3337
3337
  *
3338
- * DO NOT EDIT - regenerate with: segments storygen
3338
+ * DO NOT EDIT - regenerate with: fragments storygen
3339
3339
  */
3340
3340
 
3341
3341
  import type { Meta, StoryObj } from '@storybook/react';
3342
- import { ${componentName} } from '${relativePath.replace(/\.segment\.tsx$/, "/index.js")}';
3342
+ import { ${componentName} } from '${relativePath.replace(/\.fragment\.tsx$/, "/index.js")}';
3343
3343
 
3344
3344
  const meta: Meta<typeof ${componentName}> = {
3345
3345
  title: '${meta.category ? `${meta.category.charAt(0).toUpperCase() + meta.category.slice(1)}/` : ""}${componentName}',
@@ -3450,14 +3450,14 @@ async function updateBaseline(component, options, config, configDir, baseUrl) {
3450
3450
  throw new Error("Failed to fetch fragments. Make sure dev server is running.");
3451
3451
  }
3452
3452
  const contextData = JSON.parse(await contextResp.text());
3453
- const segments = contextData.components || [];
3454
- if (segments.length === 0) {
3453
+ const fragments = contextData.components || [];
3454
+ if (fragments.length === 0) {
3455
3455
  console.log(pc15.yellow("No components found.\n"));
3456
3456
  return { success: true, action: "update", count: 0 };
3457
3457
  }
3458
3458
  component = await select({
3459
3459
  message: "Select component to update:",
3460
- choices: segments.map((s) => ({
3460
+ choices: fragments.map((s) => ({
3461
3461
  name: s.name,
3462
3462
  value: s.name
3463
3463
  }))
@@ -3607,7 +3607,7 @@ ${BRAND.name} Component Scaffold
3607
3607
  dir = dir || "src/components";
3608
3608
  const componentDir = resolve4(process.cwd(), dir, componentName);
3609
3609
  const componentFile = join7(componentDir, `${componentName}.tsx`);
3610
- const segmentFile = join7(componentDir, `${componentName}${BRAND.fileExtension}`);
3610
+ const fragmentFile = join7(componentDir, `${componentName}${BRAND.fileExtension}`);
3611
3611
  const indexFile = join7(componentDir, "index.ts");
3612
3612
  try {
3613
3613
  await access2(componentDir);
@@ -3622,9 +3622,9 @@ ${BRAND.name} Component Scaffold
3622
3622
  await writeFile4(componentFile, componentCode);
3623
3623
  console.log(`${pc16.green("\u2713")} Created ${relative5(process.cwd(), componentFile)}`);
3624
3624
  }
3625
- const segmentCode = generateSegmentStub(componentName, category, template);
3626
- await writeFile4(segmentFile, segmentCode);
3627
- console.log(`${pc16.green("\u2713")} Created ${relative5(process.cwd(), segmentFile)}`);
3625
+ const fragmentCode = generateFragmentStub(componentName, category, template);
3626
+ await writeFile4(fragmentFile, fragmentCode);
3627
+ console.log(`${pc16.green("\u2713")} Created ${relative5(process.cwd(), fragmentFile)}`);
3628
3628
  const indexCode = `export { ${componentName} } from './${componentName}.js';
3629
3629
  `;
3630
3630
  await writeFile4(indexFile, indexCode);
@@ -3644,7 +3644,7 @@ ${BRAND.name} Component Scaffold
3644
3644
  return {
3645
3645
  success: true,
3646
3646
  componentPath: generateComponent ? componentFile : void 0,
3647
- segmentPath: segmentFile,
3647
+ fragmentPath: fragmentFile,
3648
3648
  indexPath: indexFile
3649
3649
  };
3650
3650
  }
@@ -3673,7 +3673,7 @@ export function ${name}({ children, className }: ${name}Props) {
3673
3673
  }
3674
3674
  `;
3675
3675
  }
3676
- function generateSegmentStub(name, category, template) {
3676
+ function generateFragmentStub(name, category, template) {
3677
3677
  const usageHints = {
3678
3678
  action: {
3679
3679
  when: ["User needs to trigger an action", "Form submission is required"],
@@ -3701,10 +3701,10 @@ function generateSegmentStub(name, category, template) {
3701
3701
  };
3702
3702
  const scenarioTags = scenarioTagHints[template] || scenarioTagHints.display;
3703
3703
  return `import React from 'react';
3704
- import { defineSegment } from '@fragments/core';
3704
+ import { defineFragment } from '@fragments/core';
3705
3705
  import { ${name} } from './index.js';
3706
3706
 
3707
- export default defineSegment({
3707
+ export default defineFragment({
3708
3708
  component: ${name},
3709
3709
 
3710
3710
  meta: {
@@ -3837,40 +3837,40 @@ ${BRAND.name} Link Wizard
3837
3837
  } else {
3838
3838
  console.log();
3839
3839
  }
3840
- const segmentFiles = await discoverSegmentFiles(config, configDir);
3841
- if (segmentFiles.length === 0) {
3842
- console.log(pc17.yellow("No segment files found in codebase."));
3840
+ const fragmentFiles = await discoverFragmentFiles(config, configDir);
3841
+ if (fragmentFiles.length === 0) {
3842
+ console.log(pc17.yellow("No fragment files found in codebase."));
3843
3843
  console.log(pc17.dim(`Looking for: ${config.include.join(", ")}`));
3844
3844
  process.exit(0);
3845
3845
  }
3846
- console.log(pc17.dim(`Found ${segmentFiles.length} segment file(s)
3846
+ console.log(pc17.dim(`Found ${fragmentFiles.length} fragment file(s)
3847
3847
  `));
3848
- const segments = [];
3849
- for (const file of segmentFiles) {
3848
+ const fragments = [];
3849
+ for (const file of fragmentFiles) {
3850
3850
  try {
3851
3851
  const content = await readFile4(file.absolutePath, "utf-8");
3852
3852
  const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
3853
3853
  const hasFigma = /meta:\s*\{[^}]*figma:\s*['"]https?:/.test(content);
3854
- const segmentVariants = extractVariants(content, nameMatch?.[1]);
3854
+ const fragmentVariants = extractVariants(content, nameMatch?.[1]);
3855
3855
  if (nameMatch) {
3856
- segments.push({
3856
+ fragments.push({
3857
3857
  name: nameMatch[1],
3858
3858
  filePath: file.absolutePath,
3859
3859
  relativePath: file.relativePath,
3860
3860
  hasFigma,
3861
- variants: segmentVariants
3861
+ variants: fragmentVariants
3862
3862
  });
3863
3863
  }
3864
3864
  } catch {
3865
3865
  }
3866
3866
  }
3867
3867
  const matches = [];
3868
- const unmatchedSegments = [];
3869
- for (const segment of segments) {
3868
+ const unmatchedFragments = [];
3869
+ for (const fragment of fragments) {
3870
3870
  let bestMatch = null;
3871
3871
  let bestScore = 0;
3872
3872
  for (const figmaComp of allFigmaComponents) {
3873
- const score = calculateMatchScore(segment.name, figmaComp.name);
3873
+ const score = calculateMatchScore(fragment.name, figmaComp.name);
3874
3874
  if (score > bestScore) {
3875
3875
  bestMatch = figmaComp;
3876
3876
  bestScore = score;
@@ -3878,18 +3878,18 @@ ${BRAND.name} Link Wizard
3878
3878
  }
3879
3879
  }
3880
3880
  if (bestMatch && bestScore >= 65) {
3881
- const alreadyLinked = segment.hasFigma;
3881
+ const alreadyLinked = fragment.hasFigma;
3882
3882
  if (alreadyLinked && !auto) {
3883
- console.log(pc17.dim(`\u23ED\uFE0F ${segment.name} (already linked)`));
3883
+ console.log(pc17.dim(`\u23ED\uFE0F ${fragment.name} (already linked)`));
3884
3884
  }
3885
- matches.push({ segment, figmaComponent: bestMatch, score: bestScore, alreadyLinked });
3885
+ matches.push({ fragment, figmaComponent: bestMatch, score: bestScore, alreadyLinked });
3886
3886
  } else {
3887
- unmatchedSegments.push(segment);
3887
+ unmatchedFragments.push(fragment);
3888
3888
  }
3889
3889
  }
3890
- if (unmatchedSegments.length > 0) {
3891
- console.log(pc17.dim("Unmatched segments:"));
3892
- for (const seg of unmatchedSegments) {
3890
+ if (unmatchedFragments.length > 0) {
3891
+ console.log(pc17.dim("Unmatched fragments:"));
3892
+ for (const seg of unmatchedFragments) {
3893
3893
  console.log(` ${pc17.dim("\u2022")} ${seg.name}`);
3894
3894
  }
3895
3895
  console.log();
@@ -3898,7 +3898,7 @@ ${BRAND.name} Link Wizard
3898
3898
  const alreadyLinkedMatches = matches.filter((m) => m.alreadyLinked);
3899
3899
  if (matches.length === 0) {
3900
3900
  console.log(pc17.yellow("\nNo automatic matches found."));
3901
- console.log(pc17.dim("You can manually add figma URLs to your segment definitions."));
3901
+ console.log(pc17.dim("You can manually add figma URLs to your fragment definitions."));
3902
3902
  process.exit(0);
3903
3903
  }
3904
3904
  if (dryRun) {
@@ -3907,7 +3907,7 @@ ${BRAND.name} Link Wizard
3907
3907
  for (const match of newMatches) {
3908
3908
  const scoreColor = match.score === 100 ? pc17.green : pc17.yellow;
3909
3909
  console.log(
3910
- ` ${pc17.green("\u2713")} ${pc17.bold(match.segment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`
3910
+ ` ${pc17.green("\u2713")} ${pc17.bold(match.fragment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`
3911
3911
  );
3912
3912
  }
3913
3913
  }
@@ -3921,7 +3921,7 @@ ${BRAND.name} Link Wizard
3921
3921
  for (const match of newMatches) {
3922
3922
  const scoreColor = match.score === 100 ? pc17.green : pc17.yellow;
3923
3923
  console.log(
3924
- ` ${pc17.green("\u2713")} ${pc17.bold(match.segment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`
3924
+ ` ${pc17.green("\u2713")} ${pc17.bold(match.fragment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`
3925
3925
  );
3926
3926
  }
3927
3927
  } else {
@@ -3931,7 +3931,7 @@ ${BRAND.name} Link Wizard
3931
3931
  const choices = newMatches.map((match) => {
3932
3932
  const scoreColor = match.score === 100 ? pc17.green : pc17.yellow;
3933
3933
  return {
3934
- name: `${pc17.bold(match.segment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`,
3934
+ name: `${pc17.bold(match.fragment.name)} \u2192 ${match.figmaComponent.name} ${scoreColor(`(${Math.round(match.score)}%)`)}`,
3935
3935
  value: match,
3936
3936
  checked: true
3937
3937
  };
@@ -3953,7 +3953,7 @@ ${BRAND.name} Link Wizard
3953
3953
  for (const match of selectedMatches) {
3954
3954
  if (match.alreadyLinked) continue;
3955
3955
  try {
3956
- let content = await readFile4(match.segment.filePath, "utf-8");
3956
+ let content = await readFile4(match.fragment.filePath, "utf-8");
3957
3957
  const figmaUrlToInsert = figmaClient.buildNodeUrl(
3958
3958
  match.figmaComponent.file_key,
3959
3959
  match.figmaComponent.node_id,
@@ -3971,16 +3971,16 @@ ${BRAND.name} Link Wizard
3971
3971
  figma: '${figmaUrlToInsert}',`
3972
3972
  );
3973
3973
  }
3974
- await writeFile5(match.segment.filePath, content);
3974
+ await writeFile5(match.fragment.filePath, content);
3975
3975
  updated++;
3976
- console.log(` ${pc17.green("\u2713")} Updated ${match.segment.relativePath}`);
3976
+ console.log(` ${pc17.green("\u2713")} Updated ${match.fragment.relativePath}`);
3977
3977
  } catch (error) {
3978
- console.log(` ${pc17.red("\u2717")} Failed to update ${match.segment.relativePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
3978
+ console.log(` ${pc17.red("\u2717")} Failed to update ${match.fragment.relativePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
3979
3979
  }
3980
3980
  }
3981
3981
  if (updated > 0) {
3982
3982
  console.log(pc17.green(`
3983
- \u2713 Updated ${updated} segment file(s)
3983
+ \u2713 Updated ${updated} fragment file(s)
3984
3984
  `));
3985
3985
  }
3986
3986
  let variantUpdates = 0;
@@ -4035,37 +4035,37 @@ function extractVariants(content, componentName) {
4035
4035
  }
4036
4036
  return variants;
4037
4037
  }
4038
- function calculateMatchScore(segmentName, figmaName) {
4038
+ function calculateMatchScore(fragmentName, figmaName) {
4039
4039
  const normalizeForMatch = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
4040
- const normalizedSegment = normalizeForMatch(segmentName);
4040
+ const normalizedFragment = normalizeForMatch(fragmentName);
4041
4041
  const normalizedFigma = normalizeForMatch(figmaName);
4042
- if (normalizedSegment === normalizedFigma) {
4042
+ if (normalizedFragment === normalizedFigma) {
4043
4043
  return 100;
4044
4044
  }
4045
- if (normalizedFigma.startsWith(normalizedSegment)) {
4046
- const coverage = normalizedSegment.length / normalizedFigma.length;
4045
+ if (normalizedFigma.startsWith(normalizedFragment)) {
4046
+ const coverage = normalizedFragment.length / normalizedFigma.length;
4047
4047
  return Math.max(85, coverage * 100);
4048
4048
  }
4049
- if (normalizedSegment.startsWith(normalizedFigma)) {
4050
- const coverage = normalizedFigma.length / normalizedSegment.length;
4049
+ if (normalizedFragment.startsWith(normalizedFigma)) {
4050
+ const coverage = normalizedFigma.length / normalizedFragment.length;
4051
4051
  return Math.max(80, coverage * 100);
4052
4052
  }
4053
4053
  const getWords = (s) => {
4054
4054
  return s.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[^a-zA-Z0-9]+/g, " ").toLowerCase().split(/\s+/).filter((w) => w.length > 0);
4055
4055
  };
4056
- const segmentWords = getWords(segmentName);
4056
+ const fragmentWords = getWords(fragmentName);
4057
4057
  const figmaWords = getWords(figmaName);
4058
- const allSegmentWordsInFigma = segmentWords.every(
4058
+ const allFragmentWordsInFigma = fragmentWords.every(
4059
4059
  (sw) => figmaWords.some((fw) => fw === sw || fw.startsWith(sw) || sw.startsWith(fw))
4060
4060
  );
4061
- if (allSegmentWordsInFigma && segmentWords.length > 0) {
4062
- const wordOverlap = segmentWords.length / Math.max(segmentWords.length, figmaWords.length);
4061
+ if (allFragmentWordsInFigma && fragmentWords.length > 0) {
4062
+ const wordOverlap = fragmentWords.length / Math.max(fragmentWords.length, figmaWords.length);
4063
4063
  return Math.max(75, wordOverlap * 95);
4064
4064
  }
4065
- if (normalizedFigma.includes(normalizedSegment)) {
4065
+ if (normalizedFigma.includes(normalizedFragment)) {
4066
4066
  return 70;
4067
4067
  }
4068
- if (normalizedSegment.includes(normalizedFigma)) {
4068
+ if (normalizedFragment.includes(normalizedFigma)) {
4069
4069
  return 65;
4070
4070
  }
4071
4071
  return 0;
@@ -4089,24 +4089,24 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4089
4089
  if (!csWithVariants || csWithVariants.variants.length === 0) {
4090
4090
  continue;
4091
4091
  }
4092
- const segmentVariants = match.segment.variants.filter((v) => !v.hasFigma);
4093
- if (segmentVariants.length === 0) {
4094
- console.log(pc17.dim(` \u23ED\uFE0F ${match.segment.name}: all variants already linked`));
4092
+ const fragmentVariants = match.fragment.variants.filter((v) => !v.hasFigma);
4093
+ if (fragmentVariants.length === 0) {
4094
+ console.log(pc17.dim(` \u23ED\uFE0F ${match.fragment.name}: all variants already linked`));
4095
4095
  continue;
4096
4096
  }
4097
- console.log(pc17.dim(` ${match.segment.name}: ${csWithVariants.variants.length} Figma variants`));
4098
- for (const segmentVariant of segmentVariants) {
4097
+ console.log(pc17.dim(` ${match.fragment.name}: ${csWithVariants.variants.length} Figma variants`));
4098
+ for (const fragmentVariant of fragmentVariants) {
4099
4099
  const variantMatches = [];
4100
4100
  for (const fv of csWithVariants.variants) {
4101
- const normalizedSegment = normalizeForMatch(segmentVariant.name);
4101
+ const normalizedFragment = normalizeForMatch(fragmentVariant.name);
4102
4102
  for (const value of fv.values) {
4103
4103
  const normalizedValue = normalizeForMatch(value);
4104
- if (normalizedSegment === normalizedValue) {
4104
+ if (normalizedFragment === normalizedValue) {
4105
4105
  variantMatches.push({ figmaVariant: fv, score: 100 });
4106
4106
  break;
4107
- } else if (normalizedValue.includes(normalizedSegment)) {
4107
+ } else if (normalizedValue.includes(normalizedFragment)) {
4108
4108
  variantMatches.push({ figmaVariant: fv, score: 85 });
4109
- } else if (normalizedSegment.includes(normalizedValue)) {
4109
+ } else if (normalizedFragment.includes(normalizedValue)) {
4110
4110
  variantMatches.push({ figmaVariant: fv, score: 75 });
4111
4111
  }
4112
4112
  }
@@ -4120,9 +4120,9 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4120
4120
  figmaData.fileName
4121
4121
  );
4122
4122
  try {
4123
- let content = await readFile4(match.segment.filePath, "utf-8");
4123
+ let content = await readFile4(match.fragment.filePath, "utf-8");
4124
4124
  const namePattern = new RegExp(
4125
- `(name:\\s*['"]${escapeRegExp(segmentVariant.name)}['"],?)`,
4125
+ `(name:\\s*['"]${escapeRegExp(fragmentVariant.name)}['"],?)`,
4126
4126
  "g"
4127
4127
  );
4128
4128
  let replaced = false;
@@ -4132,14 +4132,14 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4132
4132
  return `${matchedStr}
4133
4133
  figma: '${variantUrl}',`;
4134
4134
  });
4135
- await writeFile5(match.segment.filePath, content);
4135
+ await writeFile5(match.fragment.filePath, content);
4136
4136
  variantUpdates++;
4137
4137
  console.log(
4138
- ` ${pc17.green("\u2713")} ${segmentVariant.name} \u2192 ${bestMatch.figmaVariant.name}`
4138
+ ` ${pc17.green("\u2713")} ${fragmentVariant.name} \u2192 ${bestMatch.figmaVariant.name}`
4139
4139
  );
4140
4140
  } catch (error) {
4141
4141
  console.log(
4142
- ` ${pc17.red("\u2717")} ${segmentVariant.name}: ${error instanceof Error ? error.message : "Unknown error"}`
4142
+ ` ${pc17.red("\u2717")} ${fragmentVariant.name}: ${error instanceof Error ? error.message : "Unknown error"}`
4143
4143
  );
4144
4144
  }
4145
4145
  } else if (variantMatches.length > 0) {
@@ -4152,7 +4152,7 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4152
4152
  ];
4153
4153
  try {
4154
4154
  const selectedVariant = await select({
4155
- message: ` Match for "${segmentVariant.name}":`,
4155
+ message: ` Match for "${fragmentVariant.name}":`,
4156
4156
  choices
4157
4157
  });
4158
4158
  if (selectedVariant) {
@@ -4161,9 +4161,9 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4161
4161
  selectedVariant.node_id,
4162
4162
  figmaData.fileName
4163
4163
  );
4164
- let content = await readFile4(match.segment.filePath, "utf-8");
4164
+ let content = await readFile4(match.fragment.filePath, "utf-8");
4165
4165
  const namePattern = new RegExp(
4166
- `(name:\\s*['"]${escapeRegExp(segmentVariant.name)}['"],?)`,
4166
+ `(name:\\s*['"]${escapeRegExp(fragmentVariant.name)}['"],?)`,
4167
4167
  "g"
4168
4168
  );
4169
4169
  let replaced = false;
@@ -4173,19 +4173,19 @@ async function linkVariants(matches, figmaData, figmaClient, fileKey) {
4173
4173
  return `${matchedStr}
4174
4174
  figma: '${variantUrl}',`;
4175
4175
  });
4176
- await writeFile5(match.segment.filePath, content);
4176
+ await writeFile5(match.fragment.filePath, content);
4177
4177
  variantUpdates++;
4178
4178
  console.log(
4179
- ` ${pc17.green("\u2713")} ${segmentVariant.name} \u2192 ${selectedVariant.name}`
4179
+ ` ${pc17.green("\u2713")} ${fragmentVariant.name} \u2192 ${selectedVariant.name}`
4180
4180
  );
4181
4181
  } else {
4182
- console.log(` ${pc17.dim("\u23ED\uFE0F")} ${segmentVariant.name} (skipped)`);
4182
+ console.log(` ${pc17.dim("\u23ED\uFE0F")} ${fragmentVariant.name} (skipped)`);
4183
4183
  }
4184
4184
  } catch {
4185
- console.log(` ${pc17.dim("\u23ED\uFE0F")} ${segmentVariant.name} (cancelled)`);
4185
+ console.log(` ${pc17.dim("\u23ED\uFE0F")} ${fragmentVariant.name} (cancelled)`);
4186
4186
  }
4187
4187
  } else {
4188
- console.log(` ${pc17.yellow("?")} ${segmentVariant.name}: no matching Figma variant`);
4188
+ console.log(` ${pc17.yellow("?")} ${fragmentVariant.name}: no matching Figma variant`);
4189
4189
  }
4190
4190
  }
4191
4191
  }
@@ -4246,7 +4246,7 @@ ${BRAND.name} Storybook Link
4246
4246
  process.stdout.write(`\r ${pc18.dim(`[${i + 1}/${total}]`)} ${relativePath.slice(0, 60).padEnd(60)}`);
4247
4247
  try {
4248
4248
  const parsed = await parseStoryFile(storyFile);
4249
- const result = convertToSegment(parsed);
4249
+ const result = convertToFragment(parsed);
4250
4250
  const outputFile = out ? join8(out, relativePath.replace(/\.stories\.(tsx?|jsx?)$/, BRAND.fileExtension)) : result.outputFile;
4251
4251
  previews.push({
4252
4252
  componentName: result.componentName,
@@ -4288,14 +4288,14 @@ ${parseErrors} file(s) could not be parsed (use --verbose for details)`));
4288
4288
  }
4289
4289
  if (dryRun) {
4290
4290
  console.log(pc18.dim(`
4291
- ${previews.length} segment file(s) would be created`));
4291
+ ${previews.length} fragment file(s) would be created`));
4292
4292
  console.log(pc18.yellow("\n[Dry run - no files were written]"));
4293
4293
  return { success: true, generated: 0 };
4294
4294
  }
4295
4295
  let selectedPreviews = previews;
4296
4296
  if (yes) {
4297
4297
  console.log(pc18.dim(`
4298
- ${previews.length} segment file(s) will be created`));
4298
+ ${previews.length} fragment file(s) will be created`));
4299
4299
  } else {
4300
4300
  const { checkbox } = await import("@inquirer/prompts");
4301
4301
  console.log(pc18.dim("\nUse \u2191/\u2193 to navigate, Space to toggle, Enter to confirm\n"));
@@ -4325,7 +4325,7 @@ ${previews.length} segment file(s) will be created`));
4325
4325
  }
4326
4326
  const genTotal = selectedPreviews.length;
4327
4327
  console.log(pc18.dim(`
4328
- Generating ${genTotal} segment file(s)...
4328
+ Generating ${genTotal} fragment file(s)...
4329
4329
  `));
4330
4330
  let generated = 0;
4331
4331
  let genErrors = 0;
@@ -4334,7 +4334,7 @@ Generating ${genTotal} segment file(s)...
4334
4334
  const storyFile = join8(projectRoot, preview.sourceFile);
4335
4335
  try {
4336
4336
  const parsed = await parseStoryFile(storyFile);
4337
- const result = convertToSegment(parsed);
4337
+ const result = convertToFragment(parsed);
4338
4338
  const outputFile = out ? join8(projectRoot, out, preview.sourceFile.replace(/\.stories\.(tsx?|jsx?)$/, BRAND.fileExtension)) : result.outputFile;
4339
4339
  await mkdir6(dirname3(outputFile), { recursive: true });
4340
4340
  await writeFile6(outputFile, result.code);
@@ -4346,7 +4346,7 @@ Generating ${genTotal} segment file(s)...
4346
4346
  }
4347
4347
  }
4348
4348
  console.log(pc18.green(`
4349
- \u2713 Generated ${generated} segment file(s)
4349
+ \u2713 Generated ${generated} fragment file(s)
4350
4350
  `));
4351
4351
  console.log(pc18.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4352
4352
  console.log(pc18.bold("\nNext steps:"));
@@ -4456,8 +4456,8 @@ ${BRAND.name} AI Enhancement
4456
4456
  if (isInteractive) {
4457
4457
  console.log(pc19.dim("Phase 3: Loading fragment files..."));
4458
4458
  }
4459
- const segmentFiles = await findSegmentFiles(rootDir);
4460
- if (segmentFiles.length === 0) {
4459
+ const fragmentFiles = await findFragmentFiles(rootDir);
4460
+ if (fragmentFiles.length === 0) {
4461
4461
  const msg = "No fragment files found";
4462
4462
  if (format === "json") {
4463
4463
  console.log(JSON.stringify({ success: false, error: msg }));
@@ -4467,27 +4467,27 @@ ${BRAND.name} AI Enhancement
4467
4467
  return { success: false, enhanced: [], totalTokens: 0, estimatedCost: 0 };
4468
4468
  }
4469
4469
  if (isInteractive) {
4470
- console.log(pc19.green(` Found ${segmentFiles.length} fragment files`));
4470
+ console.log(pc19.green(` Found ${fragmentFiles.length} fragment files`));
4471
4471
  }
4472
4472
  let componentsToEnhance;
4473
4473
  if (component && component !== "all") {
4474
4474
  componentsToEnhance = [component];
4475
4475
  } else {
4476
- componentsToEnhance = segmentFiles.map((f) => extractComponentName(f));
4476
+ componentsToEnhance = fragmentFiles.map((f) => extractComponentName(f));
4477
4477
  }
4478
4478
  if (isInteractive) {
4479
4479
  console.log(pc19.dim("Phase 4: Extracting props from TypeScript interfaces..."));
4480
4480
  }
4481
4481
  const propsExtractions = /* @__PURE__ */ new Map();
4482
4482
  for (const compName of componentsToEnhance) {
4483
- const segmentFile = segmentFiles.find((f) => extractComponentName(f) === compName);
4484
- if (!segmentFile) continue;
4485
- const segmentDir = segmentFile.replace(/\.segment\.(tsx?|jsx?)$/, "");
4483
+ const fragmentFile = fragmentFiles.find((f) => extractComponentName(f) === compName);
4484
+ if (!fragmentFile) continue;
4485
+ const fragmentDir = fragmentFile.replace(/\.fragment\.(tsx?|jsx?)$/, "");
4486
4486
  const possiblePaths = [
4487
- `${segmentDir}.tsx`,
4488
- `${segmentDir}.ts`,
4489
- `${segmentDir}/index.tsx`,
4490
- `${segmentDir}/index.ts`,
4487
+ `${fragmentDir}.tsx`,
4488
+ `${fragmentDir}.ts`,
4489
+ `${fragmentDir}/index.tsx`,
4490
+ `${fragmentDir}/index.ts`,
4491
4491
  join9(rootDir, "src", "components", `${compName}.tsx`),
4492
4492
  join9(rootDir, "src", "components", compName, `${compName}.tsx`),
4493
4493
  join9(rootDir, "src", "components", compName, "index.tsx")
@@ -4555,9 +4555,9 @@ ${BRAND.name} AI Enhancement
4555
4555
  for (const compName of componentsToEnhance) {
4556
4556
  const analysis = usageAnalysis.components[compName];
4557
4557
  const stories = storyFiles.get(compName);
4558
- const segmentFile = segmentFiles.find((f) => extractComponentName(f) === compName);
4558
+ const fragmentFile = fragmentFiles.find((f) => extractComponentName(f) === compName);
4559
4559
  const propsExtraction = propsExtractions.get(compName);
4560
- if (!segmentFile) continue;
4560
+ if (!fragmentFile) continue;
4561
4561
  const context2 = generateComponentContext(
4562
4562
  compName,
4563
4563
  analysis,
@@ -4565,7 +4565,7 @@ ${BRAND.name} AI Enhancement
4565
4565
  stories,
4566
4566
  propsExtraction
4567
4567
  );
4568
- contexts.push({ name: compName, context: context2, segmentFile });
4568
+ contexts.push({ name: compName, context: context2, fragmentFile });
4569
4569
  }
4570
4570
  if (isContextMode) {
4571
4571
  return handleContextOnlyMode(contexts, format, isInteractive);
@@ -4578,7 +4578,7 @@ Phase 6: Generating AI enhancements for ${componentsToEnhance.length} component(
4578
4578
  const enhanced = [];
4579
4579
  let totalTokens = 0;
4580
4580
  const aiClient = await createAIClient(provider, apiKey);
4581
- for (const { name: compName, context: context2, segmentFile } of contexts) {
4581
+ for (const { name: compName, context: context2, fragmentFile } of contexts) {
4582
4582
  if (!context2.usageAnalysis || context2.usageAnalysis.totalUsages < 2) {
4583
4583
  enhanced.push({
4584
4584
  componentName: compName,
@@ -4629,22 +4629,22 @@ Phase 6: Generating AI enhancements for ${componentsToEnhance.length} component(
4629
4629
  const estimatedCost = calculateCost(provider, totalTokens);
4630
4630
  if (!dryRun) {
4631
4631
  if (isInteractive) {
4632
- console.log(pc19.dim("\nPhase 7: Updating segment files..."));
4632
+ console.log(pc19.dim("\nPhase 7: Updating fragment files..."));
4633
4633
  }
4634
4634
  for (const result of enhanced) {
4635
4635
  if (result.skipped || result.added.when.length === 0 && result.added.whenNot.length === 0) {
4636
4636
  continue;
4637
4637
  }
4638
- const segmentFile = segmentFiles.find((f) => extractComponentName(f) === result.componentName);
4639
- if (!segmentFile) continue;
4638
+ const fragmentFile = fragmentFiles.find((f) => extractComponentName(f) === result.componentName);
4639
+ if (!fragmentFile) continue;
4640
4640
  try {
4641
- await updateSegmentFile(segmentFile, result.added);
4641
+ await updateFragmentFile(fragmentFile, result.added);
4642
4642
  if (isInteractive) {
4643
- console.log(pc19.green(` Updated: ${relative7(rootDir, segmentFile)}`));
4643
+ console.log(pc19.green(` Updated: ${relative7(rootDir, fragmentFile)}`));
4644
4644
  }
4645
4645
  } catch {
4646
4646
  if (isInteractive) {
4647
- console.log(pc19.red(` Failed to update: ${relative7(rootDir, segmentFile)}`));
4647
+ console.log(pc19.red(` Failed to update: ${relative7(rootDir, fragmentFile)}`));
4648
4648
  }
4649
4649
  }
4650
4650
  }
@@ -4727,7 +4727,7 @@ For each component, provide your response in JSON format:
4727
4727
  console.log(pc19.dim("\u2500".repeat(60)));
4728
4728
  console.log();
4729
4729
  console.log(pc19.green("Tip: In Cursor, press Cmd+L to open chat and paste this prompt."));
4730
- console.log(pc19.dim("After getting suggestions, manually update your segment files."));
4730
+ console.log(pc19.dim("After getting suggestions, manually update your fragment files."));
4731
4731
  console.log();
4732
4732
  }
4733
4733
  return {
@@ -4878,19 +4878,19 @@ function calculateCost(provider, tokens) {
4878
4878
  };
4879
4879
  return tokens / 1e6 * costsPer1M[provider];
4880
4880
  }
4881
- async function findSegmentFiles(dir) {
4881
+ async function findFragmentFiles(dir) {
4882
4882
  const fg4 = await import("fast-glob");
4883
- return fg4.default(["**/*.segment.tsx", "**/*.segment.ts"], {
4883
+ return fg4.default(["**/*.fragment.tsx", "**/*.fragment.ts"], {
4884
4884
  cwd: dir,
4885
4885
  absolute: true,
4886
4886
  ignore: ["**/node_modules/**", "**/dist/**"]
4887
4887
  });
4888
4888
  }
4889
4889
  function extractComponentName(filePath) {
4890
- const match = filePath.match(/([^/\\]+)\.segment\.(tsx?|jsx?)$/);
4890
+ const match = filePath.match(/([^/\\]+)\.fragment\.(tsx?|jsx?)$/);
4891
4891
  return match ? match[1] : "";
4892
4892
  }
4893
- async function updateSegmentFile(filePath, suggestions) {
4893
+ async function updateFragmentFile(filePath, suggestions) {
4894
4894
  const content = await readFile5(filePath, "utf-8");
4895
4895
  let updated = content;
4896
4896
  if (suggestions.when.length > 0) {
@@ -5505,7 +5505,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
5505
5505
  process.exit(1);
5506
5506
  }
5507
5507
  });
5508
- program.command("storygen").description("Generate Storybook stories from fragment definitions").option("-c, --config <path>", "Path to config file").option("-o, --output <dir>", "Output directory", ".storybook/generated").option("--watch", "Watch for segment changes and regenerate").option("--format <format>", "Story format (csf3)", "csf3").action(async (options) => {
5508
+ program.command("storygen").description("Generate Storybook stories from fragment definitions").option("-c, --config <path>", "Path to config file").option("-o, --output <dir>", "Output directory", ".storybook/generated").option("--watch", "Watch for fragment changes and regenerate").option("--format <format>", "Story format (csf3)", "csf3").action(async (options) => {
5509
5509
  try {
5510
5510
  await storygen({
5511
5511
  config: options.config,
@@ -5550,7 +5550,7 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
5550
5550
  });
5551
5551
  program.command("view").description(`Generate a static HTML viewer for ${BRAND.outFile}`).option("-i, --input <path>", `Path to ${BRAND.outFile}`, BRAND.outFile).option("-o, --output <path>", "Output HTML file path", BRAND.viewerHtmlFile).option("--open", "Open in browser after generation").action(async (options) => {
5552
5552
  try {
5553
- const { generateViewerFromJson } = await import("./static-viewer-GBR7YNF3.js");
5553
+ const { generateViewerFromJson } = await import("./static-viewer-Q4F4QP5M.js");
5554
5554
  const fs2 = await import("fs/promises");
5555
5555
  const path = await import("path");
5556
5556
  const inputPath = path.resolve(process.cwd(), options.input);
@@ -5598,7 +5598,7 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
5598
5598
  });
5599
5599
  program.command("init").description("Initialize fragments in a project (interactive by default)").option("--force", "Overwrite existing config").option("-y, --yes", "Non-interactive mode - auto-detect and use defaults").action(async (options) => {
5600
5600
  try {
5601
- const { init } = await import("./init-7CHRKQ7P.js");
5601
+ const { init } = await import("./init-EIM5WNMP.js");
5602
5602
  const result = await init({
5603
5603
  projectRoot: process.cwd(),
5604
5604
  force: options.force,
@@ -5618,7 +5618,7 @@ program.command("init").description("Initialize fragments in a project (interact
5618
5618
  });
5619
5619
  program.command("tokens").description("Discover and list design tokens from CSS/SCSS files").option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--categories", "Group tokens by category").option("--theme <theme>", "Filter by theme name").option("--category <category>", "Filter by category (color, spacing, typography, etc.)").option("--verbose", "Show all tokens (no truncation)").action(async (options) => {
5620
5620
  try {
5621
- const { tokens } = await import("./tokens-3BWDESVM.js");
5621
+ const { tokens } = await import("./tokens-P2B7ZAM3.js");
5622
5622
  const result = await tokens({
5623
5623
  config: options.config,
5624
5624
  json: options.json,
@@ -5637,7 +5637,7 @@ program.command("tokens").description("Discover and list design tokens from CSS/
5637
5637
  });
5638
5638
  program.command("generate").description("Generate fragment files from component source code").argument("[component]", "Specific component name to generate (optional)").option("--force", "Overwrite existing fragment files").option("--pattern <glob>", "Pattern for component files", "src/components/**/*.tsx").action(async (component, options) => {
5639
5639
  try {
5640
- const { generate } = await import("./generate-LMTISDIJ.js");
5640
+ const { generate } = await import("./generate-54GJAWUY.js");
5641
5641
  const result = await generate({
5642
5642
  projectRoot: process.cwd(),
5643
5643
  component,
@@ -5664,7 +5664,7 @@ program.command("graph").description("Query the component relationship graph").a
5664
5664
  program.command("test").description("Run interaction tests for fragments with play functions").option("-c, --config <path>", "Path to config file").option("--component <name>", "Filter by component name").option("--tags <tags>", "Filter by tags (comma-separated)").option("--grep <pattern>", "Filter by variant name pattern").option("--exclude <pattern>", "Exclude tests matching pattern").option("--parallel <count>", "Number of parallel browser contexts", parseInt, 4).option("--timeout <ms>", "Timeout per test in milliseconds", parseInt, 3e4).option("--retries <count>", "Number of retries for failed tests", parseInt, 0).option("--bail", "Stop on first failure").option("--browser <name>", "Browser to use (chromium, firefox, webkit)", "chromium").option("--headed", "Run in headed mode (show browser)").option("--a11y", "Run accessibility checks with axe-core").option("--visual", "Capture screenshots for visual regression").option("--update-snapshots", "Update visual snapshots").option("--watch", "Watch mode - re-run on file changes").option("--reporters <names>", "Reporters to use (console, junit, json)", "console").option("-o, --output <dir>", "Output directory for results", "./test-results").option("--server-url <url>", "URL of running dev server (skips starting server)").option("-p, --port <port>", "Port for dev server", parseInt, 6006).option("--ci", "CI mode - non-interactive, exit with code 1 on failure").option("--list", "List available tests without running them").action(async (options) => {
5665
5665
  try {
5666
5666
  const { config, configDir } = await loadConfig(options.config);
5667
- const { runTestCommand, listTests } = await import("./test-OJRXNDO2.js");
5667
+ const { runTestCommand, listTests } = await import("./test-6VN2DA3S.js");
5668
5668
  if (options.list) {
5669
5669
  await listTests(config, configDir, {
5670
5670
  component: options.component,