@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
@@ -9,16 +9,16 @@
9
9
  */
10
10
 
11
11
  import { useMemo, useState } from "react";
12
- import type { SegmentDefinition, ComponentRelation, RelationshipType } from "../../core/index.js";
12
+ import type { FragmentDefinition, ComponentRelation, RelationshipType } from "../../core/index.js";
13
13
  import { ChevronRightIcon, EmptyIcon, WandIcon } from "./Icons.js";
14
14
  import { detectAllRelationships, mergeRelationships } from "../utils/detectRelationships.js";
15
15
  import { Stack, Text, Badge, Button, EmptyState, CodeBlock, Grid, Separator } from "@fragments/ui";
16
16
 
17
17
  interface ComponentGraphProps {
18
- /** Current segment definition */
19
- segment: SegmentDefinition | null;
20
- /** All available segments for navigation */
21
- allSegments: Array<{ path: string; segment: SegmentDefinition }>;
18
+ /** Current fragment definition */
19
+ fragment: FragmentDefinition | null;
20
+ /** All available fragments for navigation */
21
+ allFragments: Array<{ path: string; fragment: FragmentDefinition }>;
22
22
  /** Callback when a component is clicked */
23
23
  onNavigate?: (componentName: string) => void;
24
24
  }
@@ -68,24 +68,24 @@ const RELATIONSHIP_CONFIG: Record<RelationshipType, { label: string; color: stri
68
68
  },
69
69
  };
70
70
 
71
- export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGraphProps) {
71
+ export function ComponentGraph({ fragment, allFragments, onNavigate }: ComponentGraphProps) {
72
72
  const [showAutoDetected, setShowAutoDetected] = useState(true);
73
73
 
74
74
  // Auto-detect relationships
75
75
  const detectedRelationships = useMemo(() => {
76
- if (!segment) return [];
76
+ if (!fragment) return [];
77
77
  try {
78
- return detectAllRelationships(segment, allSegments);
78
+ return detectAllRelationships(fragment, allFragments);
79
79
  } catch {
80
80
  return [];
81
81
  }
82
- }, [segment, allSegments]);
82
+ }, [fragment, allFragments]);
83
83
 
84
84
  // Merge manual and detected relationships
85
85
  const allRelationships = useMemo(() => {
86
- if (!segment) return [];
87
- return mergeRelationships(segment.relations, showAutoDetected ? detectedRelationships : []);
88
- }, [segment, detectedRelationships, showAutoDetected]);
86
+ if (!fragment) return [];
87
+ return mergeRelationships(fragment.relations, showAutoDetected ? detectedRelationships : []);
88
+ }, [fragment, detectedRelationships, showAutoDetected]);
89
89
 
90
90
  // Group relations by type
91
91
  const groupedRelations = useMemo(() => {
@@ -110,22 +110,22 @@ export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGr
110
110
 
111
111
  // Find reverse relations (components that reference this one)
112
112
  const reverseRelations = useMemo(() => {
113
- if (!segment) return [];
113
+ if (!fragment) return [];
114
114
 
115
- const componentName = segment.meta.name;
116
- const reverse: Array<{ segment: SegmentDefinition; relation: ComponentRelation }> = [];
115
+ const componentName = fragment.meta.name;
116
+ const reverse: Array<{ fragment: FragmentDefinition; relation: ComponentRelation }> = [];
117
117
 
118
- for (const { segment: otherSegment } of allSegments) {
119
- if (otherSegment.meta.name === componentName) continue;
120
- if (!otherSegment.relations) continue;
118
+ for (const { fragment: otherFragment } of allFragments) {
119
+ if (otherFragment.meta.name === componentName) continue;
120
+ if (!otherFragment.relations) continue;
121
121
 
122
- for (const relation of otherSegment.relations) {
122
+ for (const relation of otherFragment.relations) {
123
123
  if (relation.component === componentName) {
124
124
  reverse.push({
125
- segment: otherSegment,
125
+ fragment: otherFragment,
126
126
  relation: {
127
127
  ...relation,
128
- component: otherSegment.meta.name,
128
+ component: otherFragment.meta.name,
129
129
  // Flip the relationship direction for display
130
130
  relationship: flipRelationship(relation.relationship),
131
131
  },
@@ -135,11 +135,11 @@ export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGr
135
135
  }
136
136
 
137
137
  return reverse;
138
- }, [segment, allSegments]);
138
+ }, [fragment, allFragments]);
139
139
 
140
- // Check if a component exists in our segments
140
+ // Check if a component exists in our fragments
141
141
  const componentExists = (name: string) => {
142
- return allSegments.some(s => s.segment.meta.name === name);
142
+ return allFragments.some(s => s.fragment.meta.name === name);
143
143
  };
144
144
 
145
145
  const handleNavigate = (componentName: string) => {
@@ -148,8 +148,8 @@ export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGr
148
148
  }
149
149
  };
150
150
 
151
- // No segment selected
152
- if (!segment) {
151
+ // No fragment selected
152
+ if (!fragment) {
153
153
  return (
154
154
  <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
155
155
  <div style={{ padding: '16px', borderBottom: '1px solid var(--border)' }}>
@@ -184,7 +184,7 @@ export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGr
184
184
  </EmptyState.Icon>
185
185
  <EmptyState.Title>No relationships defined</EmptyState.Title>
186
186
  <EmptyState.Description>
187
- This component doesn't have any defined relationships. Add a <code style={{ padding: '2px 4px', background: 'var(--bg-secondary)', borderRadius: '4px', fontSize: '12px' }}>relations</code> array to your segment definition to visualize component connections.
187
+ This component doesn't have any defined relationships. Add a <code style={{ padding: '2px 4px', background: 'var(--bg-secondary)', borderRadius: '4px', fontSize: '12px' }}>relations</code> array to your fragment definition to visualize component connections.
188
188
  </EmptyState.Description>
189
189
  <div style={{ marginTop: '16px', width: '100%' }}>
190
190
  <CodeBlock language="typescript">{`relations: [
@@ -220,7 +220,7 @@ export function ComponentGraph({ segment, allSegments, onNavigate }: ComponentGr
220
220
  )}
221
221
  </Stack>
222
222
  <Text size="xs" color="secondary" style={{ marginTop: '4px' }}>
223
- Relationships for <Text as="span" weight="medium" size="xs">{segment.meta.name}</Text>
223
+ Relationships for <Text as="span" weight="medium" size="xs">{fragment.meta.name}</Text>
224
224
  {showAutoDetected && detectedCount > 0 && (
225
225
  <span style={{ marginLeft: '4px' }}>
226
226
  ({detectedCount} from variants)
@@ -1,9 +1,9 @@
1
- import type { SegmentMeta } from '../../core/index.js';
1
+ import type { FragmentMeta } from '../../core/index.js';
2
2
  import { Badge, Alert, Text, Stack, Separator } from '@fragments/ui';
3
3
  import { WarningIcon, BeakerIcon } from './Icons.js';
4
4
 
5
5
  interface ComponentHeaderProps {
6
- meta: SegmentMeta;
6
+ meta: FragmentMeta;
7
7
  }
8
8
 
9
9
  // Map status to Badge variant
@@ -1,14 +1,14 @@
1
1
  /**
2
- * ContractPanel component - displays SegmentContract metadata for AI agents.
2
+ * ContractPanel component - displays FragmentContract metadata for AI agents.
3
3
  * Shows propsSummary, scenarioTags, bans, and a11yRules.
4
4
  */
5
5
 
6
6
  import { memo } from 'react';
7
- import type { SegmentContract } from '../../core/index.js';
7
+ import type { FragmentContract } from '../../core/index.js';
8
8
  import { Stack, Text, Card, Chip, Alert, EmptyState, CodeBlock, Badge } from '@fragments/ui';
9
9
 
10
10
  interface ContractPanelProps {
11
- contract?: SegmentContract;
11
+ contract?: FragmentContract;
12
12
  componentName: string;
13
13
  }
14
14
 
@@ -37,7 +37,7 @@ export const ContractPanel = memo(function ContractPanel({
37
37
  </EmptyState.Icon>
38
38
  <EmptyState.Title>No contract metadata</EmptyState.Title>
39
39
  <EmptyState.Description>
40
- Add a <code style={{ background: 'var(--bg-hover)', padding: '2px 4px', borderRadius: '4px' }}>contract</code> field to the segment definition to enable AI agent features.
40
+ Add a <code style={{ background: 'var(--bg-hover)', padding: '2px 4px', borderRadius: '4px' }}>contract</code> field to the fragment definition to enable AI agent features.
41
41
  </EmptyState.Description>
42
42
  <EmptyState.Actions>
43
43
  <CodeBlock
@@ -186,7 +186,7 @@ function Section({ title, subtitle, children }: SectionProps) {
186
186
  }
187
187
 
188
188
  // Check if contract is empty or has no meaningful content
189
- function isContractEmpty(contract: SegmentContract): boolean {
189
+ function isContractEmpty(contract: FragmentContract): boolean {
190
190
  return (
191
191
  (!contract.propsSummary || contract.propsSummary.length === 0) &&
192
192
  (!contract.scenarioTags || contract.scenarioTags.length === 0) &&
@@ -196,7 +196,7 @@ function isContractEmpty(contract: SegmentContract): boolean {
196
196
  }
197
197
 
198
198
  // Check if contract has some but not all fields
199
- function isPartialContract(contract: SegmentContract): boolean {
199
+ function isPartialContract(contract: FragmentContract): boolean {
200
200
  const fieldCount = [
201
201
  contract.propsSummary?.length ?? 0,
202
202
  contract.scenarioTags?.length ?? 0,
@@ -40,7 +40,7 @@ function parseFigmaUrl(figmaUrl: string): ParsedFigmaUrl | null {
40
40
  * Build a Figma embed URL.
41
41
  */
42
42
  function buildEmbedUrl(fileKey: string, nodeId?: string): string {
43
- let embedUrl = `https://embed.figma.com/design/${fileKey}?embed-host=segments`;
43
+ let embedUrl = `https://embed.figma.com/design/${fileKey}?embed-host=fragments`;
44
44
 
45
45
  if (nodeId) {
46
46
  const embedNodeId = nodeId.replace(/:/g, "-");
@@ -205,25 +205,25 @@ export function FigmaEmbed({ figmaUrl, allFigmaUrls, zoom = 100, className, styl
205
205
  }
206
206
 
207
207
  /**
208
- * Hook to collect all Figma URLs from a segment's variants.
208
+ * Hook to collect all Figma URLs from a fragment's variants.
209
209
  * This enables the FigmaEmbed to preload all variant iframes.
210
210
  */
211
211
  export function useAllFigmaUrls(
212
- segment: { meta: { figma?: string }; variants?: Array<{ figma?: string }> } | undefined
212
+ fragment: { meta: { figma?: string }; variants?: Array<{ figma?: string }> } | undefined
213
213
  ): string[] {
214
214
  return useMemo(() => {
215
- if (!segment) return [];
215
+ if (!fragment) return [];
216
216
 
217
217
  const urls: string[] = [];
218
218
 
219
219
  // Add meta-level Figma URL
220
- if (segment.meta.figma) {
221
- urls.push(segment.meta.figma);
220
+ if (fragment.meta.figma) {
221
+ urls.push(fragment.meta.figma);
222
222
  }
223
223
 
224
224
  // Add variant-level Figma URLs
225
- if (segment.variants) {
226
- for (const variant of segment.variants) {
225
+ if (fragment.variants) {
226
+ for (const variant of fragment.variants) {
227
227
  if (variant.figma) {
228
228
  urls.push(variant.figma);
229
229
  }
@@ -232,5 +232,5 @@ export function useAllFigmaUrls(
232
232
 
233
233
  // Deduplicate
234
234
  return [...new Set(urls)];
235
- }, [segment]);
235
+ }, [fragment]);
236
236
  }
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { useMemo, useState, useCallback, useEffect } from 'react';
8
- import type { SegmentDefinition } from '../../core/index.js';
8
+ import type { FragmentDefinition } from '../../core/index.js';
9
9
  import type { ImpactValue } from 'axe-core';
10
10
  import { Badge, Progress, Stack, Text, Card, EmptyState, Table } from '@fragments/ui';
11
11
  import {
@@ -17,7 +17,7 @@ import {
17
17
  import type { A11ySummary, CachedA11yResult } from '../types/a11y.js';
18
18
 
19
19
  interface HealthDashboardProps {
20
- segments: Array<{ path: string; segment: SegmentDefinition }>;
20
+ fragments: Array<{ path: string; fragment: FragmentDefinition }>;
21
21
  onNavigate?: (componentName: string) => void;
22
22
  }
23
23
 
@@ -50,9 +50,9 @@ interface ComponentRow {
50
50
  }
51
51
 
52
52
  function calculateCoverage(
53
- segments: Array<{ path: string; segment: SegmentDefinition }>
53
+ fragments: Array<{ path: string; fragment: FragmentDefinition }>
54
54
  ): { metrics: CoverageMetric[]; components: ComponentRow[]; categoryCount: number } {
55
- const total = segments.length;
55
+ const total = fragments.length;
56
56
 
57
57
  if (total === 0) {
58
58
  return { metrics: [], components: [], categoryCount: 0 };
@@ -66,32 +66,32 @@ function calculateCoverage(
66
66
  let withUsage = 0;
67
67
  let figmaLinked = 0;
68
68
 
69
- for (const { segment } of segments) {
70
- const cat = segment.meta.category || 'uncategorized';
69
+ for (const { fragment } of fragments) {
70
+ const cat = fragment.meta.category || 'uncategorized';
71
71
  categories.add(cat);
72
72
 
73
- if (segment.meta.description && segment.meta.description.trim().length > 10) {
73
+ if (fragment.meta.description && fragment.meta.description.trim().length > 10) {
74
74
  documented++;
75
75
  }
76
76
 
77
- const variantCount = segment.variants?.length || 0;
77
+ const variantCount = fragment.variants?.length || 0;
78
78
  if (variantCount > 0) {
79
79
  withVariants++;
80
80
  }
81
81
 
82
- if (segment.usage && (segment.usage.when.length > 0 || segment.usage.whenNot.length > 0)) {
82
+ if (fragment.usage && (fragment.usage.when.length > 0 || fragment.usage.whenNot.length > 0)) {
83
83
  withUsage++;
84
84
  }
85
85
 
86
- if (segment.meta.figma || segment.variants?.some((v) => v.figma)) {
86
+ if (fragment.meta.figma || fragment.variants?.some((v) => v.figma)) {
87
87
  figmaLinked++;
88
88
  }
89
89
 
90
90
  components.push({
91
- name: segment.meta.name,
91
+ name: fragment.meta.name,
92
92
  category: cat,
93
93
  variantCount,
94
- status: segment.meta.status || 'stable',
94
+ status: fragment.meta.status || 'stable',
95
95
  });
96
96
  }
97
97
 
@@ -120,10 +120,10 @@ function impactToBadgeVariant(impact: ImpactValue | undefined): 'error' | 'warni
120
120
  }
121
121
  }
122
122
 
123
- export function HealthDashboard({ segments, onNavigate }: HealthDashboardProps) {
123
+ export function HealthDashboard({ fragments, onNavigate }: HealthDashboardProps) {
124
124
  const { metrics, components, categoryCount } = useMemo(
125
- () => calculateCoverage(segments),
126
- [segments]
125
+ () => calculateCoverage(fragments),
126
+ [fragments]
127
127
  );
128
128
 
129
129
  const [componentA11y, setComponentA11y] = useState<Record<string, ComponentA11yResult>>({});
@@ -212,7 +212,7 @@ export function HealthDashboard({ segments, onNavigate }: HealthDashboardProps)
212
212
  };
213
213
  }, [componentA11y, a11ySummary]);
214
214
 
215
- if (segments.length === 0) {
215
+ if (fragments.length === 0) {
216
216
  return (
217
217
  <EmptyState>
218
218
  <EmptyState.Description>No components loaded</EmptyState.Description>
@@ -234,7 +234,7 @@ export function HealthDashboard({ segments, onNavigate }: HealthDashboardProps)
234
234
  <div>
235
235
  <Text as="h1" size="lg" weight="semibold">Fragments</Text>
236
236
  <Text size="sm" color="tertiary" style={{ marginTop: '2px' }}>
237
- {segments.length} component{segments.length !== 1 ? 's' : ''} · {categoryCount} categor{categoryCount !== 1 ? 'ies' : 'y'}
237
+ {fragments.length} component{fragments.length !== 1 ? 's' : ''} · {categoryCount} categor{categoryCount !== 1 ? 'ies' : 'y'}
238
238
  </Text>
239
239
  </div>
240
240
 
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { useState, useCallback, useRef, useEffect } from "react";
13
13
  import { Button, Stack, Text, Badge, EmptyState, CodeBlock, Alert } from "@fragments/ui";
14
- import type { PlayFunction, PlayFunctionContext, SegmentVariant } from "../../core/index.js";
14
+ import type { PlayFunction, PlayFunctionContext, FragmentVariant } from "../../core/index.js";
15
15
  import {
16
16
  PlayIcon,
17
17
  CheckIcon,
@@ -54,7 +54,7 @@ interface DebugState {
54
54
 
55
55
  interface InteractionsPanelProps {
56
56
  /** The current variant being displayed */
57
- variant: SegmentVariant | null;
57
+ variant: FragmentVariant | null;
58
58
  /** Selector for the preview container element */
59
59
  previewSelector?: string;
60
60
  /** Key that changes when the preview updates */
@@ -15,8 +15,8 @@ import { usePreviewBridge, type ParentMessage } from '../hooks/usePreviewBridge.
15
15
  const MAX_RETRIES = 3;
16
16
 
17
17
  export interface IsolatedPreviewFrameProps {
18
- /** Segment path (file path) to render */
19
- segmentPath: string;
18
+ /** Fragment path (file path) to render */
19
+ fragmentPath: string;
20
20
  /** Variant name to render */
21
21
  variantName: string;
22
22
  /** Props to pass to the variant render function */
@@ -50,7 +50,7 @@ export interface IsolatedPreviewFrameProps {
50
50
  * for complete CSS isolation from the viewer shell.
51
51
  */
52
52
  export const IsolatedPreviewFrame = memo(function IsolatedPreviewFrame({
53
- segmentPath,
53
+ fragmentPath,
54
54
  variantName,
55
55
  props,
56
56
  theme,
@@ -109,12 +109,12 @@ export const IsolatedPreviewFrame = memo(function IsolatedPreviewFrame({
109
109
  if (!isReady) return;
110
110
 
111
111
  // Create a render key to detect changes
112
- const renderKey = `${segmentPath}:${variantName}:${JSON.stringify(props)}:${previewKey || ''}`;
112
+ const renderKey = `${fragmentPath}:${variantName}:${JSON.stringify(props)}:${previewKey || ''}`;
113
113
  if (renderKey === lastRenderRef.current) return;
114
114
  lastRenderRef.current = renderKey;
115
115
 
116
- render(segmentPath, variantName, props);
117
- }, [isReady, segmentPath, variantName, props, previewKey, render]);
116
+ render(fragmentPath, variantName, props);
117
+ }, [isReady, fragmentPath, variantName, props, previewKey, render]);
118
118
 
119
119
  // Sync theme when it changes
120
120
  useEffect(() => {
@@ -1,10 +1,10 @@
1
1
  import { useMemo, useEffect, useState } from "react";
2
- import type { SegmentDefinition } from "../../core/index.js";
2
+ import type { FragmentDefinition } from "../../core/index.js";
3
3
  import { VariantRenderer } from "./VariantRenderer.js";
4
4
  import { getBackgroundStyle, type BackgroundOption, type ZoomLevel } from "./PreviewToolbar.js";
5
5
 
6
6
  interface IsolatedRenderProps {
7
- segments: Array<{ path: string; segment: SegmentDefinition }>;
7
+ fragments: Array<{ path: string; fragment: FragmentDefinition }>;
8
8
  }
9
9
 
10
10
  /**
@@ -12,7 +12,7 @@ interface IsolatedRenderProps {
12
12
  * Renders a single variant with minimal UI for visual testing.
13
13
  * URL params: ?isolated=true&component=Name&variant=VariantName&zoom=100&bg=white&theme=light
14
14
  */
15
- export function IsolatedRender({ segments }: IsolatedRenderProps) {
15
+ export function IsolatedRender({ fragments }: IsolatedRenderProps) {
16
16
  const [ready, setReady] = useState(false);
17
17
 
18
18
  // Parse query parameters
@@ -31,21 +31,21 @@ export function IsolatedRender({ segments }: IsolatedRenderProps) {
31
31
  };
32
32
  }, []);
33
33
 
34
- // Find the matching segment and variant
34
+ // Find the matching fragment and variant
35
35
  const match = useMemo(() => {
36
36
  if (!params.component || !params.variant) {
37
37
  return null;
38
38
  }
39
39
 
40
- const segment = segments.find(
41
- (s) => s.segment.meta.name === params.component
40
+ const fragment = fragments.find(
41
+ (s) => s.fragment.meta.name === params.component
42
42
  );
43
43
 
44
- if (!segment) {
44
+ if (!fragment) {
45
45
  return null;
46
46
  }
47
47
 
48
- const variant = segment.segment.variants.find(
48
+ const variant = fragment.fragment.variants.find(
49
49
  (v) => v.name === params.variant
50
50
  );
51
51
 
@@ -53,8 +53,8 @@ export function IsolatedRender({ segments }: IsolatedRenderProps) {
53
53
  return null;
54
54
  }
55
55
 
56
- return { segment: segment.segment, variant };
57
- }, [segments, params]);
56
+ return { fragment: fragment.fragment, variant };
57
+ }, [fragments, params]);
58
58
 
59
59
  // Apply theme
60
60
  useEffect(() => {
@@ -1,5 +1,5 @@
1
1
  import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
2
- import type { SegmentDefinition } from '../../core/index.js';
2
+ import type { FragmentDefinition } from '../../core/index.js';
3
3
  import { BRAND } from '../../core/index.js';
4
4
  import { useTheme } from './ThemeProvider.js';
5
5
  import { Sidebar, useSidebar, Badge, Text, ThemeToggle } from '@fragments/ui';
@@ -45,19 +45,19 @@ function fuzzyMatch(text: string, pattern: string): FuzzyMatch | null {
45
45
  }
46
46
 
47
47
  interface SearchResult {
48
- item: { path: string; segment: SegmentDefinition };
48
+ item: { path: string; fragment: FragmentDefinition };
49
49
  score: number;
50
50
  nameIndices: number[];
51
51
  }
52
52
 
53
- function searchSegment(
54
- item: { path: string; segment: SegmentDefinition },
53
+ function searchFragment(
54
+ item: { path: string; fragment: FragmentDefinition },
55
55
  query: string
56
56
  ): SearchResult | null {
57
- const { segment } = item;
58
- // Skip invalid segments
59
- if (!segment?.meta) return null;
60
- const { name, category, tags } = segment.meta;
57
+ const { fragment } = item;
58
+ // Skip invalid fragments
59
+ if (!fragment?.meta) return null;
60
+ const { name, category, tags } = fragment.meta;
61
61
 
62
62
  const nameMatch = fuzzyMatch(name, query);
63
63
  if (nameMatch) {
@@ -119,15 +119,15 @@ function HighlightedText({ text, indices }: { text: string; indices: number[] })
119
119
  }
120
120
 
121
121
  interface LeftSidebarProps {
122
- segments: Array<{ path: string; segment: SegmentDefinition }>;
123
- activeSegment: string | null;
122
+ fragments: Array<{ path: string; fragment: FragmentDefinition }>;
123
+ activeFragment: string | null;
124
124
  searchQuery: string;
125
125
  onSelect: (path: string) => void;
126
126
  showHealth?: boolean;
127
127
  onHealthClick?: () => void;
128
128
  }
129
129
 
130
- export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, showHealth, onHealthClick }: LeftSidebarProps) {
130
+ export function LeftSidebar({ fragments, activeFragment, searchQuery, onSelect, showHealth, onHealthClick }: LeftSidebarProps) {
131
131
  const [focusedIndex, setFocusedIndex] = useState(-1);
132
132
  const { setTheme, resolvedTheme } = useTheme();
133
133
  const { isMobile, setOpen } = useSidebar();
@@ -139,14 +139,14 @@ export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, sh
139
139
  if (!debouncedSearch) return null;
140
140
 
141
141
  const results: SearchResult[] = [];
142
- for (const item of segments) {
143
- const result = searchSegment(item, debouncedSearch);
142
+ for (const item of fragments) {
143
+ const result = searchFragment(item, debouncedSearch);
144
144
  if (result) results.push(result);
145
145
  }
146
146
 
147
147
  results.sort((a, b) => b.score - a.score);
148
148
  return results;
149
- }, [segments, debouncedSearch]);
149
+ }, [fragments, debouncedSearch]);
150
150
 
151
151
  const highlightMap = useMemo(() => {
152
152
  const map = new Map<string, number[]>();
@@ -161,29 +161,29 @@ export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, sh
161
161
  const grouped = useMemo(() => {
162
162
  const source = searchResults
163
163
  ? searchResults.map(r => r.item)
164
- : segments;
164
+ : fragments;
165
165
 
166
- const groups: Record<string, typeof segments> = {};
166
+ const groups: Record<string, typeof fragments> = {};
167
167
  for (const item of source) {
168
- // Skip invalid segments
169
- if (!item.segment?.meta) continue;
170
- const category = item.segment.meta.category || 'uncategorized';
168
+ // Skip invalid fragments
169
+ if (!item.fragment?.meta) continue;
170
+ const category = item.fragment.meta.category || 'uncategorized';
171
171
  if (!groups[category]) groups[category] = [];
172
172
  groups[category].push(item);
173
173
  }
174
174
  return groups;
175
- }, [segments, searchResults]);
175
+ }, [fragments, searchResults]);
176
176
 
177
177
  const flatItems = useMemo(() => {
178
- const items: Array<{ path: string; segment: SegmentDefinition }> = [];
178
+ const items: Array<{ path: string; fragment: FragmentDefinition }> = [];
179
179
  const sortedEntries = Object.entries(grouped).sort(([a], [b]) =>
180
180
  a.toLowerCase().localeCompare(b.toLowerCase())
181
181
  );
182
182
  for (const [, categoryItems] of sortedEntries) {
183
183
  const sorted = [...categoryItems]
184
- .filter(item => item.segment?.meta?.name)
184
+ .filter(item => item.fragment?.meta?.name)
185
185
  .sort((a, b) =>
186
- a.segment.meta.name.toLowerCase().localeCompare(b.segment.meta.name.toLowerCase())
186
+ a.fragment.meta.name.toLowerCase().localeCompare(b.fragment.meta.name.toLowerCase())
187
187
  );
188
188
  items.push(...sorted);
189
189
  }
@@ -295,9 +295,9 @@ export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, sh
295
295
 
296
296
  {sortedEntries.map(([category, items]) => {
297
297
  const sortedItems = [...items]
298
- .filter(item => item.segment?.meta?.name)
298
+ .filter(item => item.fragment?.meta?.name)
299
299
  .sort((a, b) =>
300
- a.segment.meta.name.toLowerCase().localeCompare(b.segment.meta.name.toLowerCase())
300
+ a.fragment.meta.name.toLowerCase().localeCompare(b.fragment.meta.name.toLowerCase())
301
301
  );
302
302
 
303
303
  return (
@@ -308,11 +308,11 @@ export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, sh
308
308
  return (
309
309
  <Sidebar.Item
310
310
  key={item.path}
311
- active={activeSegment === item.path}
311
+ active={activeFragment === item.path}
312
312
  onClick={() => handleSelect(item.path)}
313
313
  >
314
314
  <HighlightedText
315
- text={item.segment.meta.name}
315
+ text={item.fragment.meta.name}
316
316
  indices={nameIndices}
317
317
  />
318
318
  </Sidebar.Item>
@@ -332,7 +332,7 @@ export function LeftSidebar({ segments, activeSegment, searchQuery, onSelect, sh
332
332
 
333
333
  {/* Footer */}
334
334
  <Sidebar.Footer>
335
- <Badge size="sm">{segments.length} components</Badge>
335
+ <Badge size="sm">{fragments.length} components</Badge>
336
336
  </Sidebar.Footer>
337
337
  </>
338
338
  );