@fragments-sdk/cli 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/bin.js +996 -79
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-ICAIQ57V.js → chunk-6JBGU74P.js} +5 -3
  4. package/dist/chunk-6JBGU74P.js.map +1 -0
  5. package/dist/chunk-7OPWMLOE.js +1625 -0
  6. package/dist/chunk-7OPWMLOE.js.map +1 -0
  7. package/dist/{chunk-2H2JAA3U.js → chunk-CVXKXVOY.js} +3 -3
  8. package/dist/{chunk-2H2JAA3U.js.map → chunk-CVXKXVOY.js.map} +1 -1
  9. package/dist/{chunk-IOJE35DZ.js → chunk-NWQ4CJOQ.js} +3 -3
  10. package/dist/{chunk-2DJH4F4P.js → chunk-RVRTRESS.js} +3 -3
  11. package/dist/{chunk-V7YLRR4C.js → chunk-TJ34N7C7.js} +41 -4
  12. package/dist/{chunk-V7YLRR4C.js.map → chunk-TJ34N7C7.js.map} +1 -1
  13. package/dist/{chunk-XNWDI6UT.js → chunk-XHUDJNN3.js} +5 -5
  14. package/dist/{core-DKHB7FYV.js → core-W2HYIQW6.js} +4 -4
  15. package/dist/{generate-KL24VZVD.js → generate-LMTISDIJ.js} +5 -5
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +15 -7
  18. package/dist/index.js.map +1 -1
  19. package/dist/{init-NION5S3M.js → init-7CHRKQ7P.js} +5 -5
  20. package/dist/mcp-bin.js +8 -220
  21. package/dist/mcp-bin.js.map +1 -1
  22. package/dist/scan-WY23TJCP.js +12 -0
  23. package/dist/{service-RWUMZ3EW.js → service-T2L7VLTE.js} +5 -5
  24. package/dist/static-viewer-GBR7YNF3.js +12 -0
  25. package/dist/{test-ECPEXFDN.js → test-OJRXNDO2.js} +4 -4
  26. package/dist/{tokens-ITADYVPF.js → tokens-3BWDESVM.js} +6 -6
  27. package/dist/viewer-SUFOISZM.js +1822 -0
  28. package/dist/viewer-SUFOISZM.js.map +1 -0
  29. package/package.json +6 -5
  30. package/src/bin.ts +31 -0
  31. package/src/build.ts +147 -13
  32. package/src/cli-commands.ts +18 -0
  33. package/src/commands/__tests__/a11y-scoring.test.ts +278 -0
  34. package/src/commands/a11y-report.ts +625 -0
  35. package/src/commands/a11y.ts +168 -14
  36. package/src/commands/build.ts +16 -0
  37. package/src/commands/graph.ts +274 -0
  38. package/src/core/auto-props.ts +464 -0
  39. package/src/core/composition.ts +64 -1
  40. package/src/core/graph-extractor.test.ts +542 -0
  41. package/src/core/graph-extractor.ts +601 -0
  42. package/src/core/importAnalyzer.ts +5 -0
  43. package/src/core/schema.ts +2 -0
  44. package/src/core/types.ts +3 -1
  45. package/src/index.ts +4 -0
  46. package/src/mcp/server.ts +13 -220
  47. package/src/theme/__tests__/component-contrast.test.ts +338 -0
  48. package/src/theme/__tests__/contrast-validation.test.ts +326 -0
  49. package/src/theme/contrast.test.ts +331 -0
  50. package/src/theme/contrast.ts +246 -0
  51. package/src/theme/generator.ts +213 -1
  52. package/src/theme/index.ts +16 -0
  53. package/src/theme/types.ts +51 -0
  54. package/src/viewer/__tests__/a11y-fixes.test.ts +358 -0
  55. package/src/viewer/__tests__/viewer-integration.test.ts +2 -7
  56. package/src/viewer/components/AccessibilityPanel.tsx +493 -433
  57. package/src/viewer/components/ActionCapture.tsx +1 -1
  58. package/src/viewer/components/ActionsPanel.tsx +142 -183
  59. package/src/viewer/components/App.tsx +276 -183
  60. package/src/viewer/components/BottomPanel.tsx +40 -80
  61. package/src/viewer/components/CodePanel.tsx +9 -87
  62. package/src/viewer/components/CommandPalette.tsx +117 -74
  63. package/src/viewer/components/ComponentGraph.tsx +143 -126
  64. package/src/viewer/components/ComponentHeader.tsx +46 -43
  65. package/src/viewer/components/ContractPanel.tsx +124 -117
  66. package/src/viewer/components/ErrorBoundary.tsx +47 -35
  67. package/src/viewer/components/FigmaEmbed.tsx +18 -13
  68. package/src/viewer/components/FragmentEditor.tsx +126 -63
  69. package/src/viewer/components/HealthDashboard.tsx +146 -171
  70. package/src/viewer/components/HmrStatusIndicator.tsx +31 -41
  71. package/src/viewer/components/Icons.tsx +151 -98
  72. package/src/viewer/components/InteractionsPanel.tsx +317 -264
  73. package/src/viewer/components/IsolatedPreviewFrame.tsx +52 -27
  74. package/src/viewer/components/IsolatedRender.tsx +12 -6
  75. package/src/viewer/components/KeyboardShortcutsHelp.tsx +34 -70
  76. package/src/viewer/components/LandingPage.tsx +285 -305
  77. package/src/viewer/components/Layout.tsx +12 -10
  78. package/src/viewer/components/LeftSidebar.tsx +103 -155
  79. package/src/viewer/components/MultiViewportPreview.tsx +254 -63
  80. package/src/viewer/components/PreviewArea.tsx +113 -44
  81. package/src/viewer/components/PreviewFrameHost.tsx +36 -6
  82. package/src/viewer/components/PreviewPane.tsx +2 -3
  83. package/src/viewer/components/PreviewToolbar.tsx +109 -105
  84. package/src/viewer/components/PropsEditor.tsx +154 -74
  85. package/src/viewer/components/PropsTable.tsx +95 -82
  86. package/src/viewer/components/RelationsSection.tsx +71 -40
  87. package/src/viewer/components/ResizablePanel.tsx +158 -55
  88. package/src/viewer/components/RightSidebar.tsx +46 -56
  89. package/src/viewer/components/ScreenshotButton.tsx +12 -12
  90. package/src/viewer/components/SkeletonLoader.tsx +99 -83
  91. package/src/viewer/components/StoryRenderer.tsx +4 -11
  92. package/src/viewer/components/Toast.tsx +3 -67
  93. package/src/viewer/components/TokenStylePanel.tsx +136 -118
  94. package/src/viewer/components/UsageSection.tsx +26 -26
  95. package/src/viewer/components/VariantMatrix.tsx +140 -47
  96. package/src/viewer/components/VariantTabs.tsx +24 -68
  97. package/src/viewer/components/ViewportSelector.tsx +121 -114
  98. package/src/viewer/constants/ui.ts +23 -22
  99. package/src/viewer/entry.tsx +8 -3
  100. package/src/viewer/index.ts +3 -6
  101. package/src/viewer/preview-frame.html +43 -18
  102. package/src/viewer/server.ts +7 -16
  103. package/src/viewer/styles/globals.css +46 -85
  104. package/src/viewer/utils/a11y-fixes.ts +53 -30
  105. package/dist/chunk-ICAIQ57V.js.map +0 -1
  106. package/dist/chunk-U4GQ2JTD.js +0 -832
  107. package/dist/chunk-U4GQ2JTD.js.map +0 -1
  108. package/dist/scan-ESEXV7LF.js +0 -12
  109. package/dist/static-viewer-O37MJ5B6.js +0 -12
  110. package/dist/viewer-YDGFDTK5.js +0 -11104
  111. package/dist/viewer-YDGFDTK5.js.map +0 -1
  112. package/src/viewer/postcss.config.js +0 -6
  113. package/src/viewer/tailwind.config.js +0 -37
  114. /package/dist/{chunk-IOJE35DZ.js.map → chunk-NWQ4CJOQ.js.map} +0 -0
  115. /package/dist/{chunk-2DJH4F4P.js.map → chunk-RVRTRESS.js.map} +0 -0
  116. /package/dist/{chunk-XNWDI6UT.js.map → chunk-XHUDJNN3.js.map} +0 -0
  117. /package/dist/{core-DKHB7FYV.js.map → core-W2HYIQW6.js.map} +0 -0
  118. /package/dist/{generate-KL24VZVD.js.map → generate-LMTISDIJ.js.map} +0 -0
  119. /package/dist/{init-NION5S3M.js.map → init-7CHRKQ7P.js.map} +0 -0
  120. /package/dist/{scan-ESEXV7LF.js.map → scan-WY23TJCP.js.map} +0 -0
  121. /package/dist/{service-RWUMZ3EW.js.map → service-T2L7VLTE.js.map} +0 -0
  122. /package/dist/{static-viewer-O37MJ5B6.js.map → static-viewer-GBR7YNF3.js.map} +0 -0
  123. /package/dist/{test-ECPEXFDN.js.map → test-OJRXNDO2.js.map} +0 -0
  124. /package/dist/{tokens-ITADYVPF.js.map → tokens-3BWDESVM.js.map} +0 -0
@@ -1,94 +1,50 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
1
  /* ============================================
6
2
  * Fragments Viewer Theme System
7
3
  * ============================================
8
- * The viewer shell (sidebar, toolbar, panels) uses these variables.
9
- * These are INDEPENDENT from the UI library's --fui-* variables.
10
- *
11
- * The UI library components are rendered in the preview area which
12
- * has its own scoped --fui-* variables (see below).
4
+ * The viewer shell (sidebar, toolbar, panels) mirrors @fragments/ui
5
+ * tokens so previews and shell feel like the live docs experience.
13
6
  * ============================================ */
14
7
 
15
- /* Light mode (default) */
16
8
  :root {
17
- --bg-primary: #ffffff;
18
- --bg-secondary: #f2f2f2;
19
- --bg-tertiary: #f5f5f5;
20
- --bg-elevated: #ffffff;
21
- --bg-hover: rgba(0, 0, 0, 0.04);
22
- --bg-active: rgba(0, 0, 0, 0.08);
23
-
24
- --text-primary: #171717;
25
- --text-secondary: #525252;
26
- --text-tertiary: #a3a3a3;
27
- --text-muted: #d4d4d4;
28
-
29
- --border: rgba(0, 0, 0, 0.08);
30
- --border-subtle: rgba(0, 0, 0, 0.04);
31
- --border-strong: rgba(0, 0, 0, 0.12);
32
-
33
- --color-accent: #10a37f;
34
- --color-accent-hover: #0d8a6a;
35
- --color-accent-subtle: rgba(16, 163, 127, 0.1);
36
-
37
- --color-success: #10a37f;
38
- --color-success-bg: rgba(16, 163, 127, 0.1);
39
- --color-warning: #f59e0b;
40
- --color-warning-bg: rgba(245, 158, 11, 0.1);
41
- --color-danger: #ef4444;
42
- --color-danger-bg: rgba(239, 68, 68, 0.1);
43
- --color-info: #3b82f6;
44
- --color-info-bg: rgba(59, 130, 246, 0.1);
45
-
46
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
47
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
48
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
49
-
50
- --radius-sm: 6px;
51
- --radius-md: 8px;
52
- --radius-lg: 12px;
53
-
54
- --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
55
- --transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1);
56
- }
57
-
58
- /* Dark mode - applied when .dark class is on html */
59
- .dark {
60
- --bg-primary: #0d0d0d;
61
- --bg-secondary: #171717;
62
- --bg-tertiary: #1f1f1f;
63
- --bg-elevated: #1a1a1a;
64
- --bg-hover: rgba(255, 255, 255, 0.04);
65
- --bg-active: rgba(255, 255, 255, 0.08);
66
-
67
- --text-primary: #ececec;
68
- --text-secondary: #9a9a9a;
69
- --text-tertiary: #666666;
70
- --text-muted: #404040;
71
-
72
- --border: rgba(255, 255, 255, 0.08);
73
- --border-subtle: rgba(255, 255, 255, 0.04);
74
- --border-strong: rgba(255, 255, 255, 0.12);
75
-
76
- --color-accent: #10a37f;
77
- --color-accent-hover: #1eb894;
78
- --color-accent-subtle: rgba(16, 163, 127, 0.15);
79
-
80
- --color-success: #10a37f;
81
- --color-success-bg: rgba(16, 163, 127, 0.15);
82
- --color-warning: #f59e0b;
83
- --color-warning-bg: rgba(245, 158, 11, 0.15);
84
- --color-danger: #ef4444;
85
- --color-danger-bg: rgba(239, 68, 68, 0.15);
86
- --color-info: #60a5fa;
87
- --color-info-bg: rgba(96, 165, 250, 0.15);
88
-
89
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
90
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.2);
91
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.3);
9
+ --bg-primary: var(--fui-bg-primary, #ffffff);
10
+ --bg-secondary: var(--fui-bg-secondary, #f7f7f8);
11
+ --bg-tertiary: var(--fui-bg-tertiary, #f2f2f2);
12
+ --bg-elevated: var(--fui-bg-elevated, #ffffff);
13
+ --bg-hover: var(--fui-bg-hover, rgba(0, 0, 0, 0.06));
14
+ --bg-active: var(--fui-bg-active, rgba(0, 0, 0, 0.1));
15
+
16
+ --text-primary: var(--fui-text-primary, #171717);
17
+ --text-secondary: var(--fui-text-secondary, #525252);
18
+ --text-tertiary: var(--fui-text-tertiary, #8a8a8a);
19
+ --text-muted: var(--fui-text-tertiary, #8a8a8a);
20
+
21
+ --border: var(--fui-border, rgba(0, 0, 0, 0.1));
22
+ --border-subtle: var(--fui-border, rgba(0, 0, 0, 0.1));
23
+ --border-strong: var(--fui-border-strong, rgba(0, 0, 0, 0.16));
24
+
25
+ --color-accent: var(--fui-color-accent, #10a37f);
26
+ --color-accent-hover: var(--fui-color-accent-hover, #0d8a6a);
27
+ --color-accent-subtle: var(--fui-color-success-bg, rgba(16, 163, 127, 0.1));
28
+
29
+ --color-success: var(--fui-color-success, #10a37f);
30
+ --color-success-bg: var(--fui-color-success-bg, rgba(16, 163, 127, 0.1));
31
+ --color-warning: var(--fui-color-warning, #f59e0b);
32
+ --color-warning-bg: var(--fui-color-warning-bg, rgba(245, 158, 11, 0.1));
33
+ --color-danger: var(--fui-color-danger, #ef4444);
34
+ --color-danger-bg: var(--fui-color-danger-bg, rgba(239, 68, 68, 0.1));
35
+ --color-info: var(--fui-color-info, #3b82f6);
36
+ --color-info-bg: var(--fui-color-info-bg, rgba(59, 130, 246, 0.1));
37
+
38
+ --shadow-sm: var(--fui-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.05));
39
+ --shadow-md: var(--fui-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.08));
40
+ --shadow-lg: var(--fui-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.12));
41
+
42
+ --radius-sm: var(--fui-radius-sm, 6px);
43
+ --radius-md: var(--fui-radius-md, 8px);
44
+ --radius-lg: var(--fui-radius-lg, 12px);
45
+
46
+ --transition-fast: var(--fui-transition-fast, 150ms ease);
47
+ --transition-normal: var(--fui-transition-normal, 200ms ease);
92
48
  }
93
49
 
94
50
  /* ============================================
@@ -109,6 +65,7 @@ html {
109
65
  }
110
66
 
111
67
  body {
68
+ font-family: var(--fui-font-sans, 'Geist Sans', Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
112
69
  background-color: var(--bg-primary);
113
70
  color: var(--text-primary);
114
71
  -webkit-font-smoothing: antialiased;
@@ -330,6 +287,10 @@ td {
330
287
  * Animations
331
288
  * ============================================ */
332
289
 
290
+ @keyframes spin {
291
+ to { transform: rotate(360deg); }
292
+ }
293
+
333
294
  @keyframes fadeIn {
334
295
  from { opacity: 0; }
335
296
  to { opacity: 1; }
@@ -10,6 +10,7 @@
10
10
 
11
11
  import type { ImpactValue } from 'axe-core';
12
12
  import type { StaticFixSuggestion, ElementFix, SerializedNode } from '../types/a11y.js';
13
+ import { parseColor, suggestFix, rgbToHex } from '../../theme/contrast.js';
13
14
 
14
15
  /**
15
16
  * WCAG criteria references
@@ -217,24 +218,36 @@ function generateContrastFix(node: SerializedNode): ElementFix | null {
217
218
  const data = parseContrastData(node);
218
219
  if (!data?.fgColor || !data?.bgColor) return null;
219
220
 
220
- const { fgColor, bgColor, contrastRatio, requiredRatio } = data;
221
+ const { fgColor, bgColor, contrastRatio: ratio, requiredRatio } = data;
221
222
 
222
223
  // Safely convert to number and format
223
- const currentRatioNum = typeof contrastRatio === 'number' ? contrastRatio : parseFloat(String(contrastRatio || ''));
224
+ const currentRatioNum = typeof ratio === 'number' ? ratio : parseFloat(String(ratio || ''));
224
225
  const requiredRatioNum = typeof requiredRatio === 'number' ? requiredRatio : parseFloat(String(requiredRatio || ''));
225
226
 
226
227
  const currentRatio = !isNaN(currentRatioNum) ? currentRatioNum.toFixed(2) : 'unknown';
227
- const required = !isNaN(requiredRatioNum) ? requiredRatioNum.toFixed(1) : '4.5';
228
-
229
- // Suggest darkening text if it's light, or lightening if it's dark
230
- const suggestion = `Adjust colors to meet ${required}:1 contrast ratio (currently ${currentRatio}:1)`;
231
-
232
- return {
233
- originalHtml: node.html,
234
- fixedHtml: node.html, // Can't auto-generate fixed HTML without color calculation
235
- explanation: `Text color ${fgColor} on background ${bgColor} has insufficient contrast. ${suggestion}`,
236
- autoFixable: false,
237
- };
228
+ const required = !isNaN(requiredRatioNum) ? requiredRatioNum : 4.5;
229
+
230
+ // Use real color math to suggest a corrected foreground color
231
+ try {
232
+ const fgRgb = parseColor(fgColor);
233
+ const bgRgb = parseColor(bgColor);
234
+ const correctedHex = suggestFix(fgRgb, bgRgb, required);
235
+
236
+ return {
237
+ originalHtml: node.html,
238
+ fixedHtml: node.html,
239
+ explanation: `Text color ${fgColor} on background ${bgColor} has insufficient contrast (${currentRatio}:1, need ${required}:1). Suggested foreground: ${correctedHex}`,
240
+ autoFixable: true,
241
+ };
242
+ } catch {
243
+ // Fall back to non-auto-fixable if color parsing fails
244
+ return {
245
+ originalHtml: node.html,
246
+ fixedHtml: node.html,
247
+ explanation: `Text color ${fgColor} on background ${bgColor} has insufficient contrast (${currentRatio}:1, need ${required}:1). Adjust the foreground color to meet the required ratio.`,
248
+ autoFixable: false,
249
+ };
250
+ }
238
251
  }
239
252
 
240
253
  /**
@@ -413,9 +426,11 @@ export function getImpactDescription(impact: ImpactValue | null): string {
413
426
  }
414
427
 
415
428
  /**
416
- * Get impact color class for styling
429
+ * Get impact styling for inline styles and Badge variant mapping
417
430
  */
418
431
  export function getImpactColorClass(impact: ImpactValue | null): {
432
+ variant: 'error' | 'warning' | 'info' | 'default';
433
+ color: string;
419
434
  bg: string;
420
435
  text: string;
421
436
  border: string;
@@ -424,32 +439,40 @@ export function getImpactColorClass(impact: ImpactValue | null): {
424
439
  switch (impact) {
425
440
  case 'critical':
426
441
  return {
427
- bg: 'bg-red-100 dark:bg-red-950/50',
428
- text: 'text-red-700 dark:text-red-300',
429
- border: 'border-red-300 dark:border-red-700',
430
- borderLeft: 'border-l-red-500',
442
+ variant: 'error',
443
+ color: 'var(--color-danger)',
444
+ bg: 'var(--color-danger-bg)',
445
+ text: 'var(--color-danger)',
446
+ border: 'var(--color-danger)',
447
+ borderLeft: 'var(--color-danger)',
431
448
  };
432
449
  case 'serious':
433
450
  return {
434
- bg: 'bg-orange-100 dark:bg-orange-950/50',
435
- text: 'text-orange-700 dark:text-orange-300',
436
- border: 'border-orange-300 dark:border-orange-700',
437
- borderLeft: 'border-l-orange-500',
451
+ variant: 'error',
452
+ color: 'var(--color-danger)',
453
+ bg: 'var(--color-danger-bg)',
454
+ text: 'var(--color-danger)',
455
+ border: 'var(--color-danger)',
456
+ borderLeft: 'var(--color-danger)',
438
457
  };
439
458
  case 'moderate':
440
459
  return {
441
- bg: 'bg-amber-100 dark:bg-amber-950/50',
442
- text: 'text-amber-700 dark:text-amber-300',
443
- border: 'border-amber-300 dark:border-amber-700',
444
- borderLeft: 'border-l-amber-500',
460
+ variant: 'warning',
461
+ color: 'var(--color-warning)',
462
+ bg: 'var(--color-warning-bg)',
463
+ text: 'var(--color-warning)',
464
+ border: 'var(--color-warning)',
465
+ borderLeft: 'var(--color-warning)',
445
466
  };
446
467
  case 'minor':
447
468
  default:
448
469
  return {
449
- bg: 'bg-yellow-100 dark:bg-yellow-950/50',
450
- text: 'text-yellow-700 dark:text-yellow-300',
451
- border: 'border-yellow-300 dark:border-yellow-700',
452
- borderLeft: 'border-l-yellow-500',
470
+ variant: 'info',
471
+ color: 'var(--color-info)',
472
+ bg: 'var(--color-info-bg)',
473
+ text: 'var(--color-info)',
474
+ border: 'var(--color-info)',
475
+ borderLeft: 'var(--color-info)',
453
476
  };
454
477
  }
455
478
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/constants.ts","../src/core/schema.ts"],"sourcesContent":["/**\n * Brand constants for easy rebranding if domain availability requires it.\n * All naming throughout the codebase should reference these constants.\n */\nexport const BRAND = {\n /** Display name (e.g., \"Fragments\") */\n name: \"Fragments\",\n\n /** Lowercase name for file paths and CLI (e.g., \"fragments\") */\n nameLower: \"fragments\",\n\n /** File extension for fragment definition files (e.g., \".fragment.tsx\") */\n fileExtension: \".fragment.tsx\",\n\n /** Legacy file extension for segments (still supported for migration) */\n legacyFileExtension: \".segment.tsx\",\n\n /** JSON file extension for compiled output */\n jsonExtension: \".fragment.json\",\n\n /** Default output file name (e.g., \"fragments.json\") */\n outFile: \"fragments.json\",\n\n /** Config file name (e.g., \"fragments.config.ts\") */\n configFile: \"fragments.config.ts\",\n\n /** Legacy config file name (still supported for migration) */\n legacyConfigFile: \"segments.config.ts\",\n\n /** CLI command name (e.g., \"fragments\") */\n cliCommand: \"fragments\",\n\n /** Package scope (e.g., \"@fragments\") */\n packageScope: \"@fragments\",\n\n /** Directory for storing fragments, registry, and cache */\n dataDir: \".fragments\",\n\n /** Components subdirectory within .fragments/ */\n componentsDir: \"components\",\n\n /** Registry file name */\n registryFile: \"registry.json\",\n\n /** Context file name (AI-ready markdown) */\n contextFile: \"context.md\",\n\n /** Screenshots subdirectory */\n screenshotsDir: \"screenshots\",\n\n /** Cache subdirectory (gitignored) */\n cacheDir: \"cache\",\n\n /** Diff output subdirectory (gitignored) */\n diffDir: \"diff\",\n\n /** Manifest filename */\n manifestFile: \"manifest.json\",\n\n /** Prefix for localStorage keys (e.g., \"fragments-\") */\n storagePrefix: \"fragments-\",\n\n /** Static viewer HTML file name */\n viewerHtmlFile: \"fragments-viewer.html\",\n\n /** MCP tool name prefix (e.g., \"fragments_\") */\n mcpToolPrefix: \"fragments_\",\n\n /** File extension for block definition files */\n blockFileExtension: \".block.ts\",\n\n /** @deprecated Use blockFileExtension instead */\n recipeFileExtension: \".recipe.ts\",\n\n /** Vite plugin namespace */\n vitePluginNamespace: \"fragments-core-shim\",\n} as const;\n\nexport type Brand = typeof BRAND;\n\n/**\n * Default configuration values for the service.\n * These can be overridden in fragments.config.ts\n */\nexport const DEFAULTS = {\n /** Default viewport dimensions */\n viewport: {\n width: 1280,\n height: 800,\n },\n\n /** Default diff threshold (percentage) */\n diffThreshold: 5,\n\n /** Browser pool size */\n poolSize: 3,\n\n /** Idle timeout before browser shutdown (ms) - 5 minutes */\n idleTimeoutMs: 5 * 60 * 1000,\n\n /** Delay after render before capture (ms) */\n captureDelayMs: 100,\n\n /** Font loading timeout (ms) */\n fontTimeoutMs: 3000,\n\n /** Default theme */\n theme: \"light\" as const,\n\n /** Dev server port */\n port: 6006,\n} as const;\n\nexport type Defaults = typeof DEFAULTS;\n","import { z } from 'zod';\n\n/**\n * Zod schemas for runtime validation of segment definitions\n */\n\n// Figma property mapping schemas\nconst figmaStringMappingSchema = z.object({\n __type: z.literal('figma-string'),\n figmaProperty: z.string().min(1),\n});\n\nconst figmaBooleanMappingSchema = z.object({\n __type: z.literal('figma-boolean'),\n figmaProperty: z.string().min(1),\n valueMapping: z.object({ true: z.unknown(), false: z.unknown() }).optional(),\n});\n\nconst figmaEnumMappingSchema = z.object({\n __type: z.literal('figma-enum'),\n figmaProperty: z.string().min(1),\n valueMapping: z.record(z.unknown()),\n});\n\nconst figmaInstanceMappingSchema = z.object({\n __type: z.literal('figma-instance'),\n figmaProperty: z.string().min(1),\n});\n\nconst figmaChildrenMappingSchema = z.object({\n __type: z.literal('figma-children'),\n layers: z.array(z.string().min(1)),\n});\n\nconst figmaTextContentMappingSchema = z.object({\n __type: z.literal('figma-text-content'),\n layer: z.string().min(1),\n});\n\nexport const figmaPropMappingSchema = z.discriminatedUnion('__type', [\n figmaStringMappingSchema,\n figmaBooleanMappingSchema,\n figmaEnumMappingSchema,\n figmaInstanceMappingSchema,\n figmaChildrenMappingSchema,\n figmaTextContentMappingSchema,\n]);\n\nexport const segmentMetaSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n category: z.string().min(1),\n tags: z.array(z.string()).optional(),\n status: z.enum(['stable', 'beta', 'deprecated', 'experimental']).optional(),\n since: z.string().optional(),\n figma: z.string().url().optional(),\n figmaProps: z.record(figmaPropMappingSchema).optional(),\n});\n\nexport const segmentUsageSchema = z.object({\n when: z.array(z.string()).min(1),\n whenNot: z.array(z.string()).min(1),\n guidelines: z.array(z.string()).optional(),\n accessibility: z.array(z.string()).optional(),\n});\n\nexport const propTypeSchema: z.ZodType<string> = z.enum([\n 'string',\n 'number',\n 'boolean',\n 'enum',\n 'function',\n 'node',\n 'element',\n 'object',\n 'array',\n 'union',\n 'custom',\n]);\n\nexport const propDefinitionSchema = z.object({\n type: propTypeSchema,\n values: z.array(z.string()).readonly().optional(),\n default: z.unknown().optional(),\n description: z.string().optional(),\n required: z.boolean().optional(),\n constraints: z.array(z.string()).optional(),\n typeDetails: z.record(z.unknown()).optional(),\n});\n\nexport const relationshipTypeSchema = z.enum([\n 'alternative',\n 'sibling',\n 'parent',\n 'child',\n 'composition',\n]);\n\nexport const componentRelationSchema = z.object({\n component: z.string().min(1),\n relationship: relationshipTypeSchema,\n note: z.string().min(1),\n});\n\nexport const segmentVariantSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n render: z.function().returns(z.unknown()),\n code: z.string().optional(),\n figma: z.string().url().optional(),\n});\n\n/**\n * Schema for banned patterns in codebase\n */\nexport const segmentBanSchema = z.object({\n pattern: z.string().min(1),\n message: z.string().min(1),\n});\n\n/**\n * Schema for agent-optimized contract metadata\n */\nexport const segmentContractSchema = z.object({\n propsSummary: z.array(z.string()).optional(),\n a11yRules: z.array(z.string()).optional(),\n bans: z.array(segmentBanSchema).optional(),\n scenarioTags: z.array(z.string()).optional(),\n});\n\n/**\n * Schema for provenance tracking of generated segments\n */\nexport const segmentGeneratedSchema = z.object({\n source: z.enum(['storybook', 'manual', 'ai']),\n sourceFile: z.string().optional(),\n confidence: z.number().min(0).max(1).optional(),\n timestamp: z.string().datetime().optional(),\n});\n\n/**\n * Schema for AI-specific metadata for playground context generation\n */\nexport const aiMetadataSchema = z.object({\n compositionPattern: z.enum(['compound', 'simple', 'controlled']).optional(),\n subComponents: z.array(z.string()).optional(),\n requiredChildren: z.array(z.string()).optional(),\n commonPatterns: z.array(z.string()).optional(),\n});\n\n/**\n * Schema for block definitions\n */\nexport const blockDefinitionSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n category: z.string().min(1),\n components: z.array(z.string().min(1)).min(1),\n code: z.string().min(1),\n tags: z.array(z.string()).optional(),\n});\n\nexport const segmentDefinitionSchema = z.object({\n component: z.any(), // Allow any component type (function, class, forwardRef, etc.)\n meta: segmentMetaSchema,\n usage: segmentUsageSchema,\n props: z.record(propDefinitionSchema),\n relations: z.array(componentRelationSchema).optional(),\n variants: z.array(segmentVariantSchema), // Allow empty variants array\n contract: segmentContractSchema.optional(),\n ai: aiMetadataSchema.optional(),\n _generated: segmentGeneratedSchema.optional(),\n});\n\n/**\n * Config schema - validates required fields, passes through optional config objects.\n * Type definitions are in types.ts - schema just ensures basic structure.\n */\nexport const segmentsConfigSchema = z.object({\n include: z.array(z.string()).min(1),\n exclude: z.array(z.string()).optional(),\n components: z.array(z.string()).optional(),\n outFile: z.string().optional(),\n framework: z.enum(['react', 'vue', 'svelte']).optional(),\n figmaFile: z.string().url().optional(),\n figmaToken: z.string().optional(),\n screenshots: z.object({}).passthrough().optional(),\n service: z.object({}).passthrough().optional(),\n registry: z.object({}).passthrough().optional(),\n tokens: z.object({\n include: z.array(z.string()).min(1),\n }).passthrough().optional(),\n});\n\n/**\n * @deprecated Use blockDefinitionSchema instead\n */\nexport const recipeDefinitionSchema = blockDefinitionSchema;\n"],"mappings":"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","names":[]}