@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/static-viewer.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { CompiledSegmentsFile } from \"./core/index.js\";\nimport { BRAND } from \"./core/index.js\";\n\n/**\n * Generate a static HTML viewer for the segments.json file.\n * This viewer shows component documentation without needing to render actual components.\n */\nexport function generateStaticViewer(data: CompiledSegmentsFile): string {\n const segments = Object.values(data.segments);\n\n // Group by category\n const categories = new Map<string, typeof segments>();\n for (const segment of segments) {\n const category = segment.meta.category ?? \"Uncategorized\";\n if (!categories.has(category)) {\n categories.set(category, []);\n }\n categories.get(category)!.push(segment);\n }\n\n // Sort categories and components\n const sortedCategories = Array.from(categories.entries()).sort((a, b) =>\n a[0].localeCompare(b[0])\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${BRAND.name} - Design System Viewer</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\" rel=\"stylesheet\">\n <style>\n :root {\n --bg-primary: #0a0a0f;\n --bg-secondary: #12121a;\n --bg-tertiary: #1a1a24;\n --bg-hover: #22222e;\n --border-color: #2a2a3a;\n --text-primary: #f5f5f7;\n --text-secondary: #a0a0b0;\n --text-muted: #606070;\n --accent: #6366f1;\n --accent-hover: #818cf8;\n --success: #22c55e;\n --warning: #f59e0b;\n --error: #ef4444;\n --code-bg: #1e1e2e;\n }\n \n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n \n body {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n background: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n }\n \n .layout {\n display: grid;\n grid-template-columns: 280px 1fr;\n min-height: 100vh;\n }\n \n /* Sidebar */\n .sidebar {\n background: var(--bg-secondary);\n border-right: 1px solid var(--border-color);\n padding: 24px 0;\n position: sticky;\n top: 0;\n height: 100vh;\n overflow-y: auto;\n }\n \n .sidebar-header {\n padding: 0 20px 20px;\n border-bottom: 1px solid var(--border-color);\n margin-bottom: 16px;\n }\n \n .sidebar-header h1 {\n font-size: 20px;\n font-weight: 700;\n background: linear-gradient(135deg, var(--accent), #a855f7);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n }\n \n .sidebar-header .subtitle {\n font-size: 12px;\n color: var(--text-muted);\n margin-top: 4px;\n }\n \n .sidebar-stats {\n display: flex;\n gap: 16px;\n padding: 12px 20px;\n background: var(--bg-tertiary);\n margin: 0 12px 16px;\n border-radius: 8px;\n }\n \n .stat {\n text-align: center;\n }\n \n .stat-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--accent);\n }\n \n .stat-label {\n font-size: 11px;\n color: var(--text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .category {\n margin-bottom: 8px;\n }\n \n .category-header {\n padding: 8px 20px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--text-muted);\n }\n \n .nav-item {\n display: block;\n padding: 8px 20px 8px 32px;\n color: var(--text-secondary);\n text-decoration: none;\n font-size: 14px;\n transition: all 0.15s;\n }\n \n .nav-item:hover {\n background: var(--bg-hover);\n color: var(--text-primary);\n }\n \n .nav-item.active {\n background: var(--accent);\n color: white;\n }\n \n /* Main Content */\n .main {\n padding: 40px 60px;\n max-width: 1000px;\n }\n \n .component-section {\n margin-bottom: 60px;\n scroll-margin-top: 40px;\n }\n \n .component-header {\n margin-bottom: 24px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border-color);\n }\n \n .component-name {\n font-size: 32px;\n font-weight: 700;\n margin-bottom: 8px;\n }\n \n .component-description {\n font-size: 16px;\n color: var(--text-secondary);\n line-height: 1.7;\n }\n \n .component-meta {\n display: flex;\n gap: 16px;\n margin-top: 16px;\n }\n \n .meta-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--bg-tertiary);\n border-radius: 20px;\n font-size: 12px;\n color: var(--text-secondary);\n }\n \n .meta-badge.status-stable { color: var(--success); }\n .meta-badge.status-beta { color: var(--warning); }\n .meta-badge.status-deprecated { color: var(--error); }\n \n /* Sections */\n .section {\n margin-bottom: 32px;\n }\n \n .section-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 16px;\n color: var(--text-primary);\n }\n \n /* Usage Guidelines */\n .usage-list {\n list-style: none;\n }\n \n .usage-item {\n display: flex;\n gap: 12px;\n padding: 12px 16px;\n background: var(--bg-secondary);\n border-radius: 8px;\n margin-bottom: 8px;\n font-size: 14px;\n }\n \n .usage-item.when::before {\n content: '✓';\n color: var(--success);\n font-weight: bold;\n }\n \n .usage-item.when-not::before {\n content: '✗';\n color: var(--error);\n font-weight: bold;\n }\n \n /* Props Table */\n .props-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n }\n \n .props-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--bg-tertiary);\n font-weight: 600;\n color: var(--text-secondary);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .props-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--border-color);\n vertical-align: top;\n }\n \n .props-table tr:hover td {\n background: var(--bg-secondary);\n }\n \n .prop-name {\n font-family: 'JetBrains Mono', monospace;\n color: var(--accent);\n }\n \n .prop-type {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n color: var(--text-muted);\n }\n \n .prop-required {\n color: var(--error);\n font-size: 11px;\n font-weight: 600;\n }\n \n .prop-default {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n color: var(--text-muted);\n background: var(--code-bg);\n padding: 2px 6px;\n border-radius: 4px;\n }\n \n /* Variants */\n .variants-grid {\n display: grid;\n gap: 16px;\n }\n \n .variant-card {\n background: var(--bg-secondary);\n border: 1px solid var(--border-color);\n border-radius: 12px;\n padding: 20px;\n }\n \n .variant-name {\n font-weight: 600;\n margin-bottom: 8px;\n }\n \n .variant-description {\n font-size: 14px;\n color: var(--text-secondary);\n margin-bottom: 12px;\n }\n \n .variant-code {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n background: var(--code-bg);\n padding: 12px 16px;\n border-radius: 8px;\n overflow-x: auto;\n color: var(--text-secondary);\n }\n \n /* Relations */\n .relations-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n }\n \n .relation-tag {\n padding: 6px 14px;\n background: var(--bg-tertiary);\n border: 1px solid var(--border-color);\n border-radius: 20px;\n font-size: 13px;\n color: var(--text-secondary);\n text-decoration: none;\n transition: all 0.15s;\n }\n \n .relation-tag:hover {\n border-color: var(--accent);\n color: var(--accent);\n }\n \n /* Search */\n .search-container {\n padding: 0 12px 16px;\n }\n \n .search-input {\n width: 100%;\n padding: 10px 14px;\n background: var(--bg-tertiary);\n border: 1px solid var(--border-color);\n border-radius: 8px;\n color: var(--text-primary);\n font-size: 14px;\n outline: none;\n transition: border-color 0.15s;\n }\n \n .search-input:focus {\n border-color: var(--accent);\n }\n \n .search-input::placeholder {\n color: var(--text-muted);\n }\n \n /* Empty State */\n .empty-state {\n text-align: center;\n padding: 80px 40px;\n color: var(--text-muted);\n }\n \n .empty-state h2 {\n font-size: 24px;\n margin-bottom: 12px;\n color: var(--text-secondary);\n }\n \n @media (max-width: 900px) {\n .layout {\n grid-template-columns: 1fr;\n }\n \n .sidebar {\n position: relative;\n height: auto;\n border-right: none;\n border-bottom: 1px solid var(--border-color);\n }\n \n .main {\n padding: 24px;\n }\n }\n </style>\n</head>\n<body>\n <div class=\"layout\">\n <aside class=\"sidebar\">\n <div class=\"sidebar-header\">\n <h1>${BRAND.name}</h1>\n <div class=\"subtitle\">Design System Documentation</div>\n </div>\n \n <div class=\"sidebar-stats\">\n <div class=\"stat\">\n <div class=\"stat-value\">${segments.length}</div>\n <div class=\"stat-label\">Components</div>\n </div>\n <div class=\"stat\">\n <div class=\"stat-value\">${segments.reduce(\n (sum, s) => sum + s.variants.length,\n 0\n )}</div>\n <div class=\"stat-label\">Variants</div>\n </div>\n </div>\n \n <div class=\"search-container\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search components...\" id=\"search\">\n </div>\n \n <nav id=\"nav\">\n ${sortedCategories\n .map(\n ([category, items]) => `\n <div class=\"category\">\n <div class=\"category-header\">${category}</div>\n ${items\n .sort((a, b) => a.meta.name.localeCompare(b.meta.name))\n .map(\n (item) => `\n <a href=\"#${item.meta.name}\" class=\"nav-item\">${item.meta.name}</a>\n `\n )\n .join(\"\")}\n </div>\n `\n )\n .join(\"\")}\n </nav>\n </aside>\n \n <main class=\"main\" id=\"main\">\n ${\n segments.length === 0\n ? `\n <div class=\"empty-state\">\n <h2>No Components Found</h2>\n <p>Run <code>segments build</code> to compile your segment files.</p>\n </div>\n `\n : segments\n .sort((a, b) => a.meta.name.localeCompare(b.meta.name))\n .map(\n (segment) => `\n <section class=\"component-section\" id=\"${segment.meta.name}\">\n <div class=\"component-header\">\n <h2 class=\"component-name\">${segment.meta.name}</h2>\n <p class=\"component-description\">${segment.meta.description}</p>\n <div class=\"component-meta\">\n ${\n segment.meta.status\n ? `<span class=\"meta-badge status-${segment.meta.status}\">${segment.meta.status}</span>`\n : \"\"\n }\n ${\n segment.meta.category\n ? `<span class=\"meta-badge\">${segment.meta.category}</span>`\n : \"\"\n }\n ${\n segment.meta.tags\n ?.map((tag) => `<span class=\"meta-badge\">${tag}</span>`)\n .join(\"\") ?? \"\"\n }\n </div>\n </div>\n \n ${\n segment.usage\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Usage Guidelines</h3>\n ${\n segment.usage.when?.length\n ? `\n <ul class=\"usage-list\">\n ${segment.usage.when\n .map((item) => `<li class=\"usage-item when\">${item}</li>`)\n .join(\"\")}\n </ul>\n `\n : \"\"\n }\n ${\n segment.usage.whenNot?.length\n ? `\n <ul class=\"usage-list\" style=\"margin-top: 12px;\">\n ${segment.usage.whenNot\n .map(\n (item) => `<li class=\"usage-item when-not\">${item}</li>`\n )\n .join(\"\")}\n </ul>\n `\n : \"\"\n }\n </div>\n `\n : \"\"\n }\n \n ${\n segment.props && Object.keys(segment.props).length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Props</h3>\n <table class=\"props-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Type</th>\n <th>Default</th>\n <th>Description</th>\n </tr>\n </thead>\n <tbody>\n ${Object.entries(segment.props)\n .map(\n ([name, prop]) => `\n <tr>\n <td>\n <span class=\"prop-name\">${name}</span>\n ${\n prop.required\n ? '<span class=\"prop-required\">*</span>'\n : \"\"\n }\n </td>\n <td><span class=\"prop-type\">${prop.type}</span></td>\n <td>${\n prop.default !== undefined\n ? `<span class=\"prop-default\">${prop.default}</span>`\n : \"—\"\n }</td>\n <td>${prop.description ?? \"\"}</td>\n </tr>\n `\n )\n .join(\"\")}\n </tbody>\n </table>\n </div>\n `\n : \"\"\n }\n \n ${\n segment.variants?.length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Variants</h3>\n <div class=\"variants-grid\">\n ${segment.variants\n .map(\n (variant) => `\n <div class=\"variant-card\">\n <div class=\"variant-name\">${variant.name}</div>\n ${\n variant.description\n ? `<div class=\"variant-description\">${variant.description}</div>`\n : \"\"\n }\n ${\n variant.code\n ? `<pre class=\"variant-code\">${escapeHtml(\n variant.code\n )}</pre>`\n : \"\"\n }\n </div>\n `\n )\n .join(\"\")}\n </div>\n </div>\n `\n : \"\"\n }\n \n ${\n segment.relations?.length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Related Components</h3>\n <div class=\"relations-list\">\n ${segment.relations\n .map(\n (rel) =>\n `<a href=\"#${\n rel.component\n }\" class=\"relation-tag\" title=\"${rel.note}\">${\n rel.relationship === \"parent\"\n ? \"↑\"\n : rel.relationship === \"child\"\n ? \"↓\"\n : \"↔\"\n } ${rel.component}</a>`\n )\n .join(\"\")}\n </div>\n </div>\n `\n : \"\"\n }\n </section>\n `\n )\n .join(\"\")\n }\n </main>\n </div>\n \n <script>\n // Search functionality\n const searchInput = document.getElementById('search');\n const nav = document.getElementById('nav');\n const main = document.getElementById('main');\n \n searchInput.addEventListener('input', (e) => {\n const query = e.target.value.toLowerCase();\n \n // Filter nav items\n nav.querySelectorAll('.nav-item').forEach(item => {\n const name = item.textContent.toLowerCase();\n item.style.display = name.includes(query) ? '' : 'none';\n });\n \n // Show/hide categories with no visible items\n nav.querySelectorAll('.category').forEach(cat => {\n const hasVisible = Array.from(cat.querySelectorAll('.nav-item')).some(\n item => item.style.display !== 'none'\n );\n cat.style.display = hasVisible ? '' : 'none';\n });\n \n // Filter main sections\n main.querySelectorAll('.component-section').forEach(section => {\n const name = section.id.toLowerCase();\n section.style.display = name.includes(query) ? '' : 'none';\n });\n });\n \n // Highlight active nav item on scroll\n const sections = document.querySelectorAll('.component-section');\n const navItems = document.querySelectorAll('.nav-item');\n \n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navItems.forEach(item => {\n item.classList.toggle('active', item.getAttribute('href') === '#' + entry.target.id);\n });\n }\n });\n }, { threshold: 0.3 });\n \n sections.forEach(section => observer.observe(section));\n </script>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n\n/**\n * Load segments.json and generate static viewer\n */\nexport async function generateViewerFromJson(\n jsonPath: string\n): Promise<string> {\n const content = await readFile(jsonPath, \"utf-8\");\n const data = JSON.parse(content) as CompiledSegmentsFile;\n return generateStaticViewer(data);\n}\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB;AASlB,SAAS,qBAAqB,MAAoC;AACvE,QAAM,WAAW,OAAO,OAAO,KAAK,QAAQ;AAG5C,QAAM,aAAa,oBAAI,IAA6B;AACpD,aAAW,WAAW,UAAU;AAC9B,UAAM,WAAW,QAAQ,KAAK,YAAY;AAC1C,QAAI,CAAC,WAAW,IAAI,QAAQ,GAAG;AAC7B,iBAAW,IAAI,UAAU,CAAC,CAAC;AAAA,IAC7B;AACA,eAAW,IAAI,QAAQ,EAAG,KAAK,OAAO;AAAA,EACxC;AAGA,QAAM,mBAAmB,MAAM,KAAK,WAAW,QAAQ,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MACjE,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;AAAA,EACzB;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKE,MAAM,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/defineSegment.ts","../src/core/storyAdapter.ts","../src/core/storybook-csf.ts","../src/core/context.ts","../src/core/figma.ts","../src/core/token-parser.ts","../src/core/composition.ts"],"sourcesContent":["import type { SegmentDefinition, CompiledSegment, SegmentComponent, BlockDefinition, CompiledBlock } from './types.js';\nimport { segmentDefinitionSchema, blockDefinitionSchema } from './schema.js';\n\n/**\n * Define a segment for a component.\n *\n * This is the main API for creating segment documentation.\n * It provides runtime validation and type safety.\n *\n * @example\n * ```tsx\n * import { defineSegment } from '@fragments/core';\n * import { Button } from './Button';\n *\n * export default defineSegment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * },\n * usage: {\n * when: ['User needs to trigger an action'],\n * whenNot: ['Navigation without side effects'],\n * },\n * props: {\n * variant: {\n * type: 'enum',\n * values: ['primary', 'secondary'],\n * default: 'primary',\n * description: 'Visual style',\n * },\n * },\n * variants: [\n * {\n * name: 'Default',\n * description: 'Default button',\n * render: () => <Button>Click me</Button>,\n * },\n * ],\n * });\n * ```\n */\nexport function defineSegment<TProps>(\n definition: SegmentDefinition<TProps>\n): SegmentDefinition<TProps> {\n // Validate at runtime in development\n if (process.env.NODE_ENV !== 'production') {\n const result = segmentDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid segment definition for \"${definition.meta?.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * Alias for defineSegment - use this for new projects.\n * @see defineSegment\n */\nexport const defineFragment = defineSegment;\n\n/**\n * Compile a segment definition to JSON-serializable format.\n * Used for generating fragments.json for AI consumption.\n */\nexport function compileSegment(\n definition: SegmentDefinition,\n filePath: string\n): CompiledSegment {\n return {\n filePath,\n meta: definition.meta,\n usage: definition.usage,\n props: definition.props,\n relations: definition.relations,\n variants: definition.variants.map((v) => ({\n name: v.name,\n description: v.description,\n code: v.code,\n figma: v.figma,\n })),\n contract: definition.contract,\n _generated: definition._generated,\n };\n}\n\n/**\n * Define a composition block.\n *\n * Blocks are pure data describing how design system components\n * wire together for common use cases.\n */\nexport function defineBlock(definition: BlockDefinition): BlockDefinition {\n if (process.env.NODE_ENV !== 'production') {\n const result = blockDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid block definition for \"${definition.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * @deprecated Use defineBlock instead\n */\nexport const defineRecipe = defineBlock;\n\n/**\n * Compile a block definition to JSON-serializable format.\n */\nexport function compileBlock(\n definition: BlockDefinition,\n filePath: string\n): CompiledBlock {\n return {\n filePath,\n name: definition.name,\n description: definition.description,\n category: definition.category,\n components: definition.components,\n code: definition.code,\n tags: definition.tags,\n };\n}\n\n/**\n * @deprecated Use compileBlock instead\n */\nexport const compileRecipe = compileBlock;\n\n/**\n * Type helper for extracting props type from a component\n */\nexport type InferProps<T> = T extends SegmentComponent<infer P> ? P : never;\n","/**\n * Runtime adapter for converting Storybook CSF modules to Segment definitions.\n *\n * This operates on IMPORTED modules at runtime, not source code parsing.\n * By leveraging Vite's module system, we get 100% accurate render functions\n * without any regex or AST parsing complexity.\n *\n * Supports Storybook 8.x with both CSF2 (Template.bind) and CSF3 (object stories).\n */\n\nimport { createElement, type ComponentType, type ReactNode } from \"react\";\nimport { toId, storyNameFromExport, isExportStory } from \"./storybook-csf.js\";\nimport type {\n SegmentDefinition,\n SegmentMeta,\n SegmentUsage,\n PropDefinition,\n SegmentVariant,\n ControlType,\n VariantLoader,\n PlayFunction,\n PlayFunctionContext,\n VariantRenderOptions,\n} from \"./types.js\";\n\n// Re-export @storybook/csf utilities for use in other modules\nexport { toId, storyNameFromExport, isExportStory };\n\n/**\n * Storybook decorator function signature\n */\nexport type Decorator = (\n Story: () => ReactNode,\n context: StoryContext\n) => ReactNode;\n\n/**\n * Storybook loader function signature\n */\nexport type Loader = (context: StoryContext) => Promise<Record<string, unknown>>;\n\n/**\n * Storybook play function signature (internal, extends StoryContext)\n */\ntype StorybookPlayFunction = (context: StorybookPlayFunctionContext) => Promise<void>;\n\n/**\n * Context passed to Storybook play functions (extends StoryContext for compatibility)\n */\ninterface StorybookPlayFunctionContext extends StoryContext {\n canvasElement: HTMLElement;\n step: (name: string, fn: () => Promise<void>) => Promise<void>;\n}\n\n/**\n * Context passed to decorators and render functions\n */\nexport interface StoryContext {\n args: Record<string, unknown>;\n argTypes: Record<string, StoryArgType>;\n globals: Record<string, unknown>;\n parameters: Record<string, unknown>;\n id: string;\n kind: string;\n name: string;\n story: string;\n viewMode: \"story\" | \"docs\";\n loaded: Record<string, unknown>;\n abortSignal: AbortSignal;\n componentId: string;\n title: string;\n}\n\n/**\n * Storybook Meta (default export)\n */\nexport interface StoryMeta {\n title?: string;\n component?: ComponentType<unknown>;\n subcomponents?: Record<string, ComponentType<unknown>>;\n tags?: string[];\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n component?: string;\n };\n };\n };\n argTypes?: Record<string, StoryArgType>;\n args?: Record<string, unknown>;\n decorators?: Decorator[];\n loaders?: Loader[];\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n // Story filtering\n includeStories?: string[] | RegExp;\n excludeStories?: string[] | RegExp;\n}\n\n/**\n * Storybook argType definition\n */\nexport interface StoryArgType {\n control?:\n | string\n | false\n | { type: string; min?: number; max?: number; step?: number; presetColors?: string[] };\n options?: string[];\n description?: string;\n table?: {\n defaultValue?: { summary: string };\n type?: { summary: string };\n category?: string;\n subcategory?: string;\n disable?: boolean;\n };\n type?: { name: string; required?: boolean };\n name?: string;\n defaultValue?: unknown;\n if?: { arg?: string; exists?: boolean };\n mapping?: Record<string, unknown>;\n action?: string;\n}\n\n/**\n * Storybook Story export (CSF3)\n */\nexport interface Story {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n story?: string;\n };\n };\n };\n name?: string;\n storyName?: string; // Legacy CSF2\n tags?: string[];\n}\n\n/**\n * CSF2 story function (from Template.bind({})) with args attached\n */\nexport type CSF2Story = ((args: Record<string, unknown>) => ReactNode) & {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown>;\n storyName?: string;\n};\n\n/**\n * A complete Storybook module with default meta and named story exports\n */\nexport interface StoryModule {\n default: StoryMeta;\n [exportName: string]: Story | CSF2Story | StoryMeta | unknown;\n}\n\n/**\n * Global configuration from preview.tsx\n */\nexport interface PreviewConfig {\n decorators?: Decorator[];\n parameters?: Record<string, unknown>;\n globalTypes?: Record<string, unknown>;\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n loaders?: Loader[];\n}\n\n// Store for global preview config (set by previewLoader)\nlet globalPreviewConfig: PreviewConfig = {};\n\n/**\n * Set the global preview configuration loaded from .storybook/preview.tsx\n */\nexport function setPreviewConfig(config: PreviewConfig): void {\n globalPreviewConfig = config;\n}\n\n/**\n * Get the current global preview configuration\n */\nexport function getPreviewConfig(): PreviewConfig {\n return globalPreviewConfig;\n}\n\n/**\n * Convert a Storybook module to a Segment definition at runtime.\n *\n * @param storyModule - The imported Storybook module\n * @param filePath - File path for metadata extraction\n * @returns A complete SegmentDefinition ready for the viewer\n */\nexport function storyModuleToSegment(\n storyModule: StoryModule,\n filePath: string\n): SegmentDefinition | null {\n const meta = storyModule.default;\n const component = meta.component;\n\n // Stories without a component (e.g., documentation pages, icon galleries) are skipped\n if (!component) {\n return null;\n }\n\n const componentName = extractComponentName(meta, filePath);\n const category = extractCategory(meta.title);\n const props = convertArgTypes(meta.argTypes ?? {}, globalPreviewConfig.argTypes);\n const variants = extractVariants(storyModule, component, meta);\n\n // Extract Figma URL from parameters.design.url (storybook-addon-designs) or parameters.figma\n const figmaUrl = extractFigmaUrl(meta.parameters);\n\n const segmentMeta: SegmentMeta = {\n name: componentName,\n description:\n meta.parameters?.docs?.description?.component ??\n `${componentName} component`,\n category,\n tags: meta.tags?.filter((t) => t !== \"autodocs\"),\n status: \"stable\",\n figma: figmaUrl,\n };\n\n const usage: SegmentUsage = {\n when: [`Use ${componentName} for its intended purpose`],\n whenNot: [\"When a more specific component is available\"],\n };\n\n return {\n component,\n meta: segmentMeta,\n usage,\n props,\n variants,\n };\n}\n\n/**\n * Extract component name from meta or file path\n */\nfunction extractComponentName(meta: StoryMeta, filePath: string): string {\n // Try title (last segment of path like \"Components/Forms/Button\" -> \"Button\")\n if (meta.title) {\n const parts = meta.title.split(\"/\");\n return parts[parts.length - 1];\n }\n\n // Try component displayName\n if (meta.component?.displayName) {\n return meta.component.displayName;\n }\n\n // Try component name\n if (meta.component?.name && meta.component.name !== \"Component\") {\n return meta.component.name;\n }\n\n // Fallback: extract from file path\n const match = filePath.match(/([^/\\\\]+)\\.stories\\.(tsx?|jsx?)$/);\n return match?.[1] ?? \"Unknown\";\n}\n\n/**\n * Extract category from Storybook title path\n */\nfunction extractCategory(title?: string): string {\n if (!title) return \"general\";\n\n const parts = title.split(\"/\");\n // \"Components/Forms/Button\" -> \"forms\" (need at least 3 parts for a subcategory)\n if (parts.length >= 3) {\n return parts[parts.length - 2].toLowerCase();\n }\n // \"Components/Button\" -> \"general\" (no subcategory specified)\n return \"general\";\n}\n\n/**\n * Extract Figma URL from Storybook parameters\n * Supports storybook-addon-designs format and custom figma parameter\n */\nfunction extractFigmaUrl(parameters?: Record<string, unknown>): string | undefined {\n if (!parameters) return undefined;\n\n // Try storybook-addon-designs format: parameters.design.url\n const design = parameters.design as { url?: string; type?: string } | undefined;\n if (design?.url && typeof design.url === \"string\") {\n return design.url;\n }\n\n // Try custom figma parameter: parameters.figma\n if (typeof parameters.figma === \"string\") {\n return parameters.figma;\n }\n\n return undefined;\n}\n\n/**\n * Convert Storybook argTypes to Segment props\n * Merges global argTypes from preview config with meta argTypes\n */\nfunction convertArgTypes(\n argTypes: Record<string, StoryArgType>,\n globalArgTypes?: Record<string, StoryArgType>\n): Record<string, PropDefinition> {\n const props: Record<string, PropDefinition> = {};\n\n // Merge global and meta argTypes (meta takes precedence)\n const mergedArgTypes = { ...globalArgTypes, ...argTypes };\n\n for (const [name, argType] of Object.entries(mergedArgTypes)) {\n // Skip disabled argTypes\n if (argType.table?.disable) continue;\n // Skip action-only argTypes (no control)\n if (argType.control === false && argType.action) continue;\n\n // Extract control type and options\n const { controlType, controlOptions } = extractControlInfo(argType);\n\n props[name] = {\n type: inferPropType(argType),\n description: argType.description ?? `${name} prop`,\n ...(argType.options && { values: argType.options }),\n ...(argType.table?.defaultValue && {\n default: argType.table.defaultValue.summary,\n }),\n ...(argType.defaultValue !== undefined && {\n default: argType.defaultValue,\n }),\n ...(argType.type?.required && { required: true }),\n ...(controlType && { controlType }),\n ...(controlOptions && Object.keys(controlOptions).length > 0 && { controlOptions }),\n };\n }\n\n return props;\n}\n\n/**\n * Extract control type and options from a Storybook argType\n */\nfunction extractControlInfo(argType: StoryArgType): {\n controlType?: ControlType;\n controlOptions?: PropDefinition[\"controlOptions\"];\n} {\n // Handle no control or explicitly disabled control\n if (argType.control === undefined || argType.control === false) {\n return {};\n }\n\n const control = typeof argType.control === \"string\"\n ? { type: argType.control }\n : argType.control;\n\n // Map control type string to ControlType\n const validControlTypes: ControlType[] = [\n \"text\", \"number\", \"range\", \"boolean\", \"select\", \"multi-select\",\n \"radio\", \"inline-radio\", \"check\", \"inline-check\", \"object\", \"file\", \"color\", \"date\"\n ];\n\n const controlType = validControlTypes.includes(control.type as ControlType)\n ? (control.type as ControlType)\n : undefined;\n\n // Extract control options for controls that need them\n const controlOptions: PropDefinition[\"controlOptions\"] = {};\n\n if (control.min !== undefined) controlOptions.min = control.min;\n if (control.max !== undefined) controlOptions.max = control.max;\n if (control.step !== undefined) controlOptions.step = control.step;\n if (control.presetColors) controlOptions.presetColors = control.presetColors;\n\n return {\n controlType,\n controlOptions: Object.keys(controlOptions).length > 0 ? controlOptions : undefined,\n };\n}\n\n/**\n * Infer prop type from Storybook control/type\n * Handles all Storybook 8.x control types\n */\nfunction inferPropType(argType: StoryArgType): PropDefinition[\"type\"] {\n // Action argType → function\n if (argType.action) return \"function\";\n\n // If has options, it's an enum\n if (argType.options?.length) return \"enum\";\n\n // Check explicit type\n if (argType.type?.name) {\n const typeMap: Record<string, PropDefinition[\"type\"]> = {\n string: \"string\",\n number: \"number\",\n boolean: \"boolean\",\n object: \"object\",\n array: \"array\",\n function: \"function\",\n };\n const mapped = typeMap[argType.type.name];\n if (mapped) return mapped;\n }\n\n // Check control type\n const control =\n typeof argType.control === \"string\"\n ? argType.control\n : argType.control\n ? argType.control.type\n : undefined;\n\n if (control) {\n const controlMap: Record<string, PropDefinition[\"type\"]> = {\n // Text controls\n text: \"string\",\n\n // Number controls\n number: \"number\",\n range: \"number\",\n\n // Boolean controls\n boolean: \"boolean\",\n check: \"boolean\",\n \"inline-check\": \"boolean\",\n\n // Enum/selection controls\n select: \"enum\",\n \"multi-select\": \"enum\",\n radio: \"enum\",\n \"inline-radio\": \"enum\",\n\n // Object controls\n object: \"object\",\n file: \"object\",\n\n // Special string controls\n color: \"string\",\n date: \"string\",\n };\n const mapped = controlMap[control];\n if (mapped) return mapped;\n }\n\n return \"string\";\n}\n\n/**\n * Check if a value looks like a Storybook story\n * Handles both CSF 3 (objects) and CSF 2 (functions from Template.bind({}))\n */\nfunction isStory(value: unknown): value is Story | CSF2Story {\n // CSF 3: Story is an object with args/render/play\n if (typeof value === \"object\" && value !== null) {\n const obj = value as Record<string, unknown>;\n if (\"args\" in obj || \"render\" in obj || \"play\" in obj) return true;\n }\n\n // CSF 2: Story is a function (from Template.bind({})) with args attached\n if (typeof value === \"function\") {\n const fn = value as ((...args: unknown[]) => unknown) & { args?: unknown };\n if (\"args\" in fn) return true;\n }\n\n return false;\n}\n\n/**\n * Extract variants from story exports using @storybook/csf utilities\n */\nfunction extractVariants(\n storyModule: StoryModule,\n component: ComponentType<unknown>,\n meta: StoryMeta\n): SegmentVariant[] {\n const variants: SegmentVariant[] = [];\n\n for (const [exportName, exportValue] of Object.entries(storyModule)) {\n // Skip default export\n if (exportName === \"default\") continue;\n\n // Use isExportStory to filter based on includeStories/excludeStories\n if (!isExportStory(exportName, meta)) continue;\n\n // Check if it's a story\n if (!isStory(exportValue)) continue;\n\n const story = exportValue as Story | CSF2Story;\n\n // Get story name using storyNameFromExport\n const storyName =\n (typeof story === \"object\" && story.name) ||\n (typeof story === \"object\" && story.storyName) ||\n (typeof story === \"function\" && story.storyName) ||\n storyNameFromExport(exportName);\n\n // Generate story ID matching Storybook format\n const storyId = toId(meta.title || \"Unknown\", exportName);\n\n // Extract description based on story format\n let description = `${storyName} variant`;\n if (typeof story === \"object\" && story.parameters?.docs?.description?.story) {\n description = story.parameters.docs.description.story;\n }\n\n // Check for play function and capture it\n const storyPlayFn = typeof story === \"object\" ? story.play : story.play;\n const hasPlayFunction = !!storyPlayFn;\n\n // Create wrapped play function that adapts Storybook context to our PlayFunctionContext\n const wrappedPlay: PlayFunction | undefined = storyPlayFn\n ? async (context: PlayFunctionContext): Promise<void> => {\n // Build full Storybook context for compatibility\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n const fullContext = buildStoryContext(meta, story, args, storyId, storyName);\n\n // Merge our context with Storybook context\n const playContext = {\n ...fullContext,\n canvasElement: context.canvasElement,\n args: context.args,\n step: context.step,\n };\n\n await storyPlayFn(playContext as unknown as StorybookPlayFunctionContext);\n }\n : undefined;\n\n // Get story tags\n const storyTags = typeof story === \"object\" ? story.tags : undefined;\n\n // Collect loaders from global, meta, and story (in order)\n const loaders = collectLoaders(meta, story);\n\n // Compute the merged args for this variant (for code generation)\n const variantArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n\n // Only include args if there are any defined\n const hasArgs = Object.keys(variantArgs).length > 0;\n\n variants.push({\n name: storyName,\n description,\n render: createRenderFunction(story, component, meta, storyId, storyName),\n // Store Storybook-specific metadata\n ...(hasPlayFunction && { hasPlayFunction: true }),\n ...(wrappedPlay && { play: wrappedPlay }),\n ...(storyId && { storyId }),\n ...(storyTags && { tags: storyTags }),\n ...(loaders.length > 0 && { loaders }),\n ...(hasArgs && { args: variantArgs }),\n });\n }\n\n return variants;\n}\n\n/**\n * Collect loaders from global, meta, and story levels\n * Returns wrapped loader functions that execute with context\n */\nfunction collectLoaders(\n meta: StoryMeta,\n story: Story | CSF2Story\n): VariantLoader[] {\n const allLoaders: Loader[] = [\n ...(globalPreviewConfig.loaders ?? []),\n ...(meta.loaders ?? []),\n ...(typeof story === \"function\" ? story.loaders ?? [] : story.loaders ?? []),\n ];\n\n if (allLoaders.length === 0) {\n return [];\n }\n\n // Wrap each loader to execute without requiring context at call time\n // The actual context will be built when the loader is executed\n return allLoaders.map((loader) => {\n return async (): Promise<Record<string, unknown>> => {\n // Create a minimal context for loader execution\n const minimalContext: StoryContext = {\n args: {},\n argTypes: {},\n globals: {},\n parameters: {},\n id: \"\",\n kind: meta.title || \"Unknown\",\n name: \"\",\n story: \"\",\n viewMode: \"story\",\n loaded: {},\n abortSignal: new AbortController().signal,\n componentId: \"\",\n title: meta.title || \"Unknown\",\n };\n return loader(minimalContext);\n };\n });\n}\n\n/**\n * Build a StoryContext for decorators and render functions\n */\nfunction buildStoryContext(\n meta: StoryMeta,\n story: Story | CSF2Story,\n args: Record<string, unknown>,\n storyId: string,\n storyName: string,\n loadedData?: Record<string, unknown>\n): StoryContext {\n const mergedArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"object\" ? story.args : story.args),\n ...args,\n };\n\n const mergedArgTypes = {\n ...globalPreviewConfig.argTypes,\n ...meta.argTypes,\n ...(typeof story === \"object\" ? story.argTypes : story.argTypes),\n };\n\n const mergedParameters = {\n ...globalPreviewConfig.parameters,\n ...meta.parameters,\n ...(typeof story === \"object\" ? story.parameters : story.parameters),\n };\n\n return {\n args: mergedArgs,\n argTypes: mergedArgTypes ?? {},\n globals: {},\n parameters: mergedParameters ?? {},\n id: storyId,\n kind: meta.title || \"Unknown\",\n name: storyName,\n story: storyName,\n viewMode: \"story\",\n loaded: loadedData ?? {},\n abortSignal: new AbortController().signal,\n componentId: toId(meta.title || \"Unknown\", \"\"),\n title: meta.title || \"Unknown\",\n };\n}\n\n/**\n * Create a render function for a story\n * Handles both CSF 3 (objects) and CSF 2 (functions)\n * Applies decorators in correct order: story → meta → global (innermost first)\n * Accepts optional args overrides and loaded data from loaders\n */\nfunction createRenderFunction(\n story: Story | CSF2Story,\n component: ComponentType<unknown>,\n meta: StoryMeta,\n storyId: string,\n storyName: string\n): (options?: VariantRenderOptions) => ReactNode {\n return (options?: VariantRenderOptions) => {\n // Merge args: global → meta → story → runtime overrides\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n ...options?.args, // Runtime overrides from viewer props panel\n };\n\n const loadedData = options?.loadedData;\n\n // Build the story context with loaded data\n const context = buildStoryContext(meta, story, args, storyId, storyName, loadedData);\n\n // Create the base render function\n let renderFn: () => ReactNode;\n\n if (typeof story === \"function\") {\n // CSF 2: Story is a function (from Template.bind({}))\n renderFn = () => story(args);\n } else if (story.render) {\n // CSF 3: Story has custom render function\n // Support both render(args) and render(args, context) signatures\n renderFn = () =>\n story.render!.length >= 2\n ? story.render!(args, context)\n : story.render!(args);\n } else if (meta.render) {\n // CSF 3: Meta has default render function\n renderFn = () =>\n meta.render!.length >= 2\n ? meta.render!(args, context)\n : meta.render!(args);\n } else {\n // Default: render component with args\n renderFn = () => createElement(component, args);\n }\n\n // Collect decorators in Storybook order\n // story → meta → global, then reverse to apply innermost first\n const allDecorators = [\n ...(globalPreviewConfig.decorators ?? []),\n ...(meta.decorators ?? []),\n ...(typeof story === \"function\" ? story.decorators ?? [] : story.decorators ?? []),\n ].reverse();\n\n // Apply decorators if any\n if (allDecorators.length > 0) {\n return applyDecorators(renderFn, allDecorators, context);\n }\n\n return renderFn();\n };\n}\n\n/**\n * Apply decorators in the correct order\n * Decorators wrap from innermost to outermost\n */\nfunction applyDecorators(\n renderFn: () => ReactNode,\n decorators: Decorator[],\n context: StoryContext\n): ReactNode {\n // Start with the base render function\n let storyFn: () => ReactNode = renderFn;\n\n // Each decorator wraps the previous one\n for (const decorator of decorators) {\n const wrappedFn = storyFn;\n storyFn = () => decorator(wrappedFn, context);\n }\n\n return storyFn();\n}\n\n/**\n * Convert PascalCase to Title Case\n * @deprecated Use storyNameFromExport from @storybook/csf instead\n */\nfunction pascalToTitle(name: string): string {\n return name.replace(/([A-Z])/g, \" $1\").trim();\n}\n","import {\n toId as storybookToId,\n storyNameFromExport as storybookStoryNameFromExport,\n isExportStory as storybookIsExportStory,\n} from \"@storybook/csf\";\n\nexport const toId: typeof storybookToId = (...args) => storybookToId(...args);\nexport const storyNameFromExport: typeof storybookStoryNameFromExport = (...args) =>\n storybookStoryNameFromExport(...args);\nexport const isExportStory: typeof storybookIsExportStory = (...args) =>\n storybookIsExportStory(...args);\n","export { generateContext, filterPlaceholders, PLACEHOLDER_PATTERNS } from '@fragments-sdk/context/generate';\nexport type { ContextOptions, ContextResult } from '@fragments-sdk/context/generate';\n","/**\n * Figma property mapping DSL\n *\n * Provides helpers for mapping Figma component properties to code props.\n * Inspired by Figma Code Connect's API.\n *\n * @example\n * ```tsx\n * import { defineSegment, figma } from '@fragments/core';\n *\n * export default defineSegment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * figma: 'https://figma.com/file/abc/Design?node-id=1-2',\n * figmaProps: {\n * children: figma.string('Label'),\n * disabled: figma.boolean('Disabled'),\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * }),\n * },\n * },\n * // ...\n * });\n * ```\n */\n\nimport type {\n FigmaStringMapping,\n FigmaBooleanMapping,\n FigmaEnumMapping,\n FigmaInstanceMapping,\n FigmaChildrenMapping,\n FigmaTextContentMapping,\n} from './types.js';\n\n/**\n * Map a Figma text property to a string prop.\n *\n * @param figmaProperty - The name of the text property in Figma\n * @returns A string mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * label: figma.string('Button Text'),\n * placeholder: figma.string('Placeholder'),\n * }\n * ```\n */\nfunction string(figmaProperty: string): FigmaStringMapping {\n return {\n __type: 'figma-string',\n figmaProperty,\n };\n}\n\n/**\n * Map a Figma boolean property to a boolean prop.\n * Optionally map true/false to different values.\n *\n * @param figmaProperty - The name of the boolean property in Figma\n * @param valueMapping - Optional mapping of true/false to other values\n * @returns A boolean mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * disabled: figma.boolean('Disabled'),\n * // Map boolean to string values\n * size: figma.boolean('Large', { true: 'lg', false: 'md' }),\n * }\n * ```\n */\nfunction boolean(\n figmaProperty: string,\n valueMapping?: { true: unknown; false: unknown }\n): FigmaBooleanMapping {\n return {\n __type: 'figma-boolean',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Map a Figma variant property to an enum prop.\n *\n * @param figmaProperty - The name of the variant property in Figma\n * @param valueMapping - Mapping of Figma values to code values\n * @returns An enum mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * 'Outline': 'outline',\n * }),\n * size: figma.enum('Size', {\n * 'Small': 'sm',\n * 'Medium': 'md',\n * 'Large': 'lg',\n * }),\n * }\n * ```\n */\nfunction enumValue<T extends Record<string, unknown>>(\n figmaProperty: string,\n valueMapping: T\n): FigmaEnumMapping {\n return {\n __type: 'figma-enum',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Reference a nested Figma component instance.\n * Use this when a prop accepts a component that's represented\n * as an instance swap in Figma.\n *\n * @param figmaProperty - The name of the instance property in Figma\n * @returns An instance mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * icon: figma.instance('Icon'),\n * avatar: figma.instance('Avatar'),\n * }\n * ```\n */\nfunction instance(figmaProperty: string): FigmaInstanceMapping {\n return {\n __type: 'figma-instance',\n figmaProperty,\n };\n}\n\n/**\n * Render children from specific Figma layers.\n * Use this when children are represented as named layers in Figma.\n *\n * @param layers - Array of layer names to include as children\n * @returns A children mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * children: figma.children(['Title', 'Description', 'Actions']),\n * }\n * ```\n */\nfunction children(layers: string[]): FigmaChildrenMapping {\n return {\n __type: 'figma-children',\n layers,\n };\n}\n\n/**\n * Extract text content from a Figma text layer.\n * Use this when a prop should be the actual text from a layer.\n *\n * @param layer - The name of the text layer in Figma\n * @returns A text content mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * title: figma.textContent('Header Text'),\n * description: figma.textContent('Body Text'),\n * }\n * ```\n */\nfunction textContent(layer: string): FigmaTextContentMapping {\n return {\n __type: 'figma-text-content',\n layer,\n };\n}\n\n/**\n * Figma property mapping helpers.\n *\n * Use these to define how Figma properties map to your component props.\n * The mappings are used for:\n * - Generating accurate code snippets in Figma Dev Mode\n * - AI agents understanding the design-to-code relationship\n * - Automated design verification\n */\nexport const figma = {\n string,\n boolean,\n enum: enumValue,\n instance,\n children,\n textContent,\n} as const;\n\n/**\n * Helper type to check if a value is a Figma prop mapping\n */\nexport function isFigmaPropMapping(\n value: unknown\n): value is FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping {\n if (typeof value !== 'object' || value === null || !('__type' in value)) {\n return false;\n }\n const typeValue = (value as Record<string, unknown>).__type;\n return typeof typeValue === 'string' && typeValue.startsWith('figma-');\n}\n\n/**\n * Resolve a Figma prop mapping to an actual value given Figma property values.\n *\n * @param mapping - The Figma prop mapping\n * @param figmaValues - Object containing Figma property values\n * @returns The resolved value for the code prop\n */\nexport function resolveFigmaMapping(\n mapping: FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping,\n figmaValues: Record<string, unknown>\n): unknown {\n switch (mapping.__type) {\n case 'figma-string':\n return figmaValues[mapping.figmaProperty] ?? '';\n\n case 'figma-boolean': {\n const boolValue = figmaValues[mapping.figmaProperty] as boolean;\n if (mapping.valueMapping) {\n return boolValue ? mapping.valueMapping.true : mapping.valueMapping.false;\n }\n return boolValue;\n }\n\n case 'figma-enum': {\n const enumKey = figmaValues[mapping.figmaProperty] as string;\n return mapping.valueMapping[enumKey] ?? enumKey;\n }\n\n case 'figma-instance':\n // Instance mappings return the instance reference\n return figmaValues[mapping.figmaProperty];\n\n case 'figma-children':\n // Children mappings return array of layer contents\n return mapping.layers.map((layer) => figmaValues[layer]);\n\n case 'figma-text-content':\n return figmaValues[mapping.layer] ?? '';\n\n default:\n return undefined;\n }\n}\n","/**\n * Token Parser — extracts CSS custom property declarations from SCSS/CSS files.\n *\n * Parses files for `--prefix-*: value;` declarations and groups them\n * by SCSS comment sections (e.g., `// Typography`, `// Colors`).\n * Falls back to naming-convention-based categorization when comments\n * are absent.\n */\n\nexport interface ParsedToken {\n /** Full CSS variable name (e.g., \"--fui-color-accent\") */\n name: string;\n /** Category inferred from SCSS comment or naming convention */\n category: string;\n /** Description from inline comment, if any */\n description?: string;\n}\n\nexport interface TokenParseOutput {\n /** Detected prefix (e.g., \"--fui-\") */\n prefix: string;\n /** Tokens grouped by category */\n categories: Record<string, ParsedToken[]>;\n /** Total number of tokens found */\n total: number;\n}\n\n/**\n * Category inference from naming conventions.\n * Order matters — first match wins.\n */\nconst NAMING_RULES: Array<{ pattern: RegExp; category: string }> = [\n { pattern: /--\\w+-font-/, category: 'typography' },\n { pattern: /--\\w+-line-height-/, category: 'typography' },\n { pattern: /--\\w+-space-/, category: 'spacing' },\n { pattern: /--\\w+-padding-/, category: 'spacing' },\n { pattern: /--\\w+-radius-/, category: 'radius' },\n { pattern: /--\\w+-color-/, category: 'colors' },\n { pattern: /--\\w+-bg-/, category: 'surfaces' },\n { pattern: /--\\w+-text-/, category: 'text' },\n { pattern: /--\\w+-border/, category: 'borders' },\n { pattern: /--\\w+-shadow-/, category: 'shadows' },\n { pattern: /--\\w+-focus-/, category: 'focus' },\n { pattern: /--\\w+-transition-/, category: 'transitions' },\n { pattern: /--\\w+-scrollbar-/, category: 'scrollbar' },\n { pattern: /--\\w+-z-index/, category: 'z-index' },\n { pattern: /--\\w+-(button|input|touch)-/, category: 'component-sizing' },\n { pattern: /--\\w+-appshell-/, category: 'layout' },\n { pattern: /--\\w+-header-/, category: 'layout' },\n { pattern: /--\\w+-code-/, category: 'code' },\n { pattern: /--\\w+-tooltip-/, category: 'tooltip' },\n { pattern: /--\\w+-hero-/, category: 'marketing' },\n];\n\n/**\n * Infer category from a CSS variable name using naming conventions.\n */\nfunction inferCategory(name: string): string {\n for (const rule of NAMING_RULES) {\n if (rule.pattern.test(name)) {\n return rule.category;\n }\n }\n return 'other';\n}\n\n/**\n * Detect the most common prefix from a list of CSS variable names.\n * E.g., given [\"--fui-color-accent\", \"--fui-bg-primary\"] → \"--fui-\"\n */\nfunction detectPrefix(names: string[]): string {\n if (names.length === 0) return '--';\n\n // Find common prefix after \"--\"\n const stripped = names.map((n) => n.slice(2)); // remove \"--\"\n let prefix = '';\n const first = stripped[0];\n\n for (let i = 0; i < first.length; i++) {\n const ch = first[i];\n if (stripped.every((s) => s[i] === ch)) {\n prefix += ch;\n } else {\n break;\n }\n }\n\n // Trim to last hyphen to get clean prefix\n const lastHyphen = prefix.lastIndexOf('-');\n if (lastHyphen > 0) {\n prefix = prefix.slice(0, lastHyphen + 1);\n }\n\n return `--${prefix}`;\n}\n\n/**\n * Normalize a SCSS comment into a category name.\n * \"// Typography\" → \"typography\"\n * \"// Component heights\" → \"component-sizing\"\n * \"// Hero/Marketing gradient\" → \"marketing\"\n */\nfunction normalizeCategory(comment: string): string {\n const text = comment\n .trim()\n .replace(/^\\/\\/\\s*/, '')\n .replace(/^\\/\\*+\\s*/, '')\n .replace(/\\s*\\*+\\/$/, '')\n .trim()\n .toLowerCase();\n\n // Map common comment headings to clean category names\n const mappings: Record<string, string> = {\n 'base configuration': 'base',\n 'typography': 'typography',\n 'spacing (micro)': 'spacing',\n 'spacing': 'spacing',\n 'density padding': 'spacing',\n 'border radius': 'radius',\n 'transitions': 'transitions',\n 'colors': 'colors',\n 'surfaces': 'surfaces',\n 'text': 'text',\n 'borders': 'borders',\n 'shadows': 'shadows',\n 'focus': 'focus',\n 'scrollbar': 'scrollbar',\n 'component heights': 'component-sizing',\n 'appshell layout': 'layout',\n 'codeblock': 'code',\n 'tooltip': 'tooltip',\n 'hero/marketing gradient': 'marketing',\n };\n\n return mappings[text] ?? text.replace(/\\s+/g, '-');\n}\n\n/**\n * Parse a SCSS or CSS file and extract CSS custom property declarations.\n *\n * Handles two grouping strategies:\n * 1. Comment-based: Uses `// Category` comments above groups of declarations\n * 2. Naming-based: Falls back to inferring category from variable name patterns\n */\nexport function parseTokenFile(content: string, filePath: string): TokenParseOutput {\n const lines = content.split('\\n');\n const tokens: ParsedToken[] = [];\n const seenNames = new Set<string>();\n let currentCategory = 'other';\n let hasCommentCategories = false;\n\n // Regex for CSS custom property declarations\n // Matches: --name: value; (with optional SCSS interpolation)\n const varDeclRegex = /^\\s*(--[\\w-]+)\\s*:/;\n // Regex for section comments (// Category or /* Category */)\n // Allow any characters after uppercase start (including / for \"Hero/Marketing\")\n const sectionCommentRegex = /^\\s*\\/\\/\\s+([A-Z].+)$/;\n\n for (const line of lines) {\n // Check for section comment\n const commentMatch = line.match(sectionCommentRegex);\n if (commentMatch) {\n const normalized = normalizeCategory(commentMatch[0]);\n if (normalized) {\n currentCategory = normalized;\n hasCommentCategories = true;\n }\n continue;\n }\n\n // Check for CSS variable declaration\n const varMatch = line.match(varDeclRegex);\n if (varMatch) {\n const name = varMatch[1];\n\n // Deduplicate: keep only the first occurrence of each variable.\n // Dark mode and high contrast blocks redefine the same variables\n // with different values — we only want the canonical list.\n if (seenNames.has(name)) continue;\n seenNames.add(name);\n\n // Extract inline comment if present\n const inlineComment = line.match(/\\/\\/\\s*(.+)$/);\n const description = inlineComment ? inlineComment[1].trim() : undefined;\n\n tokens.push({\n name,\n category: hasCommentCategories ? currentCategory : inferCategory(name),\n description,\n });\n }\n }\n\n // Group by category\n const categories: Record<string, ParsedToken[]> = {};\n for (const token of tokens) {\n if (!categories[token.category]) {\n categories[token.category] = [];\n }\n categories[token.category].push(token);\n }\n\n // Detect prefix\n const prefix = detectPrefix(tokens.map((t) => t.name));\n\n return {\n prefix,\n categories,\n total: tokens.length,\n };\n}\n","import type { CompiledSegment, RelationshipType } from \"./types.js\";\nimport type { ComponentGraph } from \"@fragments-sdk/context/graph\";\nimport { ComponentGraphEngine } from \"@fragments-sdk/context/graph\";\n\n// --- Public types ---\n\nexport interface CompositionWarning {\n type:\n | \"missing_parent\"\n | \"missing_child\"\n | \"missing_composition\"\n | \"redundant_alternative\"\n | \"deprecated\"\n | \"experimental\";\n component: string;\n message: string;\n relatedComponent?: string;\n}\n\nexport interface CompositionSuggestion {\n component: string;\n reason: string;\n relationship: RelationshipType | \"category_gap\";\n sourceComponent: string;\n}\n\nexport interface CompositionGuideline {\n component: string;\n guideline: string;\n}\n\nexport interface CompositionAnalysis {\n /** The validated component names (filtered to those that exist) */\n components: string[];\n\n /** Components requested but not found in the registry */\n unknown: string[];\n\n /** Issues with the current selection */\n warnings: CompositionWarning[];\n\n /** Components to consider adding */\n suggestions: CompositionSuggestion[];\n\n /** Relevant usage guidelines for the selected components */\n guidelines: CompositionGuideline[];\n}\n\n// --- Category affinities ---\n\nconst CATEGORY_AFFINITIES: Record<string, string[]> = {\n forms: [\"feedback\"],\n actions: [\"feedback\"],\n};\n\n// --- Main function ---\n\n/**\n * Analyzes a set of components as a composition group.\n * Returns warnings about missing relations, usage conflicts,\n * and suggestions for additional components.\n *\n * When a ComponentGraph is provided via `options.graph`, the analysis is\n * enhanced with graph-based dependency detection and block-based suggestions.\n *\n * Browser-safe: no Node.js APIs used.\n */\nexport function analyzeComposition(\n segments: Record<string, CompiledSegment>,\n componentNames: string[],\n _context?: string,\n options?: { graph?: ComponentGraph },\n): CompositionAnalysis {\n const allNames = new Set(Object.keys(segments));\n\n // 1. Validate names\n const components: string[] = [];\n const unknown: string[] = [];\n for (const name of componentNames) {\n if (allNames.has(name)) {\n components.push(name);\n } else {\n unknown.push(name);\n }\n }\n\n const selectedSet = new Set(components);\n const warnings: CompositionWarning[] = [];\n const suggestions: CompositionSuggestion[] = [];\n const guidelines: CompositionGuideline[] = [];\n\n // Track suggestions to avoid duplicates\n const suggestedSet = new Set<string>();\n\n for (const name of components) {\n const segment = segments[name];\n\n // 2. Relation checks\n if (segment.relations) {\n for (const rel of segment.relations) {\n switch (rel.relationship) {\n case \"parent\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_parent\",\n component: name,\n message: `\"${name}\" expects to be wrapped by \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"child\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${name}\" typically contains \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"child\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"composition\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_composition\",\n component: name,\n message: `\"${name}\" is typically used together with \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"sibling\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${rel.component}\" is a sibling of \"${name}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"sibling\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"alternative\":\n if (selectedSet.has(rel.component)) {\n warnings.push({\n type: \"redundant_alternative\",\n component: name,\n message: `\"${name}\" and \"${rel.component}\" are alternatives — using both may be redundant${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n }\n }\n }\n\n // 3. Usage conflict checks (whenNot)\n if (segment.usage?.whenNot) {\n for (const whenNotEntry of segment.usage.whenNot) {\n const lower = whenNotEntry.toLowerCase();\n for (const other of components) {\n if (other !== name && lower.includes(other.toLowerCase())) {\n guidelines.push({\n component: name,\n guideline: `Potential conflict with \"${other}\": ${whenNotEntry}`,\n });\n }\n }\n }\n }\n\n // 4. Status warnings\n if (segment.meta.status === \"deprecated\") {\n warnings.push({\n type: \"deprecated\",\n component: name,\n message: segment.meta.description\n ? `\"${name}\" is deprecated: ${segment.meta.description}`\n : `\"${name}\" is deprecated`,\n });\n } else if (segment.meta.status === \"experimental\") {\n warnings.push({\n type: \"experimental\",\n component: name,\n message: `\"${name}\" is experimental and may change without notice`,\n });\n }\n }\n\n // 5. Category gap analysis\n const selectedCategories = new Set(\n components.map((name) => segments[name].meta.category)\n );\n\n for (const [category, affinities] of Object.entries(CATEGORY_AFFINITIES)) {\n if (!selectedCategories.has(category)) continue;\n\n for (const neededCategory of affinities) {\n if (selectedCategories.has(neededCategory)) continue;\n\n // Find the best component from the needed category\n const candidate = findBestCategoryCandidate(\n segments,\n neededCategory,\n selectedSet,\n suggestedSet\n );\n if (candidate) {\n suggestions.push({\n component: candidate,\n reason: `Compositions using \"${category}\" components often benefit from a \"${neededCategory}\" component`,\n relationship: \"category_gap\",\n sourceComponent: components.find(\n (n) => segments[n].meta.category === category\n )!,\n });\n suggestedSet.add(candidate);\n }\n }\n }\n\n // 6. Graph-enhanced analysis (when graph data is available)\n if (options?.graph) {\n const engine = new ComponentGraphEngine(options.graph);\n\n // Add graph-based dependency warnings\n for (const name of components) {\n const deps = engine.dependencies(name, [\"imports\", \"hook-depends\"]);\n for (const dep of deps) {\n if (\n !selectedSet.has(dep.target) &&\n !suggestedSet.has(dep.target) &&\n allNames.has(dep.target)\n ) {\n suggestions.push({\n component: dep.target,\n reason: `\"${name}\" ${dep.type === \"hook-depends\" ? \"uses a hook from\" : \"imports\"} \"${dep.target}\"`,\n relationship: \"composition\",\n sourceComponent: name,\n });\n suggestedSet.add(dep.target);\n }\n }\n }\n\n // Add block-based suggestions\n for (const name of components) {\n const blocks = engine.blocksUsing(name);\n for (const blockName of blocks) {\n // Find other components in this block that aren't selected\n const blockComps = options.graph.edges\n .filter(\n (e) =>\n e.type === \"composes\" &&\n e.provenance === `block:${blockName}` &&\n (e.source === name || e.target === name)\n )\n .map((e) => (e.source === name ? e.target : e.source));\n\n for (const comp of blockComps) {\n if (\n !selectedSet.has(comp) &&\n !suggestedSet.has(comp) &&\n allNames.has(comp)\n ) {\n suggestions.push({\n component: comp,\n reason: `\"${name}\" and \"${comp}\" are used together in the \"${blockName}\" block`,\n relationship: \"composition\",\n sourceComponent: name,\n });\n suggestedSet.add(comp);\n }\n }\n }\n }\n }\n\n return { components, unknown, warnings, suggestions, guidelines };\n}\n\n/**\n * Find the best candidate component from a given category.\n * Prefers stable components and avoids already-selected or already-suggested ones.\n */\nfunction findBestCategoryCandidate(\n segments: Record<string, CompiledSegment>,\n category: string,\n selectedSet: Set<string>,\n suggestedSet: Set<string>\n): string | null {\n let best: string | null = null;\n let bestScore = -1;\n\n for (const [name, segment] of Object.entries(segments)) {\n if (segment.meta.category !== category) continue;\n if (selectedSet.has(name) || suggestedSet.has(name)) continue;\n\n const status = segment.meta.status ?? \"stable\";\n let score = 0;\n if (status === \"stable\") score = 3;\n else if (status === \"beta\") score = 2;\n else if (status === \"experimental\") score = 1;\n // deprecated gets 0\n\n if (score > bestScore) {\n bestScore = score;\n best = name;\n }\n }\n\n return best;\n}\n"],"mappings":";;;;;;;AA2CO,SAAS,cACd,YAC2B;AAE3B,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAM,SAAS,wBAAwB,UAAU,UAAU;AAC3D,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAClD,KAAK,IAAI;AACZ,YAAM,IAAI;AAAA,QACR,mCAAmC,WAAW,MAAM,QAAQ,SAAS;AAAA,EAAO,MAAM;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAMO,IAAM,iBAAiB;AAMvB,SAAS,eACd,YACA,UACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA,MAAM,WAAW;AAAA,IACjB,OAAO,WAAW;AAAA,IAClB,OAAO,WAAW;AAAA,IAClB,WAAW,WAAW;AAAA,IACtB,UAAU,WAAW,SAAS,IAAI,CAAC,OAAO;AAAA,MACxC,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,IACX,EAAE;AAAA,IACF,UAAU,WAAW;AAAA,IACrB,YAAY,WAAW;AAAA,EACzB;AACF;AAQO,SAAS,YAAY,YAA8C;AACxE,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAM,SAAS,sBAAsB,UAAU,UAAU;AACzD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAClD,KAAK,IAAI;AACZ,YAAM,IAAI;AAAA,QACR,iCAAiC,WAAW,QAAQ,SAAS;AAAA,EAAO,MAAM;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,IAAM,eAAe;AAKrB,SAAS,aACd,YACA,UACe;AACf,SAAO;AAAA,IACL;AAAA,IACA,MAAM,WAAW;AAAA,IACjB,aAAa,WAAW;AAAA,IACxB,UAAU,WAAW;AAAA,IACrB,YAAY,WAAW;AAAA,IACvB,MAAM,WAAW;AAAA,IACjB,MAAM,WAAW;AAAA,EACnB;AACF;AAKO,IAAM,gBAAgB;;;ACnI7B,SAAS,qBAAyD;;;ACVlE;AAAA,EACE,QAAQ;AAAA,EACR,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,OACZ;AAEA,IAAM,OAA6B,IAAI,SAAS,cAAc,GAAG,IAAI;AACrE,IAAM,sBAA2D,IAAI,SAC1E,6BAA6B,GAAG,IAAI;AAC/B,IAAM,gBAA+C,IAAI,SAC9D,uBAAuB,GAAG,IAAI;;;ADyKhC,IAAI,sBAAqC,CAAC;AAKnC,SAAS,iBAAiB,QAA6B;AAC5D,wBAAsB;AACxB;AAKO,SAAS,mBAAkC;AAChD,SAAO;AACT;AASO,SAAS,qBACd,aACA,UAC0B;AAC1B,QAAM,OAAO,YAAY;AACzB,QAAM,YAAY,KAAK;AAGvB,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,qBAAqB,MAAM,QAAQ;AACzD,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAC3C,QAAM,QAAQ,gBAAgB,KAAK,YAAY,CAAC,GAAG,oBAAoB,QAAQ;AAC/E,QAAM,WAAW,gBAAgB,aAAa,WAAW,IAAI;AAG7D,QAAM,WAAW,gBAAgB,KAAK,UAAU;AAEhD,QAAM,cAA2B;AAAA,IAC/B,MAAM;AAAA,IACN,aACE,KAAK,YAAY,MAAM,aAAa,aACpC,GAAG,aAAa;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,MAAM,OAAO,CAAC,MAAM,MAAM,UAAU;AAAA,IAC/C,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AAEA,QAAM,QAAsB;AAAA,IAC1B,MAAM,CAAC,OAAO,aAAa,2BAA2B;AAAA,IACtD,SAAS,CAAC,6CAA6C;AAAA,EACzD;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,qBAAqB,MAAiB,UAA0B;AAEvE,MAAI,KAAK,OAAO;AACd,UAAM,QAAQ,KAAK,MAAM,MAAM,GAAG;AAClC,WAAO,MAAM,MAAM,SAAS,CAAC;AAAA,EAC/B;AAGA,MAAI,KAAK,WAAW,aAAa;AAC/B,WAAO,KAAK,UAAU;AAAA,EACxB;AAGA,MAAI,KAAK,WAAW,QAAQ,KAAK,UAAU,SAAS,aAAa;AAC/D,WAAO,KAAK,UAAU;AAAA,EACxB;AAGA,QAAM,QAAQ,SAAS,MAAM,kCAAkC;AAC/D,SAAO,QAAQ,CAAC,KAAK;AACvB;AAKA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MAAM,MAAM,GAAG;AAE7B,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO,MAAM,MAAM,SAAS,CAAC,EAAE,YAAY;AAAA,EAC7C;AAEA,SAAO;AACT;AAMA,SAAS,gBAAgB,YAA0D;AACjF,MAAI,CAAC,WAAY,QAAO;AAGxB,QAAM,SAAS,WAAW;AAC1B,MAAI,QAAQ,OAAO,OAAO,OAAO,QAAQ,UAAU;AACjD,WAAO,OAAO;AAAA,EAChB;AAGA,MAAI,OAAO,WAAW,UAAU,UAAU;AACxC,WAAO,WAAW;AAAA,EACpB;AAEA,SAAO;AACT;AAMA,SAAS,gBACP,UACA,gBACgC;AAChC,QAAM,QAAwC,CAAC;AAG/C,QAAM,iBAAiB,EAAE,GAAG,gBAAgB,GAAG,SAAS;AAExD,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,cAAc,GAAG;AAE5D,QAAI,QAAQ,OAAO,QAAS;AAE5B,QAAI,QAAQ,YAAY,SAAS,QAAQ,OAAQ;AAGjD,UAAM,EAAE,aAAa,eAAe,IAAI,mBAAmB,OAAO;AAElE,UAAM,IAAI,IAAI;AAAA,MACZ,MAAM,cAAc,OAAO;AAAA,MAC3B,aAAa,QAAQ,eAAe,GAAG,IAAI;AAAA,MAC3C,GAAI,QAAQ,WAAW,EAAE,QAAQ,QAAQ,QAAQ;AAAA,MACjD,GAAI,QAAQ,OAAO,gBAAgB;AAAA,QACjC,SAAS,QAAQ,MAAM,aAAa;AAAA,MACtC;AAAA,MACA,GAAI,QAAQ,iBAAiB,UAAa;AAAA,QACxC,SAAS,QAAQ;AAAA,MACnB;AAAA,MACA,GAAI,QAAQ,MAAM,YAAY,EAAE,UAAU,KAAK;AAAA,MAC/C,GAAI,eAAe,EAAE,YAAY;AAAA,MACjC,GAAI,kBAAkB,OAAO,KAAK,cAAc,EAAE,SAAS,KAAK,EAAE,eAAe;AAAA,IACnF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,mBAAmB,SAG1B;AAEA,MAAI,QAAQ,YAAY,UAAa,QAAQ,YAAY,OAAO;AAC9D,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,OAAO,QAAQ,YAAY,WACvC,EAAE,MAAM,QAAQ,QAAQ,IACxB,QAAQ;AAGZ,QAAM,oBAAmC;AAAA,IACvC;AAAA,IAAQ;AAAA,IAAU;AAAA,IAAS;AAAA,IAAW;AAAA,IAAU;AAAA,IAChD;AAAA,IAAS;AAAA,IAAgB;AAAA,IAAS;AAAA,IAAgB;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAS;AAAA,EAC/E;AAEA,QAAM,cAAc,kBAAkB,SAAS,QAAQ,IAAmB,IACrE,QAAQ,OACT;AAGJ,QAAM,iBAAmD,CAAC;AAE1D,MAAI,QAAQ,QAAQ,OAAW,gBAAe,MAAM,QAAQ;AAC5D,MAAI,QAAQ,QAAQ,OAAW,gBAAe,MAAM,QAAQ;AAC5D,MAAI,QAAQ,SAAS,OAAW,gBAAe,OAAO,QAAQ;AAC9D,MAAI,QAAQ,aAAc,gBAAe,eAAe,QAAQ;AAEhE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;AAAA,EAC5E;AACF;AAMA,SAAS,cAAc,SAA+C;AAEpE,MAAI,QAAQ,OAAQ,QAAO;AAG3B,MAAI,QAAQ,SAAS,OAAQ,QAAO;AAGpC,MAAI,QAAQ,MAAM,MAAM;AACtB,UAAM,UAAkD;AAAA,MACtD,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AACA,UAAM,SAAS,QAAQ,QAAQ,KAAK,IAAI;AACxC,QAAI,OAAQ,QAAO;AAAA,EACrB;AAGA,QAAM,UACJ,OAAO,QAAQ,YAAY,WACvB,QAAQ,UACR,QAAQ,UACN,QAAQ,QAAQ,OAChB;AAER,MAAI,SAAS;AACX,UAAM,aAAqD;AAAA;AAAA,MAEzD,MAAM;AAAA;AAAA,MAGN,QAAQ;AAAA,MACR,OAAO;AAAA;AAAA,MAGP,SAAS;AAAA,MACT,OAAO;AAAA,MACP,gBAAgB;AAAA;AAAA,MAGhB,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,OAAO;AAAA,MACP,gBAAgB;AAAA;AAAA,MAGhB,QAAQ;AAAA,MACR,MAAM;AAAA;AAAA,MAGN,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AACA,UAAM,SAAS,WAAW,OAAO;AACjC,QAAI,OAAQ,QAAO;AAAA,EACrB;AAEA,SAAO;AACT;AAMA,SAAS,QAAQ,OAA4C;AAE3D,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,MAAM;AACZ,QAAI,UAAU,OAAO,YAAY,OAAO,UAAU,IAAK,QAAO;AAAA,EAChE;AAGA,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,KAAK;AACX,QAAI,UAAU,GAAI,QAAO;AAAA,EAC3B;AAEA,SAAO;AACT;AAKA,SAAS,gBACP,aACA,WACA,MACkB;AAClB,QAAM,WAA6B,CAAC;AAEpC,aAAW,CAAC,YAAY,WAAW,KAAK,OAAO,QAAQ,WAAW,GAAG;AAEnE,QAAI,eAAe,UAAW;AAG9B,QAAI,CAAC,cAAc,YAAY,IAAI,EAAG;AAGtC,QAAI,CAAC,QAAQ,WAAW,EAAG;AAE3B,UAAM,QAAQ;AAGd,UAAM,YACH,OAAO,UAAU,YAAY,MAAM,QACnC,OAAO,UAAU,YAAY,MAAM,aACnC,OAAO,UAAU,cAAc,MAAM,aACtC,oBAAoB,UAAU;AAGhC,UAAM,UAAU,KAAK,KAAK,SAAS,WAAW,UAAU;AAGxD,QAAI,cAAc,GAAG,SAAS;AAC9B,QAAI,OAAO,UAAU,YAAY,MAAM,YAAY,MAAM,aAAa,OAAO;AAC3E,oBAAc,MAAM,WAAW,KAAK,YAAY;AAAA,IAClD;AAGA,UAAM,cAAc,OAAO,UAAU,WAAW,MAAM,OAAO,MAAM;AACnE,UAAM,kBAAkB,CAAC,CAAC;AAG1B,UAAM,cAAwC,cAC1C,OAAO,YAAgD;AAErD,YAAM,OAAO;AAAA,QACX,GAAG,oBAAoB;AAAA,QACvB,GAAG,KAAK;AAAA,QACR,GAAI,OAAO,UAAU,aAAa,MAAM,OAAO,MAAM;AAAA,MACvD;AACA,YAAM,cAAc,kBAAkB,MAAM,OAAO,MAAM,SAAS,SAAS;AAG3E,YAAM,cAAc;AAAA,QAClB,GAAG;AAAA,QACH,eAAe,QAAQ;AAAA,QACvB,MAAM,QAAQ;AAAA,QACd,MAAM,QAAQ;AAAA,MAChB;AAEA,YAAM,YAAY,WAAsD;AAAA,IAC1E,IACA;AAGJ,UAAM,YAAY,OAAO,UAAU,WAAW,MAAM,OAAO;AAG3D,UAAM,UAAU,eAAe,MAAM,KAAK;AAG1C,UAAM,cAAc;AAAA,MAClB,GAAG,oBAAoB;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,GAAI,OAAO,UAAU,aAAa,MAAM,OAAO,MAAM;AAAA,IACvD;AAGA,UAAM,UAAU,OAAO,KAAK,WAAW,EAAE,SAAS;AAElD,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,QAAQ,qBAAqB,OAAO,WAAW,MAAM,SAAS,SAAS;AAAA;AAAA,MAEvE,GAAI,mBAAmB,EAAE,iBAAiB,KAAK;AAAA,MAC/C,GAAI,eAAe,EAAE,MAAM,YAAY;AAAA,MACvC,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,GAAI,aAAa,EAAE,MAAM,UAAU;AAAA,MACnC,GAAI,QAAQ,SAAS,KAAK,EAAE,QAAQ;AAAA,MACpC,GAAI,WAAW,EAAE,MAAM,YAAY;AAAA,IACrC,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMA,SAAS,eACP,MACA,OACiB;AACjB,QAAM,aAAuB;AAAA,IAC3B,GAAI,oBAAoB,WAAW,CAAC;AAAA,IACpC,GAAI,KAAK,WAAW,CAAC;AAAA,IACrB,GAAI,OAAO,UAAU,aAAa,MAAM,WAAW,CAAC,IAAI,MAAM,WAAW,CAAC;AAAA,EAC5E;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,CAAC;AAAA,EACV;AAIA,SAAO,WAAW,IAAI,CAAC,WAAW;AAChC,WAAO,YAA8C;AAEnD,YAAM,iBAA+B;AAAA,QACnC,MAAM,CAAC;AAAA,QACP,UAAU,CAAC;AAAA,QACX,SAAS,CAAC;AAAA,QACV,YAAY,CAAC;AAAA,QACb,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,aAAa,IAAI,gBAAgB,EAAE;AAAA,QACnC,aAAa;AAAA,QACb,OAAO,KAAK,SAAS;AAAA,MACvB;AACA,aAAO,OAAO,cAAc;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;AAKA,SAAS,kBACP,MACA,OACA,MACA,SACA,WACA,YACc;AACd,QAAM,aAAa;AAAA,IACjB,GAAG,oBAAoB;AAAA,IACvB,GAAG,KAAK;AAAA,IACR,GAAI,OAAO,UAAU,WAAW,MAAM,OAAO,MAAM;AAAA,IACnD,GAAG;AAAA,EACL;AAEA,QAAM,iBAAiB;AAAA,IACrB,GAAG,oBAAoB;AAAA,IACvB,GAAG,KAAK;AAAA,IACR,GAAI,OAAO,UAAU,WAAW,MAAM,WAAW,MAAM;AAAA,EACzD;AAEA,QAAM,mBAAmB;AAAA,IACvB,GAAG,oBAAoB;AAAA,IACvB,GAAG,KAAK;AAAA,IACR,GAAI,OAAO,UAAU,WAAW,MAAM,aAAa,MAAM;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,kBAAkB,CAAC;AAAA,IAC7B,SAAS,CAAC;AAAA,IACV,YAAY,oBAAoB,CAAC;AAAA,IACjC,IAAI;AAAA,IACJ,MAAM,KAAK,SAAS;AAAA,IACpB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,cAAc,CAAC;AAAA,IACvB,aAAa,IAAI,gBAAgB,EAAE;AAAA,IACnC,aAAa,KAAK,KAAK,SAAS,WAAW,EAAE;AAAA,IAC7C,OAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAQA,SAAS,qBACP,OACA,WACA,MACA,SACA,WAC+C;AAC/C,SAAO,CAAC,YAAmC;AAEzC,UAAM,OAAO;AAAA,MACX,GAAG,oBAAoB;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,GAAI,OAAO,UAAU,aAAa,MAAM,OAAO,MAAM;AAAA,MACrD,GAAG,SAAS;AAAA;AAAA,IACd;AAEA,UAAM,aAAa,SAAS;AAG5B,UAAM,UAAU,kBAAkB,MAAM,OAAO,MAAM,SAAS,WAAW,UAAU;AAGnF,QAAI;AAEJ,QAAI,OAAO,UAAU,YAAY;AAE/B,iBAAW,MAAM,MAAM,IAAI;AAAA,IAC7B,WAAW,MAAM,QAAQ;AAGvB,iBAAW,MACT,MAAM,OAAQ,UAAU,IACpB,MAAM,OAAQ,MAAM,OAAO,IAC3B,MAAM,OAAQ,IAAI;AAAA,IAC1B,WAAW,KAAK,QAAQ;AAEtB,iBAAW,MACT,KAAK,OAAQ,UAAU,IACnB,KAAK,OAAQ,MAAM,OAAO,IAC1B,KAAK,OAAQ,IAAI;AAAA,IACzB,OAAO;AAEL,iBAAW,MAAM,cAAc,WAAW,IAAI;AAAA,IAChD;AAIA,UAAM,gBAAgB;AAAA,MACpB,GAAI,oBAAoB,cAAc,CAAC;AAAA,MACvC,GAAI,KAAK,cAAc,CAAC;AAAA,MACxB,GAAI,OAAO,UAAU,aAAa,MAAM,cAAc,CAAC,IAAI,MAAM,cAAc,CAAC;AAAA,IAClF,EAAE,QAAQ;AAGV,QAAI,cAAc,SAAS,GAAG;AAC5B,aAAO,gBAAgB,UAAU,eAAe,OAAO;AAAA,IACzD;AAEA,WAAO,SAAS;AAAA,EAClB;AACF;AAMA,SAAS,gBACP,UACA,YACA,SACW;AAEX,MAAI,UAA2B;AAG/B,aAAW,aAAa,YAAY;AAClC,UAAM,YAAY;AAClB,cAAU,MAAM,UAAU,WAAW,OAAO;AAAA,EAC9C;AAEA,SAAO,QAAQ;AACjB;;;AEhvBA,SAAS,iBAAiB,oBAAoB,4BAA4B;;;ACsD1E,SAAS,OAAO,eAA2C;AACzD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAmBA,SAAS,QACP,eACA,cACqB;AACrB,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAyBA,SAAS,UACP,eACA,cACkB;AAClB,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAkBA,SAAS,SAAS,eAA6C;AAC7D,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAgBA,SAAS,SAAS,QAAwC;AACxD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAiBA,SAAS,YAAY,OAAwC;AAC3D,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAWO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,mBACd,OAC8I;AAC9I,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,YAAY,QAAQ;AACvE,WAAO;AAAA,EACT;AACA,QAAM,YAAa,MAAkC;AACrD,SAAO,OAAO,cAAc,YAAY,UAAU,WAAW,QAAQ;AACvE;AASO,SAAS,oBACd,SACA,aACS;AACT,UAAQ,QAAQ,QAAQ;AAAA,IACtB,KAAK;AACH,aAAO,YAAY,QAAQ,aAAa,KAAK;AAAA,IAE/C,KAAK,iBAAiB;AACpB,YAAM,YAAY,YAAY,QAAQ,aAAa;AACnD,UAAI,QAAQ,cAAc;AACxB,eAAO,YAAY,QAAQ,aAAa,OAAO,QAAQ,aAAa;AAAA,MACtE;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,UAAU,YAAY,QAAQ,aAAa;AACjD,aAAO,QAAQ,aAAa,OAAO,KAAK;AAAA,IAC1C;AAAA,IAEA,KAAK;AAEH,aAAO,YAAY,QAAQ,aAAa;AAAA,IAE1C,KAAK;AAEH,aAAO,QAAQ,OAAO,IAAI,CAAC,UAAU,YAAY,KAAK,CAAC;AAAA,IAEzD,KAAK;AACH,aAAO,YAAY,QAAQ,KAAK,KAAK;AAAA,IAEvC;AACE,aAAO;AAAA,EACX;AACF;;;ACvOA,IAAM,eAA6D;AAAA,EACjE,EAAE,SAAS,eAAe,UAAU,aAAa;AAAA,EACjD,EAAE,SAAS,sBAAsB,UAAU,aAAa;AAAA,EACxD,EAAE,SAAS,gBAAgB,UAAU,UAAU;AAAA,EAC/C,EAAE,SAAS,kBAAkB,UAAU,UAAU;AAAA,EACjD,EAAE,SAAS,iBAAiB,UAAU,SAAS;AAAA,EAC/C,EAAE,SAAS,gBAAgB,UAAU,SAAS;AAAA,EAC9C,EAAE,SAAS,aAAa,UAAU,WAAW;AAAA,EAC7C,EAAE,SAAS,eAAe,UAAU,OAAO;AAAA,EAC3C,EAAE,SAAS,gBAAgB,UAAU,UAAU;AAAA,EAC/C,EAAE,SAAS,iBAAiB,UAAU,UAAU;AAAA,EAChD,EAAE,SAAS,gBAAgB,UAAU,QAAQ;AAAA,EAC7C,EAAE,SAAS,qBAAqB,UAAU,cAAc;AAAA,EACxD,EAAE,SAAS,oBAAoB,UAAU,YAAY;AAAA,EACrD,EAAE,SAAS,iBAAiB,UAAU,UAAU;AAAA,EAChD,EAAE,SAAS,+BAA+B,UAAU,mBAAmB;AAAA,EACvE,EAAE,SAAS,mBAAmB,UAAU,SAAS;AAAA,EACjD,EAAE,SAAS,iBAAiB,UAAU,SAAS;AAAA,EAC/C,EAAE,SAAS,eAAe,UAAU,OAAO;AAAA,EAC3C,EAAE,SAAS,kBAAkB,UAAU,UAAU;AAAA,EACjD,EAAE,SAAS,eAAe,UAAU,YAAY;AAClD;AAKA,SAAS,cAAc,MAAsB;AAC3C,aAAW,QAAQ,cAAc;AAC/B,QAAI,KAAK,QAAQ,KAAK,IAAI,GAAG;AAC3B,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,aAAa,OAAyB;AAC7C,MAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,QAAM,WAAW,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC5C,MAAI,SAAS;AACb,QAAM,QAAQ,SAAS,CAAC;AAExB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,KAAK,MAAM,CAAC;AAClB,QAAI,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG;AACtC,gBAAU;AAAA,IACZ,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAa,OAAO,YAAY,GAAG;AACzC,MAAI,aAAa,GAAG;AAClB,aAAS,OAAO,MAAM,GAAG,aAAa,CAAC;AAAA,EACzC;AAEA,SAAO,KAAK,MAAM;AACpB;AAQA,SAAS,kBAAkB,SAAyB;AAClD,QAAM,OAAO,QACV,KAAK,EACL,QAAQ,YAAY,EAAE,EACtB,QAAQ,aAAa,EAAE,EACvB,QAAQ,aAAa,EAAE,EACvB,KAAK,EACL,YAAY;AAGf,QAAM,WAAmC;AAAA,IACvC,sBAAsB;AAAA,IACtB,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,IACb,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,aAAa;AAAA,IACb,WAAW;AAAA,IACX,2BAA2B;AAAA,EAC7B;AAEA,SAAO,SAAS,IAAI,KAAK,KAAK,QAAQ,QAAQ,GAAG;AACnD;AASO,SAAS,eAAe,SAAiB,UAAoC;AAClF,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,SAAwB,CAAC;AAC/B,QAAM,YAAY,oBAAI,IAAY;AAClC,MAAI,kBAAkB;AACtB,MAAI,uBAAuB;AAI3B,QAAM,eAAe;AAGrB,QAAM,sBAAsB;AAE5B,aAAW,QAAQ,OAAO;AAExB,UAAM,eAAe,KAAK,MAAM,mBAAmB;AACnD,QAAI,cAAc;AAChB,YAAM,aAAa,kBAAkB,aAAa,CAAC,CAAC;AACpD,UAAI,YAAY;AACd,0BAAkB;AAClB,+BAAuB;AAAA,MACzB;AACA;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,MAAM,YAAY;AACxC,QAAI,UAAU;AACZ,YAAM,OAAO,SAAS,CAAC;AAKvB,UAAI,UAAU,IAAI,IAAI,EAAG;AACzB,gBAAU,IAAI,IAAI;AAGlB,YAAM,gBAAgB,KAAK,MAAM,cAAc;AAC/C,YAAM,cAAc,gBAAgB,cAAc,CAAC,EAAE,KAAK,IAAI;AAE9D,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU,uBAAuB,kBAAkB,cAAc,IAAI;AAAA,QACrE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,aAA4C,CAAC;AACnD,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,WAAW,MAAM,QAAQ,GAAG;AAC/B,iBAAW,MAAM,QAAQ,IAAI,CAAC;AAAA,IAChC;AACA,eAAW,MAAM,QAAQ,EAAE,KAAK,KAAK;AAAA,EACvC;AAGA,QAAM,SAAS,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,OAAO;AAAA,EAChB;AACF;;;AChNA,SAAS,4BAA4B;AAgDrC,IAAM,sBAAgD;AAAA,EACpD,OAAO,CAAC,UAAU;AAAA,EAClB,SAAS,CAAC,UAAU;AACtB;AAcO,SAAS,mBACd,UACA,gBACA,UACA,SACqB;AACrB,QAAM,WAAW,IAAI,IAAI,OAAO,KAAK,QAAQ,CAAC;AAG9C,QAAM,aAAuB,CAAC;AAC9B,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,gBAAgB;AACjC,QAAI,SAAS,IAAI,IAAI,GAAG;AACtB,iBAAW,KAAK,IAAI;AAAA,IACtB,OAAO;AACL,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,cAAc,IAAI,IAAI,UAAU;AACtC,QAAM,WAAiC,CAAC;AACxC,QAAM,cAAuC,CAAC;AAC9C,QAAM,aAAqC,CAAC;AAG5C,QAAM,eAAe,oBAAI,IAAY;AAErC,aAAW,QAAQ,YAAY;AAC7B,UAAM,UAAU,SAAS,IAAI;AAG7B,QAAI,QAAQ,WAAW;AACrB,iBAAW,OAAO,QAAQ,WAAW;AACnC,gBAAQ,IAAI,cAAc;AAAA,UACxB,KAAK;AACH,gBAAI,CAAC,YAAY,IAAI,IAAI,SAAS,GAAG;AACnC,uBAAS,KAAK;AAAA,gBACZ,MAAM;AAAA,gBACN,WAAW;AAAA,gBACX,SAAS,IAAI,IAAI,+BAA+B,IAAI,SAAS,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,gBAChG,kBAAkB,IAAI;AAAA,cACxB,CAAC;AAAA,YACH;AACA;AAAA,UAEF,KAAK;AACH,gBAAI,CAAC,YAAY,IAAI,IAAI,SAAS,KAAK,CAAC,aAAa,IAAI,IAAI,SAAS,GAAG;AACvE,0BAAY,KAAK;AAAA,gBACf,WAAW,IAAI;AAAA,gBACf,QAAQ,IAAI,IAAI,yBAAyB,IAAI,SAAS,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,gBACzF,cAAc;AAAA,gBACd,iBAAiB;AAAA,cACnB,CAAC;AACD,2BAAa,IAAI,IAAI,SAAS;AAAA,YAChC;AACA;AAAA,UAEF,KAAK;AACH,gBAAI,CAAC,YAAY,IAAI,IAAI,SAAS,GAAG;AACnC,uBAAS,KAAK;AAAA,gBACZ,MAAM;AAAA,gBACN,WAAW;AAAA,gBACX,SAAS,IAAI,IAAI,sCAAsC,IAAI,SAAS,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,gBACvG,kBAAkB,IAAI;AAAA,cACxB,CAAC;AAAA,YACH;AACA;AAAA,UAEF,KAAK;AACH,gBAAI,CAAC,YAAY,IAAI,IAAI,SAAS,KAAK,CAAC,aAAa,IAAI,IAAI,SAAS,GAAG;AACvE,0BAAY,KAAK;AAAA,gBACf,WAAW,IAAI;AAAA,gBACf,QAAQ,IAAI,IAAI,SAAS,sBAAsB,IAAI,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,gBACtF,cAAc;AAAA,gBACd,iBAAiB;AAAA,cACnB,CAAC;AACD,2BAAa,IAAI,IAAI,SAAS;AAAA,YAChC;AACA;AAAA,UAEF,KAAK;AACH,gBAAI,YAAY,IAAI,IAAI,SAAS,GAAG;AAClC,uBAAS,KAAK;AAAA,gBACZ,MAAM;AAAA,gBACN,WAAW;AAAA,gBACX,SAAS,IAAI,IAAI,UAAU,IAAI,SAAS,wDAAmD,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,gBAC1H,kBAAkB,IAAI;AAAA,cACxB,CAAC;AAAA,YACH;AACA;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,OAAO,SAAS;AAC1B,iBAAW,gBAAgB,QAAQ,MAAM,SAAS;AAChD,cAAM,QAAQ,aAAa,YAAY;AACvC,mBAAW,SAAS,YAAY;AAC9B,cAAI,UAAU,QAAQ,MAAM,SAAS,MAAM,YAAY,CAAC,GAAG;AACzD,uBAAW,KAAK;AAAA,cACd,WAAW;AAAA,cACX,WAAW,4BAA4B,KAAK,MAAM,YAAY;AAAA,YAChE,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK,WAAW,cAAc;AACxC,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS,QAAQ,KAAK,cAClB,IAAI,IAAI,oBAAoB,QAAQ,KAAK,WAAW,KACpD,IAAI,IAAI;AAAA,MACd,CAAC;AAAA,IACH,WAAW,QAAQ,KAAK,WAAW,gBAAgB;AACjD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS,IAAI,IAAI;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,qBAAqB,IAAI;AAAA,IAC7B,WAAW,IAAI,CAAC,SAAS,SAAS,IAAI,EAAE,KAAK,QAAQ;AAAA,EACvD;AAEA,aAAW,CAAC,UAAU,UAAU,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AACxE,QAAI,CAAC,mBAAmB,IAAI,QAAQ,EAAG;AAEvC,eAAW,kBAAkB,YAAY;AACvC,UAAI,mBAAmB,IAAI,cAAc,EAAG;AAG5C,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,WAAW;AACb,oBAAY,KAAK;AAAA,UACf,WAAW;AAAA,UACX,QAAQ,uBAAuB,QAAQ,sCAAsC,cAAc;AAAA,UAC3F,cAAc;AAAA,UACd,iBAAiB,WAAW;AAAA,YAC1B,CAAC,MAAM,SAAS,CAAC,EAAE,KAAK,aAAa;AAAA,UACvC;AAAA,QACF,CAAC;AACD,qBAAa,IAAI,SAAS;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,OAAO;AAClB,UAAM,SAAS,IAAI,qBAAqB,QAAQ,KAAK;AAGrD,eAAW,QAAQ,YAAY;AAC7B,YAAM,OAAO,OAAO,aAAa,MAAM,CAAC,WAAW,cAAc,CAAC;AAClE,iBAAW,OAAO,MAAM;AACtB,YACE,CAAC,YAAY,IAAI,IAAI,MAAM,KAC3B,CAAC,aAAa,IAAI,IAAI,MAAM,KAC5B,SAAS,IAAI,IAAI,MAAM,GACvB;AACA,sBAAY,KAAK;AAAA,YACf,WAAW,IAAI;AAAA,YACf,QAAQ,IAAI,IAAI,KAAK,IAAI,SAAS,iBAAiB,qBAAqB,SAAS,KAAK,IAAI,MAAM;AAAA,YAChG,cAAc;AAAA,YACd,iBAAiB;AAAA,UACnB,CAAC;AACD,uBAAa,IAAI,IAAI,MAAM;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAGA,eAAW,QAAQ,YAAY;AAC7B,YAAM,SAAS,OAAO,YAAY,IAAI;AACtC,iBAAW,aAAa,QAAQ;AAE9B,cAAM,aAAa,QAAQ,MAAM,MAC9B;AAAA,UACC,CAAC,MACC,EAAE,SAAS,cACX,EAAE,eAAe,SAAS,SAAS,OAClC,EAAE,WAAW,QAAQ,EAAE,WAAW;AAAA,QACvC,EACC,IAAI,CAAC,MAAO,EAAE,WAAW,OAAO,EAAE,SAAS,EAAE,MAAO;AAEvD,mBAAW,QAAQ,YAAY;AAC7B,cACE,CAAC,YAAY,IAAI,IAAI,KACrB,CAAC,aAAa,IAAI,IAAI,KACtB,SAAS,IAAI,IAAI,GACjB;AACA,wBAAY,KAAK;AAAA,cACf,WAAW;AAAA,cACX,QAAQ,IAAI,IAAI,UAAU,IAAI,+BAA+B,SAAS;AAAA,cACtE,cAAc;AAAA,cACd,iBAAiB;AAAA,YACnB,CAAC;AACD,yBAAa,IAAI,IAAI;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,SAAS,UAAU,aAAa,WAAW;AAClE;AAMA,SAAS,0BACP,UACA,UACA,aACA,cACe;AACf,MAAI,OAAsB;AAC1B,MAAI,YAAY;AAEhB,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACtD,QAAI,QAAQ,KAAK,aAAa,SAAU;AACxC,QAAI,YAAY,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,EAAG;AAErD,UAAM,SAAS,QAAQ,KAAK,UAAU;AACtC,QAAI,QAAQ;AACZ,QAAI,WAAW,SAAU,SAAQ;AAAA,aACxB,WAAW,OAAQ,SAAQ;AAAA,aAC3B,WAAW,eAAgB,SAAQ;AAG5C,QAAI,QAAQ,WAAW;AACrB,kBAAY;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/scan.ts"],"sourcesContent":["/**\n * fragments scan - Zero-config segments.json generation from source code\n *\n * Automatically extracts component documentation by:\n * 1. Discovering components from source files and barrel exports\n * 2. Extracting props from TypeScript interfaces\n * 3. Scanning codebase for usage patterns\n * 4. Parsing Storybook stories for examples\n * 5. Inferring component relationships from usage data\n * 6. Generating complete segments.json without manual documentation\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join, dirname, relative } from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n BRAND,\n type CompiledSegmentsFile,\n type CompiledSegment,\n type PropDefinition,\n} from \"../core/index.js\";\nimport {\n loadConfig,\n discoverAllComponents,\n type DiscoveredComponent,\n} from \"../core/node.js\";\nimport {\n scanCodebase,\n extractPropsFromFile,\n parseAllStories,\n inferAllRelations,\n generateComponentContext,\n generateEnhancementSuggestions,\n filterBoilerplate,\n convertToSegmentProps,\n type UsageAnalysis,\n type ComponentRelation,\n type PropsExtractionResult,\n type ParsedStoryFile,\n} from \"../service/index.js\";\n\nexport interface ScanOptions {\n /** Path to config file */\n config?: string;\n /** Output file path (default: segments.json) */\n output?: string;\n /** Component patterns to scan */\n componentPatterns?: string[];\n /** Barrel export files to parse */\n barrelFiles?: string[];\n /** Directory to scan for usage patterns */\n usageDir?: string;\n /** Skip usage analysis */\n skipUsage?: boolean;\n /** Skip Storybook parsing */\n skipStorybook?: boolean;\n /** Verbose output */\n verbose?: boolean;\n}\n\nexport interface ScanResult {\n success: boolean;\n outputPath: string;\n componentCount: number;\n propsExtracted: number;\n usagesFound: number;\n relationsInferred: number;\n storiesParsed: number;\n errors: Array<{ component: string; error: string }>;\n warnings: Array<{ component: string; warning: string }>;\n}\n\n/**\n * Scan codebase and generate segments.json directly from source\n */\nexport async function scan(options: ScanOptions = {}): Promise<ScanResult> {\n const startTime = Date.now();\n const errors: Array<{ component: string; error: string }> = [];\n const warnings: Array<{ component: string; warning: string }> = [];\n\n // Load config or use defaults\n let configDir: string;\n let outputFile: string;\n let componentPatterns: string[] | undefined;\n\n try {\n const loaded = await loadConfig(options.config);\n configDir = loaded.configDir;\n outputFile = options.output || loaded.config.outFile || \"segments.json\";\n componentPatterns = options.componentPatterns || loaded.config.components;\n } catch {\n // No config file, use defaults\n configDir = process.cwd();\n outputFile = options.output || \"segments.json\";\n componentPatterns = options.componentPatterns;\n }\n\n console.log(pc.cyan(`\\n${BRAND.name} Scan\\n`));\n console.log(pc.dim(\"Zero-config segments.json generation from source code\\n\"));\n\n // Phase 1: Discover components\n console.log(pc.dim(\"Phase 1: Discovering components...\"));\n const components = await discoverAllComponents(configDir, {\n patterns: componentPatterns,\n exclude: [\"**/*.test.*\", \"**/*.spec.*\", \"**/__tests__/**\"],\n barrelFiles: options.barrelFiles,\n });\n\n if (components.length === 0) {\n console.log(pc.yellow(\"No components found. Check your patterns or config.\"));\n return {\n success: false,\n outputPath: resolve(configDir, outputFile),\n componentCount: 0,\n propsExtracted: 0,\n usagesFound: 0,\n relationsInferred: 0,\n storiesParsed: 0,\n errors: [{ component: \"*\", error: \"No components found\" }],\n warnings: [],\n };\n }\n\n console.log(pc.green(` Found ${components.length} components`));\n if (options.verbose) {\n for (const comp of components.slice(0, 10)) {\n console.log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));\n }\n if (components.length > 10) {\n console.log(pc.dim(` ... and ${components.length - 10} more`));\n }\n }\n\n // Phase 2: Extract props from TypeScript\n console.log(pc.dim(\"\\nPhase 2: Extracting props from TypeScript...\"));\n const propsMap = new Map<string, ReturnType<typeof convertToSegmentProps>>();\n const propsResults = new Map<string, PropsExtractionResult>();\n let propsExtracted = 0;\n\n for (const comp of components) {\n try {\n const extraction = await extractPropsFromFile(comp.sourcePath, {\n propsTypeName: `${comp.name}Props`,\n });\n\n propsResults.set(comp.name, extraction);\n\n if (extraction.success && extraction.props.length > 0) {\n propsMap.set(comp.name, convertToSegmentProps(extraction.props));\n propsExtracted++;\n }\n } catch (e) {\n if (options.verbose) {\n warnings.push({\n component: comp.name,\n warning: `Props extraction failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n }\n\n console.log(pc.green(` Extracted props for ${propsExtracted} components`));\n\n // Phase 3: Scan for usage patterns\n let usageAnalysis: UsageAnalysis | undefined;\n let usagesFound = 0;\n let allRelations = new Map<string, ComponentRelation[]>();\n\n if (!options.skipUsage) {\n console.log(pc.dim(\"\\nPhase 3: Scanning for usage patterns...\"));\n const usageDir = options.usageDir || configDir;\n\n try {\n // Get component names for filtering\n const componentNames = components.map((c) => c.name);\n\n usageAnalysis = await scanCodebase({\n rootDir: usageDir,\n include: [\"**/*.tsx\", \"**/*.ts\", \"**/*.jsx\", \"**/*.js\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/*.stories.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n ],\n componentNames,\n useCache: true,\n });\n\n // Count total usages across all components\n usagesFound = Object.values(usageAnalysis.components).reduce(\n (sum, comp) => sum + comp.totalUsages,\n 0\n );\n\n // Infer relations\n allRelations = inferAllRelations(usageAnalysis);\n console.log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));\n console.log(pc.green(` Inferred relations for ${allRelations.size} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n console.log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n console.log(pc.dim(\"\\nPhase 3: Skipping usage analysis\"));\n }\n\n // Phase 4: Parse Storybook stories\n const storiesMap = new Map<string, ParsedStoryFile>();\n let storiesParsed = 0;\n\n if (!options.skipStorybook) {\n console.log(pc.dim(\"\\nPhase 4: Parsing Storybook stories...\"));\n\n try {\n const allStories = await parseAllStories(configDir);\n\n for (const [name, stories] of Object.entries(allStories)) {\n if (stories && stories.stories.length > 0) {\n storiesMap.set(name, stories);\n storiesParsed++;\n }\n }\n\n console.log(pc.green(` Parsed stories for ${storiesParsed} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n console.log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n console.log(pc.dim(\"\\nPhase 4: Skipping Storybook parsing\"));\n }\n\n // Phase 5: Generate segments\n console.log(pc.dim(\"\\nPhase 5: Generating segments...\"));\n const segments: Record<string, CompiledSegment> = {};\n\n for (const comp of components) {\n try {\n const segment = generateSegmentFromData(\n comp,\n configDir,\n propsMap.get(comp.name),\n usageAnalysis?.components[comp.name],\n allRelations.get(comp.name),\n storiesMap.get(comp.name)\n );\n\n segments[comp.name] = segment;\n } catch (e) {\n errors.push({\n component: comp.name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n // Write output\n const outputPath = resolve(configDir, outputFile);\n await mkdir(dirname(outputPath), { recursive: true });\n\n const output: CompiledSegmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n segments,\n };\n\n await writeFile(outputPath, JSON.stringify(output, null, 2));\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n // Summary\n console.log(pc.dim(\"\\n────────────────────────────────────────\"));\n console.log(pc.green(`\\n✓ Generated segments.json in ${elapsed}s`));\n console.log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));\n console.log(pc.dim(` Components: ${Object.keys(segments).length}`));\n console.log(pc.dim(` Props extracted: ${propsExtracted}`));\n console.log(pc.dim(` Usages found: ${usagesFound}`));\n console.log(pc.dim(` Relations inferred: ${allRelations.size}`));\n console.log(pc.dim(` Stories parsed: ${storiesParsed}`));\n\n if (warnings.length > 0) {\n console.log(pc.yellow(`\\n ${warnings.length} warning(s)`));\n if (options.verbose) {\n for (const w of warnings) {\n console.log(pc.dim(` ${w.component}: ${w.warning}`));\n }\n }\n }\n\n if (errors.length > 0) {\n console.log(pc.red(`\\n ${errors.length} error(s)`));\n for (const e of errors) {\n console.log(pc.dim(` ${e.component}: ${e.error}`));\n }\n }\n\n console.log();\n\n return {\n success: errors.length === 0,\n outputPath,\n componentCount: Object.keys(segments).length,\n propsExtracted,\n usagesFound,\n relationsInferred: allRelations.size,\n storiesParsed,\n errors,\n warnings,\n };\n}\n\n/**\n * Generate a CompiledSegment from extracted data\n */\nfunction generateSegmentFromData(\n comp: DiscoveredComponent,\n configDir: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n relations: ComponentRelation[] | undefined,\n storyFile: ParsedStoryFile | undefined\n): CompiledSegment {\n // Generate context for AI suggestions\n const context = generateComponentContext(\n comp.name,\n usageAnalysis,\n undefined, // No extracted docs yet\n storyFile,\n undefined, // No props extraction result (we have the converted props already)\n relations\n );\n\n // Generate enhancement suggestions from context\n const suggestions = generateEnhancementSuggestions(context);\n\n // Filter boilerplate from suggestions\n const when = filterBoilerplate(suggestions.suggestions.when);\n const whenNot = filterBoilerplate(suggestions.suggestions.whenNot);\n\n // Infer category from path\n const category = inferCategory(comp.relativePath);\n\n // Infer status from path\n const status = inferStatus(comp.relativePath);\n\n // Build variants from stories\n const variants: CompiledSegment[\"variants\"] = [];\n if (storyFile?.stories) {\n for (const story of storyFile.stories) {\n variants.push({\n name: story.name,\n description: story.description || `${story.displayName} variant`,\n code: story.code,\n });\n }\n }\n\n // Build relations\n const compiledRelations: CompiledSegment[\"relations\"] = [];\n if (relations && relations.length > 0) {\n for (const rel of relations.slice(0, 10)) {\n compiledRelations.push({\n component: rel.component,\n relationship: rel.relationship,\n note: `Appears together ${rel.frequency} times`,\n });\n }\n }\n\n // Generate description\n const description = generateDescription(comp.name, props, usageAnalysis);\n\n return {\n filePath: comp.relativePath,\n meta: {\n name: comp.name,\n description,\n category,\n status,\n },\n usage: {\n when: when.length > 0 ? when : [`Use ${comp.name} for its intended purpose`],\n whenNot: whenNot,\n },\n props: props || {},\n relations: compiledRelations.length > 0 ? compiledRelations : undefined,\n variants,\n _generated: {\n source: \"ai\",\n sourceFile: comp.relativePath,\n confidence: calculateConfidence(props, usageAnalysis, storyFile),\n timestamp: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Infer category from file path\n */\nfunction inferCategory(relativePath: string): string {\n const parts = relativePath.toLowerCase().split(\"/\");\n\n // Common category patterns\n const categoryPatterns: Record<string, string[]> = {\n \"Actions\": [\"button\", \"action\", \"cta\"],\n \"Forms\": [\"form\", \"input\", \"select\", \"checkbox\", \"radio\", \"textarea\", \"field\"],\n \"Layout\": [\"layout\", \"container\", \"grid\", \"flex\", \"stack\", \"box\", \"divider\", \"spacer\"],\n \"Navigation\": [\"nav\", \"menu\", \"breadcrumb\", \"tab\", \"link\", \"pagination\"],\n \"Feedback\": [\"alert\", \"toast\", \"notification\", \"message\", \"badge\", \"indicator\", \"progress\", \"spinner\", \"loading\"],\n \"Data Display\": [\"table\", \"list\", \"card\", \"avatar\", \"stat\", \"timeline\", \"tree\"],\n \"Overlays\": [\"modal\", \"dialog\", \"drawer\", \"popover\", \"tooltip\", \"dropdown\"],\n \"Typography\": [\"text\", \"heading\", \"title\", \"label\", \"paragraph\"],\n \"Media\": [\"image\", \"video\", \"icon\", \"avatar\"],\n };\n\n for (const [category, patterns] of Object.entries(categoryPatterns)) {\n for (const pattern of patterns) {\n if (parts.some((part) => part.includes(pattern))) {\n return category;\n }\n }\n }\n\n // Check path structure for category\n const componentIdx = parts.findIndex((p) => p === \"components\");\n if (componentIdx !== -1 && parts.length > componentIdx + 1) {\n const categoryPart = parts[componentIdx + 1];\n return categoryPart.charAt(0).toUpperCase() + categoryPart.slice(1);\n }\n\n return \"Components\";\n}\n\n/**\n * Infer status from file path\n */\nfunction inferStatus(\n relativePath: string\n): \"stable\" | \"beta\" | \"experimental\" | \"deprecated\" {\n const lowerPath = relativePath.toLowerCase();\n\n if (lowerPath.includes(\"/experimental/\") || lowerPath.includes(\"/labs/\")) {\n return \"experimental\";\n }\n if (lowerPath.includes(\"/beta/\")) {\n return \"beta\";\n }\n if (lowerPath.includes(\"/deprecated/\") || lowerPath.includes(\"/legacy/\")) {\n return \"deprecated\";\n }\n\n return \"stable\";\n}\n\n/**\n * Generate component description\n */\nfunction generateDescription(\n name: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined\n): string {\n // Convert name to readable form\n const words = name\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Check props for hints\n const hasOnClick = props && (\"onClick\" in props || \"onPress\" in props);\n const hasValue = props && (\"value\" in props || \"defaultValue\" in props);\n const hasChildren = props && \"children\" in props;\n const hasHref = props && \"href\" in props;\n\n // Check usage contexts\n const topContext = usageAnalysis?.contexts[0]?.type;\n\n if (hasHref) {\n return `Navigational ${words} for linking to other pages or resources`;\n }\n\n if (hasOnClick && !hasValue) {\n return `Interactive ${words} for triggering actions`;\n }\n\n if (hasValue) {\n return `Form ${words} for user input`;\n }\n\n if (topContext && topContext !== \"unknown\") {\n return `${words.charAt(0).toUpperCase() + words.slice(1)} commonly used in ${topContext} contexts`;\n }\n\n if (hasChildren) {\n return `Container ${words} for composing UI`;\n }\n\n return `${words.charAt(0).toUpperCase() + words.slice(1)} component`;\n}\n\n/**\n * Calculate confidence score based on available data\n */\nfunction calculateConfidence(\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n storyFile: ParsedStoryFile | undefined\n): number {\n let confidence = 0;\n\n // Props give +30 confidence\n if (props && Object.keys(props).length > 0) {\n confidence += 30;\n }\n\n // Usage data gives up to +40 confidence\n if (usageAnalysis) {\n if (usageAnalysis.totalUsages > 10) confidence += 40;\n else if (usageAnalysis.totalUsages > 5) confidence += 30;\n else if (usageAnalysis.totalUsages > 0) confidence += 20;\n }\n\n // Stories give +30 confidence\n if (storyFile && storyFile.stories.length > 0) {\n confidence += 30;\n }\n\n return Math.min(confidence, 100);\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/generate.ts"],"sourcesContent":["/**\n * fragments generate - AI-assisted fragment generation\n *\n * Analyzes component source code and generates fragment files with:\n * - Extracted props from TypeScript\n * - Inferred usage patterns from story names\n * - Generated description\n */\n\nimport { readFile, writeFile, mkdir, access } from \"node:fs/promises\";\nimport { resolve, join, basename, dirname, relative } from \"node:path\";\nimport pc from \"picocolors\";\nimport fg from \"fast-glob\";\nimport { BRAND, type Fragment } from \"../core/index.js\";\nimport { extractPropsFromFile } from \"../core/node.js\";\n\nexport interface GenerateOptions {\n /** Project root directory */\n projectRoot?: string;\n /** Specific component name to generate (optional) */\n component?: string;\n /** Overwrite existing fragment files */\n force?: boolean;\n /** Pattern for component files */\n componentPattern?: string;\n}\n\nexport interface GenerateResult {\n success: boolean;\n generated: Array<{ name: string; path: string }>;\n skipped: Array<{ name: string; reason: string }>;\n errors: Array<{ name: string; error: string }>;\n}\n\n/**\n * Generate fragment files from component source code\n */\nexport async function generate(options: GenerateOptions = {}): Promise<GenerateResult> {\n const projectRoot = resolve(options.projectRoot || process.cwd());\n const generated: Array<{ name: string; path: string }> = [];\n const skipped: Array<{ name: string; reason: string }> = [];\n const errors: Array<{ name: string; error: string }> = [];\n\n console.log(pc.cyan(`\\n${BRAND.name} Generate\\n`));\n\n // Ensure .fragments/components directory exists\n const fragmentsDir = join(projectRoot, BRAND.dataDir, BRAND.componentsDir);\n await mkdir(fragmentsDir, { recursive: true });\n\n // Find component files\n const componentPattern =\n options.componentPattern ||\n \"src/components/**/*.tsx\";\n\n const componentFiles = await fg(componentPattern, {\n cwd: projectRoot,\n ignore: [\n \"**/node_modules/**\",\n \"**/*.stories.*\",\n \"**/*.segment.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/*.d.ts\",\n \"**/index.tsx\", // Often just re-exports\n ],\n absolute: true,\n });\n\n // Find story files for pattern inference\n const storyFiles = await fg([\"src/**/*.stories.tsx\", \"src/**/*.stories.ts\"], {\n cwd: projectRoot,\n ignore: [\"**/node_modules/**\"],\n absolute: true,\n });\n\n // Build story map for pattern inference\n const storyMap = new Map<string, string[]>();\n for (const storyFile of storyFiles) {\n try {\n const content = await readFile(storyFile, \"utf-8\");\n const componentName = extractComponentNameFromStory(content, storyFile);\n if (componentName) {\n const storyNames = extractStoryNames(content);\n storyMap.set(componentName, storyNames);\n }\n } catch {\n // Ignore parsing errors\n }\n }\n\n console.log(pc.dim(`Found ${componentFiles.length} component files\\n`));\n\n // Process each component file\n for (const filePath of componentFiles) {\n try {\n const extracted = extractPropsFromFile(filePath);\n\n if (!extracted || !extracted.componentName) {\n continue;\n }\n\n const componentName = extracted.componentName;\n\n // Filter by component name if specified\n if (options.component && componentName !== options.component) {\n continue;\n }\n\n // Check if fragment already exists\n const fragmentPath = join(fragmentsDir, `${componentName}${BRAND.fileExtension}`);\n let fragmentExists = false;\n try {\n await access(fragmentPath);\n fragmentExists = true;\n } catch {\n // Fragment doesn't exist\n }\n\n if (fragmentExists && !options.force) {\n skipped.push({ name: componentName, reason: \"Fragment already exists\" });\n console.log(pc.dim(` Skipping ${componentName} (fragment exists)`));\n continue;\n }\n\n // Generate fragment from analysis\n const fragment = generateFragmentFromComponent(\n componentName,\n extracted,\n filePath,\n storyMap.get(componentName) || []\n );\n\n // Write fragment file\n await writeFile(fragmentPath, JSON.stringify(fragment, null, 2), \"utf-8\");\n generated.push({ name: componentName, path: relative(projectRoot, fragmentPath) });\n console.log(pc.green(` ✓ Generated ${componentName}${BRAND.fileExtension}`));\n } catch (e) {\n const fileName = basename(filePath);\n errors.push({\n name: fileName,\n error: e instanceof Error ? e.message : String(e),\n });\n console.log(pc.red(` ✗ Failed: ${fileName}`));\n }\n }\n\n // Summary\n console.log();\n if (generated.length > 0) {\n console.log(pc.green(`✓ Generated ${generated.length} fragment(s)`));\n }\n if (skipped.length > 0) {\n console.log(pc.dim(` Skipped ${skipped.length} (use --force to overwrite)`));\n }\n if (errors.length > 0) {\n console.log(pc.yellow(` ${errors.length} error(s)`));\n }\n console.log();\n\n return {\n success: errors.length === 0,\n generated,\n skipped,\n errors,\n };\n}\n\n/**\n * Generate a Fragment from extracted component data\n */\nfunction generateFragmentFromComponent(\n componentName: string,\n extracted: ReturnType<typeof extractPropsFromFile> & { componentName: string },\n filePath: string,\n storyNames: string[]\n): Fragment {\n // Infer usage from story names\n const whenToUse = inferUsageFromStories(storyNames);\n\n // Generate description from component name\n const description = generateDescription(componentName, extracted.props);\n\n // Infer accessibility from props\n const accessibility = inferAccessibility(extracted.props);\n\n // Infer status from file path\n const status = inferStatus(filePath);\n\n const fragment: Fragment = {\n $schema: \"https://fragments.dev/schema/v1.json\",\n name: componentName,\n description,\n usage: {\n when: whenToUse,\n doNot: [],\n },\n meta: {\n status,\n },\n };\n\n // Add accessibility if any was inferred\n if (accessibility.role || (accessibility.requirements && accessibility.requirements.length > 0)) {\n fragment.accessibility = accessibility;\n }\n\n return fragment;\n}\n\n/**\n * Extract component name from story file\n */\nfunction extractComponentNameFromStory(content: string, filePath: string): string | null {\n // Try to extract from title in default export\n // e.g., export default { title: 'Components/Button' }\n const titleMatch = content.match(/title:\\s*['\"](?:[^'\"]+\\/)?([^'\"]+)['\"]/);\n if (titleMatch) {\n return titleMatch[1];\n }\n\n // Try to extract from file name\n const fileName = basename(filePath);\n const componentName = fileName.replace(/\\.stories\\.(tsx?|jsx?)$/, \"\");\n if (/^[A-Z]/.test(componentName)) {\n return componentName;\n }\n\n return null;\n}\n\n/**\n * Extract story names from story file content\n */\nfunction extractStoryNames(content: string): string[] {\n const names: string[] = [];\n\n // Match named exports that look like stories\n // e.g., export const Primary = ...\n const exportMatches = content.matchAll(\n /export\\s+const\\s+([A-Z][a-zA-Z0-9]*)\\s*[=:]/g\n );\n\n for (const match of exportMatches) {\n const name = match[1];\n if (name !== \"default\" && !name.endsWith(\"Args\") && !name.endsWith(\"Meta\")) {\n names.push(name);\n }\n }\n\n return names;\n}\n\n/**\n * Infer usage scenarios from story names\n */\nfunction inferUsageFromStories(storyNames: string[]): string[] {\n const usage: string[] = [];\n\n for (const name of storyNames) {\n // Convert PascalCase to sentence\n const sentence = name\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Skip generic names\n if (\n [\"default\", \"primary\", \"basic\", \"example\", \"playground\"].includes(\n sentence.toLowerCase()\n )\n ) {\n continue;\n }\n\n // Generate usage from story name\n if (sentence.includes(\"loading\")) {\n usage.push(\"Showing loading states\");\n } else if (sentence.includes(\"disabled\")) {\n usage.push(\"Preventing user interaction\");\n } else if (sentence.includes(\"error\")) {\n usage.push(\"Displaying error states\");\n } else if (sentence.includes(\"success\")) {\n usage.push(\"Showing success feedback\");\n } else if (sentence.includes(\"empty\")) {\n usage.push(\"Handling empty states\");\n } else if (sentence.includes(\"with\")) {\n // \"WithIcon\" -> \"Adding icons\"\n const withPart = sentence.replace(\"with \", \"\");\n usage.push(`Displaying with ${withPart}`);\n }\n }\n\n return usage;\n}\n\n/**\n * Generate description from component name and props\n */\nfunction generateDescription(\n componentName: string,\n props: Record<string, unknown>\n): string {\n // Convert PascalCase to words\n const words = componentName\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Detect component type from name or props\n const hasOnClick = \"onClick\" in props || \"onPress\" in props;\n const hasValue = \"value\" in props || \"defaultValue\" in props;\n const hasChildren = \"children\" in props;\n\n if (hasOnClick && !hasValue) {\n return `Interactive ${words} element for triggering actions`;\n }\n\n if (hasValue) {\n return `Form ${words} for user input`;\n }\n\n if (hasChildren) {\n return `Container ${words} for grouping content`;\n }\n\n return `${words.charAt(0).toUpperCase() + words.slice(1)} component`;\n}\n\n/**\n * Infer accessibility from props\n */\nfunction inferAccessibility(props: Record<string, unknown>): {\n role?: string;\n requirements?: string[];\n} {\n const accessibility: { role?: string; requirements?: string[] } = {};\n\n const hasOnClick = \"onClick\" in props || \"onPress\" in props;\n const hasAriaLabel = \"ariaLabel\" in props || \"aria-label\" in props;\n const hasRole = \"role\" in props;\n const hasDisabled = \"disabled\" in props;\n const hasHref = \"href\" in props;\n\n // Infer role\n if (hasOnClick && !hasHref) {\n accessibility.role = \"button\";\n } else if (hasHref) {\n accessibility.role = \"link\";\n }\n\n // Infer requirements\n const requirements: string[] = [];\n\n if (hasOnClick && !hasAriaLabel) {\n requirements.push(\"Should have visible text or aria-label\");\n }\n\n if (hasDisabled) {\n requirements.push(\"Disabled state should be conveyed to assistive technology\");\n }\n\n if (requirements.length > 0) {\n accessibility.requirements = requirements;\n }\n\n return accessibility;\n}\n\n/**\n * Infer status from file path\n */\nfunction inferStatus(\n filePath: string\n): \"draft\" | \"experimental\" | \"beta\" | \"stable\" | \"deprecated\" {\n const lowerPath = filePath.toLowerCase();\n\n if (lowerPath.includes(\"/experimental/\") || lowerPath.includes(\"/labs/\")) {\n return \"experimental\";\n }\n if (lowerPath.includes(\"/beta/\")) {\n return \"beta\";\n }\n if (lowerPath.includes(\"/deprecated/\") || lowerPath.includes(\"/legacy/\")) {\n return \"deprecated\";\n }\n if (lowerPath.includes(\"/draft/\") || lowerPath.includes(\"/wip/\")) {\n return \"draft\";\n }\n\n return \"stable\";\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +0,0 @@
1
- import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
- import {
3
- scan
4
- } from "./chunk-XHUDJNN3.js";
5
- import "./chunk-NWQ4CJOQ.js";
6
- import "./chunk-CVXKXVOY.js";
7
- import "./chunk-TJ34N7C7.js";
8
- import "./chunk-6JBGU74P.js";
9
- export {
10
- scan
11
- };
12
- //# sourceMappingURL=scan-WY23TJCP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/test/index.ts","../src/test/discovery.ts","../src/test/runner.ts","../src/test/reporters/console.ts","../src/test/reporters/junit.ts","../src/test/reporters/json.ts","../src/test/watch.ts"],"sourcesContent":["/**\n * Main test command - orchestrates test discovery, execution, and reporting\n */\n\nimport { resolve, join } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport pc from 'picocolors';\nimport type { SegmentsConfig } from '../core/index.js';\nimport type {\n TestConfig,\n DiscoveryOptions,\n RunnerOptions,\n TestReporter,\n TestRunResult,\n} from './types.js';\nimport { discoverTests, getUniqueComponents, getUniqueTags } from './discovery.js';\nimport { runTests } from './runner.js';\nimport { createConsoleReporter } from './reporters/console.js';\nimport { createJUnitReporter } from './reporters/junit.js';\nimport { createJsonReporter } from './reporters/json.js';\nimport { startWatchMode } from './watch.js';\n\nexport interface TestCommandOptions {\n // Discovery options\n component?: string;\n tags?: string;\n grep?: string;\n exclude?: string;\n\n // Execution options\n parallel?: number;\n timeout?: number;\n retries?: number;\n bail?: boolean;\n browser?: 'chromium' | 'firefox' | 'webkit';\n headless?: boolean;\n\n // Feature flags\n a11y?: boolean;\n visual?: boolean;\n updateSnapshots?: boolean;\n watch?: boolean;\n\n // Output options\n reporters?: string;\n output?: string;\n\n // Server options\n serverUrl?: string;\n port?: number;\n\n // CI mode\n ci?: boolean;\n}\n\n/**\n * Default options\n */\nconst DEFAULT_OPTIONS = {\n parallel: 4,\n timeout: 30000,\n retries: 0,\n bail: false,\n browser: 'chromium' as const,\n headless: true,\n a11y: false,\n visual: false,\n updateSnapshots: false,\n watch: false,\n reporters: 'console',\n output: './test-results',\n port: 6006,\n ci: false,\n};\n\n/**\n * Run the test command\n */\nexport async function runTestCommand(\n config: SegmentsConfig,\n configDir: string,\n options: TestCommandOptions\n): Promise<number> {\n // Merge with defaults\n const opts = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n // Parse discovery options\n const discoveryOptions: DiscoveryOptions = {\n component: opts.component,\n tags: opts.tags ? opts.tags.split(',').map((t) => t.trim()) : undefined,\n grep: opts.grep,\n exclude: opts.exclude,\n };\n\n // Parse runner options\n const runnerOptions: RunnerOptions = {\n parallel: opts.parallel,\n timeout: opts.timeout,\n retries: opts.retries,\n bail: opts.bail,\n a11y: opts.a11y,\n visual: opts.visual,\n updateSnapshots: opts.updateSnapshots,\n outputDir: resolve(configDir, opts.output),\n browser: opts.browser,\n headless: opts.headless,\n serverUrl: opts.serverUrl,\n port: opts.port,\n };\n\n // In CI mode, adjust settings\n if (opts.ci) {\n runnerOptions.headless = true;\n }\n\n // Discover tests\n console.log(pc.cyan('\\nDiscovering tests...'));\n const testCases = await discoverTests(config, configDir, discoveryOptions);\n\n if (testCases.length === 0) {\n console.log(pc.yellow('No tests with play functions found'));\n\n // Show helpful info about what was searched\n const components = getUniqueComponents(testCases);\n const tags = getUniqueTags(testCases);\n\n if (discoveryOptions.component) {\n console.log(pc.dim(` Filtered by component: ${discoveryOptions.component}`));\n }\n if (discoveryOptions.tags?.length) {\n console.log(pc.dim(` Filtered by tags: ${discoveryOptions.tags.join(', ')}`));\n }\n if (discoveryOptions.grep) {\n console.log(pc.dim(` Filtered by pattern: ${discoveryOptions.grep}`));\n }\n\n console.log();\n console.log(pc.dim('Add play functions to your segment variants to enable testing.'));\n console.log();\n\n return opts.ci ? 0 : 0; // Not a failure if no tests\n }\n\n console.log(pc.dim(`Found ${testCases.length} test(s)`));\n\n // Create output directory\n await mkdir(runnerOptions.outputDir, { recursive: true });\n\n // Create reporters\n const reporters = createReporters(opts.reporters, runnerOptions.outputDir, opts.ci);\n\n // Watch mode\n if (opts.watch && !opts.ci) {\n await startWatchMode(config, configDir, runnerOptions, reporters);\n return 0;\n }\n\n // Run tests\n let result: TestRunResult;\n try {\n result = await runTests(testCases, runnerOptions, reporters);\n } catch (error) {\n console.error(pc.red('Error running tests:'), error);\n return 1;\n }\n\n // Return exit code based on results\n if (opts.ci && result.totalFailed > 0) {\n return 1;\n }\n\n return result.totalFailed > 0 ? 1 : 0;\n}\n\n/**\n * Create reporters based on configuration\n */\nfunction createReporters(\n reporterNames: string,\n outputDir: string,\n ci: boolean\n): TestReporter[] {\n const reporters: TestReporter[] = [];\n const names = reporterNames.split(',').map((n) => n.trim().toLowerCase());\n\n for (const name of names) {\n switch (name) {\n case 'console':\n reporters.push(\n createConsoleReporter({\n verbose: !ci,\n showTiming: true,\n })\n );\n break;\n\n case 'junit':\n reporters.push(\n createJUnitReporter({\n outputPath: join(outputDir, 'junit.xml'),\n suiteName: 'Segments Tests',\n })\n );\n break;\n\n case 'json':\n reporters.push(\n createJsonReporter({\n outputPath: join(outputDir, 'results.json'),\n pretty: true,\n includeSteps: true,\n includeStacks: !ci,\n })\n );\n break;\n\n default:\n console.warn(pc.yellow(`Unknown reporter: ${name}`));\n }\n }\n\n // Always include console reporter if not explicitly specified\n if (!names.includes('console') && reporters.length === 0) {\n reporters.push(createConsoleReporter({ verbose: !ci }));\n }\n\n return reporters;\n}\n\n/**\n * List available tests without running them\n */\nexport async function listTests(\n config: SegmentsConfig,\n configDir: string,\n options: Pick<TestCommandOptions, 'component' | 'tags' | 'grep' | 'exclude'>\n): Promise<void> {\n const discoveryOptions: DiscoveryOptions = {\n component: options.component,\n tags: options.tags ? options.tags.split(',').map((t) => t.trim()) : undefined,\n grep: options.grep,\n exclude: options.exclude,\n };\n\n const testCases = await discoverTests(config, configDir, discoveryOptions);\n\n console.log();\n console.log(pc.cyan(pc.bold('Available Tests')));\n console.log();\n\n if (testCases.length === 0) {\n console.log(pc.yellow('No tests with play functions found'));\n return;\n }\n\n // Group by component\n const byComponent = new Map<string, typeof testCases>();\n for (const test of testCases) {\n const existing = byComponent.get(test.component) || [];\n existing.push(test);\n byComponent.set(test.component, existing);\n }\n\n for (const [component, tests] of byComponent) {\n console.log(pc.bold(component));\n for (const test of tests) {\n const tags = test.tags.length > 0 ? pc.dim(` [${test.tags.join(', ')}]`) : '';\n console.log(` ${pc.green('›')} ${test.variant}${tags}`);\n }\n console.log();\n }\n\n console.log(pc.dim(`Total: ${testCases.length} test(s) in ${byComponent.size} component(s)`));\n console.log();\n}\n\n// Re-export types\nexport type { TestCase, TestResult, TestRunResult, TestSuite, TestReporter } from './types.js';\n","/**\n * Test discovery - finds variants with play functions\n */\n\nimport { readFile } from 'node:fs/promises';\nimport type { SegmentsConfig } from '../core/index.js';\nimport { discoverSegmentFiles, parseSegmentFile } from '../core/node.js';\nimport type { TestCase, DiscoveryOptions } from './types.js';\n\n/**\n * Discovered segment with play function metadata\n */\ninterface DiscoveredVariant {\n component: string;\n variant: string;\n tags: string[];\n hasPlayFunction: boolean;\n storyId?: string;\n sourceFile: string;\n}\n\n/**\n * Discover all variants with play functions\n */\nexport async function discoverTests(\n config: SegmentsConfig,\n configDir: string,\n options: DiscoveryOptions = {}\n): Promise<TestCase[]> {\n const files = await discoverSegmentFiles(config, configDir);\n const variants: DiscoveredVariant[] = [];\n\n for (const file of files) {\n try {\n const content = await readFile(file.absolutePath, 'utf-8');\n const parsed = parseSegmentFile(content, file.relativePath);\n\n if (!parsed.meta.name) continue;\n\n // Filter by component name if specified\n if (options.component) {\n const componentMatch = parsed.meta.name.toLowerCase().includes(options.component.toLowerCase());\n if (!componentMatch) continue;\n }\n\n // Extract tags from meta for the component\n const componentTags = parsed.meta.tags || [];\n\n for (const variant of parsed.variants) {\n // Check if variant has play function by scanning source code\n const hasPlay = hasPlayFunctionInSource(content, variant.name);\n\n if (!hasPlay) continue;\n\n // Filter by tags if specified (use component-level tags since variant tags aren't in parsed data)\n if (options.tags && options.tags.length > 0) {\n const hasMatchingTag = options.tags.some((tag: string) =>\n componentTags.some((ct: string) => ct.toLowerCase().includes(tag.toLowerCase()))\n );\n if (!hasMatchingTag) continue;\n }\n\n // Filter by grep pattern if specified\n if (options.grep) {\n const pattern = new RegExp(options.grep, 'i');\n const matchesName = pattern.test(variant.name);\n const matchesComponent = pattern.test(parsed.meta.name);\n if (!matchesName && !matchesComponent) continue;\n }\n\n // Exclude pattern\n if (options.exclude) {\n const pattern = new RegExp(options.exclude, 'i');\n const excludeName = pattern.test(variant.name);\n const excludeComponent = pattern.test(parsed.meta.name);\n if (excludeName || excludeComponent) continue;\n }\n\n variants.push({\n component: parsed.meta.name,\n variant: variant.name,\n tags: componentTags,\n hasPlayFunction: true,\n storyId: undefined, // Not available from static parsing\n sourceFile: file.relativePath,\n });\n }\n } catch {\n // Skip files that can't be parsed\n continue;\n }\n }\n\n // Convert to test cases\n return variants.map((v) => ({\n id: `${v.component}--${v.variant}`.replace(/\\s+/g, '-').toLowerCase(),\n component: v.component,\n variant: v.variant,\n tags: v.tags,\n play: null as unknown as TestCase['play'], // Play function loaded at runtime in browser\n sourceFile: v.sourceFile,\n storyId: v.storyId,\n }));\n}\n\n/**\n * Check if a variant has a play function by scanning the source code\n */\nfunction hasPlayFunctionInSource(content: string, variantName: string): boolean {\n // Look for play function patterns in the source\n // Pattern 1: play: async ({ ... }) => { ... }\n // Pattern 2: play: async function ({ ... }) { ... }\n // Pattern 3: play: playFunction (reference)\n\n // Normalize variant name for matching (handle Default, Primary, etc.)\n const patterns = [\n // Export const VariantName = { ... play: ... }\n new RegExp(`export\\\\s+const\\\\s+${escapeRegExp(variantName)}\\\\s*=\\\\s*\\\\{[^}]*\\\\bplay\\\\s*:`, 's'),\n // variants: [{ name: 'VariantName', ... play: ... }]\n new RegExp(`name\\\\s*:\\\\s*['\"\\`]${escapeRegExp(variantName)}['\"\\`][^}]*\\\\bplay\\\\s*:`, 's'),\n // In case the variant has play in its definition object\n new RegExp(`['\"\\`]${escapeRegExp(variantName)}['\"\\`]\\\\s*:\\\\s*\\\\{[^}]*\\\\bplay\\\\s*:`, 's'),\n ];\n\n return patterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Escape special regex characters\n */\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Group test cases by component\n */\nexport function groupTestsByComponent(testCases: TestCase[]): Map<string, TestCase[]> {\n const groups = new Map<string, TestCase[]>();\n\n for (const test of testCases) {\n const existing = groups.get(test.component) || [];\n existing.push(test);\n groups.set(test.component, existing);\n }\n\n return groups;\n}\n\n/**\n * Get unique tags from all test cases\n */\nexport function getUniqueTags(testCases: TestCase[]): string[] {\n const tags = new Set<string>();\n for (const test of testCases) {\n for (const tag of test.tags) {\n tags.add(tag);\n }\n }\n return Array.from(tags).sort();\n}\n\n/**\n * Get unique components from all test cases\n */\nexport function getUniqueComponents(testCases: TestCase[]): string[] {\n const components = new Set<string>();\n for (const test of testCases) {\n components.add(test.component);\n }\n return Array.from(components).sort();\n}\n","/**\n * Test runner - executes play functions in browser via Playwright\n *\n * Playwright is an optional dependency. If not installed, the test command\n * will prompt the user to install it.\n */\n\nimport type {\n TestCase,\n TestResult,\n TestSuite,\n TestRunResult,\n TestError,\n StepResult,\n A11yResult,\n A11yViolation,\n RunnerOptions,\n TestReporter,\n} from './types.js';\nimport { groupTestsByComponent } from './discovery.js';\n\n// Dynamic playwright types (since it's optional)\n \ntype Browser = any;\n \ntype BrowserContext = any;\n \ntype Page = any;\n\n/**\n * Browser pool for parallel test execution\n */\ninterface BrowserPool {\n browser: Browser;\n contexts: BrowserContextEntry[];\n}\n\ninterface BrowserContextEntry {\n id: number;\n context: BrowserContext;\n page: Page;\n busy: boolean;\n}\n\n/**\n * Run tests with the given configuration\n */\nexport async function runTests(\n testCases: TestCase[],\n options: RunnerOptions,\n reporters: TestReporter[] = []\n): Promise<TestRunResult> {\n const startTime = new Date();\n const results: TestResult[] = [];\n\n // Notify reporters of run start\n for (const reporter of reporters) {\n reporter.onRunStart?.(testCases.length);\n }\n\n // Import Playwright dynamically (optional dependency)\n \n let playwright: any;\n try {\n playwright = await import('playwright');\n } catch {\n throw new Error(\n 'Playwright is required for running tests. Install it with: npm install -D playwright'\n );\n }\n\n // Launch browser\n const browserType = playwright[options.browser];\n const browser = await browserType.launch({\n headless: options.headless,\n });\n\n // Create browser pool for parallel execution\n const pool = await createBrowserPool(browser, options.parallel);\n\n try {\n // Determine server URL\n const serverUrl = options.serverUrl || `http://localhost:${options.port}`;\n\n // Run tests with parallelism\n if (options.parallel > 1) {\n await runTestsParallel(\n testCases,\n pool,\n serverUrl,\n options,\n reporters,\n results\n );\n } else {\n await runTestsSequential(\n testCases,\n pool.contexts[0],\n serverUrl,\n options,\n reporters,\n results\n );\n }\n } finally {\n // Cleanup browser pool\n await cleanupBrowserPool(pool);\n }\n\n const endTime = new Date();\n\n // Aggregate results into suites\n const suites = aggregateResults(results);\n\n const runResult: TestRunResult = {\n suites,\n totalTests: results.length,\n totalPassed: results.filter((r) => r.status === 'passed').length,\n totalFailed: results.filter((r) => r.status === 'failed').length,\n totalSkipped: results.filter((r) => r.status === 'skipped').length,\n totalDuration: endTime.getTime() - startTime.getTime(),\n startTime,\n endTime,\n totalA11yViolations: options.a11y\n ? results.reduce((sum, r) => sum + (r.accessibility?.violations.length || 0), 0)\n : undefined,\n };\n\n // Notify reporters of run completion\n for (const reporter of reporters) {\n await reporter.onRunComplete(runResult);\n }\n\n return runResult;\n}\n\n/**\n * Create a browser pool for parallel execution\n */\nasync function createBrowserPool(\n browser: Browser,\n parallelism: number\n): Promise<BrowserPool> {\n const contexts: BrowserContextEntry[] = [];\n\n for (let i = 0; i < parallelism; i++) {\n const context = await browser.newContext({\n viewport: { width: 1280, height: 720 },\n });\n const page = await context.newPage();\n contexts.push({ id: i, context, page, busy: false });\n }\n\n return { browser, contexts };\n}\n\n/**\n * Cleanup browser pool\n */\nasync function cleanupBrowserPool(pool: BrowserPool): Promise<void> {\n for (const entry of pool.contexts) {\n await entry.page.close();\n await entry.context.close();\n }\n await pool.browser.close();\n}\n\n/**\n * Run tests sequentially\n */\nasync function runTestsSequential(\n testCases: TestCase[],\n ctx: BrowserContextEntry,\n serverUrl: string,\n options: RunnerOptions,\n reporters: TestReporter[],\n results: TestResult[]\n): Promise<void> {\n for (const testCase of testCases) {\n // Notify reporters of test start\n for (const reporter of reporters) {\n reporter.onTestStart?.(testCase);\n }\n\n const result = await runSingleTest(testCase, ctx, serverUrl, options);\n results.push(result);\n\n // Notify reporters of test completion\n for (const reporter of reporters) {\n reporter.onTestComplete?.(result);\n }\n\n // Bail on first failure if configured\n if (options.bail && result.status === 'failed') {\n break;\n }\n }\n}\n\n/**\n * Run tests in parallel\n */\nasync function runTestsParallel(\n testCases: TestCase[],\n pool: BrowserPool,\n serverUrl: string,\n options: RunnerOptions,\n reporters: TestReporter[],\n results: TestResult[]\n): Promise<void> {\n const queue = [...testCases];\n const inFlight: Promise<void>[] = [];\n let bailTriggered = false;\n\n const acquireContext = (): BrowserContextEntry | null => {\n const available = pool.contexts.find((c) => !c.busy);\n if (available) {\n available.busy = true;\n return available;\n }\n return null;\n };\n\n const releaseContext = (ctx: BrowserContextEntry): void => {\n ctx.busy = false;\n };\n\n const runNext = async (): Promise<void> => {\n if (bailTriggered || queue.length === 0) return;\n\n const ctx = acquireContext();\n if (!ctx) return;\n\n const testCase = queue.shift()!;\n\n // Notify reporters of test start\n for (const reporter of reporters) {\n reporter.onTestStart?.(testCase);\n }\n\n try {\n const result = await runSingleTest(testCase, ctx, serverUrl, options);\n results.push(result);\n\n // Notify reporters of test completion\n for (const reporter of reporters) {\n reporter.onTestComplete?.(result);\n }\n\n // Check bail condition\n if (options.bail && result.status === 'failed') {\n bailTriggered = true;\n }\n } finally {\n releaseContext(ctx);\n // Start next test if not bailing\n if (!bailTriggered && queue.length > 0) {\n const nextPromise = runNext();\n inFlight.push(nextPromise);\n }\n }\n };\n\n // Start initial batch\n const initialBatch = Math.min(pool.contexts.length, queue.length);\n for (let i = 0; i < initialBatch; i++) {\n inFlight.push(runNext());\n }\n\n // Wait for all to complete\n await Promise.all(inFlight);\n}\n\n/**\n * Run a single test case\n */\nasync function runSingleTest(\n testCase: TestCase,\n ctx: BrowserContextEntry,\n serverUrl: string,\n options: RunnerOptions\n): Promise<TestResult> {\n const { page } = ctx;\n const startTime = performance.now();\n const steps: StepResult[] = [];\n let error: TestError | undefined;\n let status: TestResult['status'] = 'passed';\n let retryAttempt = 0;\n\n // Retry logic\n const maxAttempts = options.retries + 1;\n\n while (retryAttempt < maxAttempts) {\n try {\n // Navigate to the variant\n const url = buildVariantUrl(serverUrl, testCase);\n await page.goto(url, { waitUntil: 'networkidle' });\n\n // Wait for preview container\n await page.waitForSelector('[data-preview-container=\"true\"]', {\n timeout: options.timeout,\n });\n\n // Execute play function in browser context\n const playResult = await executePlayFunction(page, testCase, options.timeout);\n\n if (playResult.error) {\n error = playResult.error;\n status = 'failed';\n steps.push(...playResult.steps);\n\n // Retry if not last attempt\n if (retryAttempt < maxAttempts - 1) {\n retryAttempt++;\n continue;\n }\n } else {\n status = 'passed';\n steps.push(...playResult.steps);\n }\n\n break; // Success, no retry needed\n } catch (e) {\n error = {\n message: e instanceof Error ? e.message : String(e),\n stack: e instanceof Error ? e.stack : undefined,\n };\n status = 'failed';\n\n if (retryAttempt < maxAttempts - 1) {\n retryAttempt++;\n continue;\n }\n break;\n }\n }\n\n const duration = performance.now() - startTime;\n\n // Run accessibility checks if enabled\n let accessibility: A11yResult | undefined;\n if (options.a11y && status === 'passed') {\n accessibility = await runA11yChecks(page);\n }\n\n // Capture screenshot for visual regression if enabled\n let screenshotPath: string | undefined;\n if (options.visual) {\n screenshotPath = await captureScreenshot(page, testCase, options.outputDir);\n }\n\n return {\n testCase,\n status,\n duration,\n steps,\n error,\n accessibility,\n screenshotPath,\n retryAttempt: retryAttempt > 0 ? retryAttempt : undefined,\n };\n}\n\n/**\n * Build URL for a variant\n */\nfunction buildVariantUrl(serverUrl: string, testCase: TestCase): string {\n const params = new URLSearchParams({\n component: testCase.component,\n variant: testCase.variant,\n isolated: 'true',\n });\n return `${serverUrl}?${params.toString()}`;\n}\n\n/**\n * Execute play function in browser context\n */\nasync function executePlayFunction(\n page: Page,\n testCase: TestCase,\n timeout: number\n): Promise<{ steps: StepResult[]; error?: TestError }> {\n const result = await page.evaluate(\n async ({ component, variant, timeout }: { component: string; variant: string; timeout: number }) => {\n // Find the segment definition in the global registry\n const registry = (window as unknown as { __SEGMENTS_REGISTRY__?: Map<string, unknown> })\n .__SEGMENTS_REGISTRY__;\n\n if (!registry) {\n return {\n steps: [],\n error: { message: 'Segments registry not found. Make sure the viewer is loaded.' },\n };\n }\n\n const segment = registry.get(component) as {\n variants?: Array<{\n name: string;\n play?: (ctx: {\n canvasElement: HTMLElement;\n args: Record<string, unknown>;\n step: (name: string, fn: () => Promise<void>) => Promise<void>;\n }) => Promise<void>;\n }>;\n } | undefined;\n\n if (!segment) {\n return {\n steps: [],\n error: { message: `Component \"${component}\" not found in registry` },\n };\n }\n\n const variantDef = segment.variants?.find((v) => v.name === variant);\n if (!variantDef || !variantDef.play) {\n return {\n steps: [],\n error: { message: `Variant \"${variant}\" not found or has no play function` },\n };\n }\n\n // Find the preview container\n const canvasElement = document.querySelector('[data-preview-container=\"true\"]') as HTMLElement;\n if (!canvasElement) {\n return {\n steps: [],\n error: { message: 'Preview container not found' },\n };\n }\n\n // Track steps\n const steps: Array<{\n name: string;\n status: 'passed' | 'failed';\n duration: number;\n error?: { message: string };\n }> = [];\n\n const step = async (name: string, fn: () => Promise<void>): Promise<void> => {\n const stepStart = performance.now();\n try {\n await fn();\n steps.push({\n name,\n status: 'passed',\n duration: performance.now() - stepStart,\n });\n } catch (e) {\n steps.push({\n name,\n status: 'failed',\n duration: performance.now() - stepStart,\n error: { message: e instanceof Error ? e.message : String(e) },\n });\n throw e;\n }\n };\n\n // Execute with timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Test timed out after ${timeout}ms`)), timeout);\n });\n\n try {\n await Promise.race([\n variantDef.play({\n canvasElement,\n args: {},\n step,\n }),\n timeoutPromise,\n ]);\n\n // If no explicit steps, add one for the whole play function\n if (steps.length === 0) {\n steps.push({\n name: 'Play function',\n status: 'passed',\n duration: 0,\n });\n }\n\n return { steps, error: undefined };\n } catch (e) {\n // If no steps failed explicitly, add one\n if (!steps.some((s) => s.status === 'failed')) {\n steps.push({\n name: 'Play function',\n status: 'failed',\n duration: 0,\n error: { message: e instanceof Error ? e.message : String(e) },\n });\n }\n\n return {\n steps,\n error: { message: e instanceof Error ? e.message : String(e) },\n };\n }\n },\n { component: testCase.component, variant: testCase.variant, timeout }\n );\n\n return result as { steps: StepResult[]; error?: TestError };\n}\n\n/**\n * Run accessibility checks using axe-core\n */\nasync function runA11yChecks(page: Page): Promise<A11yResult> {\n try {\n // Inject axe-core if not already present\n await page.evaluate(() => {\n if ((window as unknown as { axe?: unknown }).axe) return;\n\n return new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.2/axe.min.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load axe-core'));\n document.head.appendChild(script);\n });\n });\n\n // Run axe-core analysis\n const results = await page.evaluate(async () => {\n const axe = (window as unknown as { axe: { run: (el: HTMLElement) => Promise<{ violations: unknown[]; passes: unknown[] }> } }).axe;\n const container = document.querySelector('[data-preview-container=\"true\"]') as HTMLElement;\n if (!container) {\n return { violations: [], passes: 0 };\n }\n const axeResults = await axe.run(container);\n return {\n violations: axeResults.violations,\n passes: axeResults.passes.length,\n };\n });\n\n return {\n violations: results.violations as A11yViolation[],\n passes: results.passes,\n };\n } catch {\n return { violations: [], passes: 0 };\n }\n}\n\n/**\n * Capture screenshot for visual regression\n */\nasync function captureScreenshot(\n page: Page,\n testCase: TestCase,\n outputDir: string\n): Promise<string> {\n const { mkdir, writeFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n\n const screenshotsDir = join(outputDir, 'screenshots');\n await mkdir(screenshotsDir, { recursive: true });\n\n const filename = `${testCase.component}--${testCase.variant}.png`\n .replace(/\\s+/g, '-')\n .toLowerCase();\n const filepath = join(screenshotsDir, filename);\n\n const container = await page.$('[data-preview-container=\"true\"]');\n if (container) {\n const screenshot = await container.screenshot();\n await writeFile(filepath, screenshot);\n }\n\n return filepath;\n}\n\n/**\n * Aggregate test results into suites by component\n */\nfunction aggregateResults(results: TestResult[]): TestSuite[] {\n const grouped = groupTestsByComponent(results.map((r) => r.testCase));\n const suites: TestSuite[] = [];\n\n for (const [componentName, testCases] of grouped) {\n const componentResults = results.filter((r) => r.testCase.component === componentName);\n\n suites.push({\n name: componentName,\n tests: componentResults,\n duration: componentResults.reduce((sum, r) => sum + r.duration, 0),\n passed: componentResults.filter((r) => r.status === 'passed').length,\n failed: componentResults.filter((r) => r.status === 'failed').length,\n skipped: componentResults.filter((r) => r.status === 'skipped').length,\n });\n }\n\n return suites;\n}\n","/**\n * Console reporter - pretty terminal output\n */\n\nimport pc from 'picocolors';\nimport type { TestCase, TestResult, TestRunResult, TestReporter } from '../types.js';\n\nexport interface ConsoleReporterOptions {\n /** Show verbose output including all steps */\n verbose?: boolean;\n /** Show timing for each test */\n showTiming?: boolean;\n}\n\n/**\n * Create a console reporter\n */\nexport function createConsoleReporter(options: ConsoleReporterOptions = {}): TestReporter {\n const { verbose = false, showTiming = true } = options;\n\n let startTime: number;\n let testCount: number;\n let currentIndex: number;\n\n return {\n onRunStart(count: number) {\n testCount = count;\n currentIndex = 0;\n startTime = Date.now();\n\n console.log();\n console.log(pc.cyan(pc.bold('Segments Test Runner')));\n console.log(pc.dim(`Running ${count} test${count === 1 ? '' : 's'}...`));\n console.log();\n },\n\n onTestStart(testCase: TestCase) {\n currentIndex++;\n if (verbose) {\n const progress = pc.dim(`[${currentIndex}/${testCount}]`);\n console.log(`${progress} ${pc.dim('Running')} ${testCase.component} › ${testCase.variant}`);\n }\n },\n\n onTestComplete(result: TestResult) {\n const { testCase, status, duration, steps, error, accessibility } = result;\n const timing = showTiming ? pc.dim(` (${formatDuration(duration)})`) : '';\n\n const statusIcon = getStatusIcon(status);\n const testName = `${testCase.component} › ${testCase.variant}`;\n\n if (status === 'passed') {\n console.log(` ${statusIcon} ${testName}${timing}`);\n\n // Show a11y results if present\n if (accessibility && accessibility.violations.length > 0) {\n console.log(\n pc.yellow(` ⚠ ${accessibility.violations.length} accessibility violation(s)`)\n );\n }\n } else if (status === 'failed') {\n console.log(` ${statusIcon} ${pc.red(testName)}${timing}`);\n\n // Show error message\n if (error) {\n console.log(pc.red(` ${error.message}`));\n if (verbose && error.stack) {\n console.log(pc.dim(` ${error.stack.split('\\n').slice(1, 4).join('\\n ')}`));\n }\n }\n\n // Show failed steps\n if (verbose || steps.some((s) => s.status === 'failed')) {\n for (const step of steps) {\n if (step.status === 'failed') {\n console.log(pc.red(` ✗ ${step.name}`));\n if (step.error) {\n console.log(pc.red(` ${step.error.message}`));\n }\n } else if (verbose && step.status === 'passed') {\n console.log(pc.dim(` ✓ ${step.name}`));\n }\n }\n }\n\n // Show retry info\n if (result.retryAttempt) {\n console.log(pc.dim(` (failed after ${result.retryAttempt + 1} attempts)`));\n }\n } else if (status === 'skipped') {\n console.log(` ${statusIcon} ${pc.dim(testName)} ${pc.dim('(skipped)')}`);\n }\n\n // Show all steps in verbose mode\n if (verbose && status === 'passed' && steps.length > 0) {\n for (const step of steps) {\n const stepTiming = showTiming ? pc.dim(` ${formatDuration(step.duration)}`) : '';\n console.log(pc.dim(` ✓ ${step.name}${stepTiming}`));\n }\n }\n },\n\n onRunComplete(result: TestRunResult) {\n const { totalTests, totalPassed, totalFailed, totalSkipped, totalDuration, suites } = result;\n\n console.log();\n console.log(pc.dim('─'.repeat(50)));\n console.log();\n\n // Summary by suite\n if (suites.length > 1) {\n console.log(pc.bold('Test Suites:'));\n for (const suite of suites) {\n const statusIcon = suite.failed > 0 ? pc.red('✗') : pc.green('✓');\n const failedText = suite.failed > 0 ? pc.red(`${suite.failed} failed, `) : '';\n const passedText = suite.passed > 0 ? pc.green(`${suite.passed} passed`) : '';\n const skippedText = suite.skipped > 0 ? pc.dim(`, ${suite.skipped} skipped`) : '';\n console.log(` ${statusIcon} ${suite.name} (${failedText}${passedText}${skippedText})`);\n }\n console.log();\n }\n\n // Overall summary\n console.log(pc.bold('Tests:'));\n const parts: string[] = [];\n\n if (totalFailed > 0) {\n parts.push(pc.red(`${totalFailed} failed`));\n }\n if (totalPassed > 0) {\n parts.push(pc.green(`${totalPassed} passed`));\n }\n if (totalSkipped > 0) {\n parts.push(pc.dim(`${totalSkipped} skipped`));\n }\n parts.push(`${totalTests} total`);\n\n console.log(` ${parts.join(', ')}`);\n console.log(` ${pc.dim('Time:')} ${formatDuration(totalDuration)}`);\n\n // A11y summary if applicable\n if (result.totalA11yViolations !== undefined) {\n if (result.totalA11yViolations > 0) {\n console.log(\n ` ${pc.yellow('Accessibility:')} ${result.totalA11yViolations} violation(s)`\n );\n } else {\n console.log(` ${pc.green('Accessibility:')} All checks passed`);\n }\n }\n\n console.log();\n\n // Final status\n if (totalFailed > 0) {\n console.log(pc.red(pc.bold('Test run failed')));\n } else {\n console.log(pc.green(pc.bold('Test run passed')));\n }\n console.log();\n },\n };\n}\n\n/**\n * Get status icon with color\n */\nfunction getStatusIcon(status: TestResult['status']): string {\n switch (status) {\n case 'passed':\n return pc.green('✓');\n case 'failed':\n return pc.red('✗');\n case 'skipped':\n return pc.dim('○');\n default:\n return ' ';\n }\n}\n\n/**\n * Format duration in human-readable form\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n","/**\n * JUnit XML reporter - CI/CD integration\n *\n * Generates JUnit XML format compatible with:\n * - GitHub Actions (mikepenz/action-junit-report)\n * - Jenkins\n * - GitLab CI\n * - CircleCI\n * - Azure DevOps\n */\n\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport type { TestRunResult, TestReporter, TestResult, TestSuite } from '../types.js';\n\nexport interface JUnitReporterOptions {\n /** Output file path */\n outputPath: string;\n /** Suite name for the root element */\n suiteName?: string;\n /** Include properties in the XML */\n includeProperties?: boolean;\n}\n\n/**\n * Create a JUnit XML reporter\n */\nexport function createJUnitReporter(options: JUnitReporterOptions): TestReporter {\n const { outputPath, suiteName = 'Segments Tests', includeProperties = true } = options;\n\n return {\n async onRunComplete(result: TestRunResult) {\n const xml = generateJUnitXml(result, suiteName, includeProperties);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n // Write the XML file\n await writeFile(outputPath, xml, 'utf-8');\n },\n };\n}\n\n/**\n * Generate JUnit XML from test results\n */\nfunction generateJUnitXml(\n result: TestRunResult,\n suiteName: string,\n includeProperties: boolean\n): string {\n const lines: string[] = [];\n\n // XML declaration\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n\n // Root testsuites element\n lines.push(\n `<testsuites name=\"${escapeXml(suiteName)}\" tests=\"${result.totalTests}\" failures=\"${result.totalFailed}\" skipped=\"${result.totalSkipped}\" time=\"${(result.totalDuration / 1000).toFixed(3)}\">`\n );\n\n // Generate each test suite\n for (const suite of result.suites) {\n lines.push(generateTestSuiteXml(suite, includeProperties));\n }\n\n lines.push('</testsuites>');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate XML for a single test suite\n */\nfunction generateTestSuiteXml(suite: TestSuite, includeProperties: boolean): string {\n const lines: string[] = [];\n\n // Testsuite element\n lines.push(\n ` <testsuite name=\"${escapeXml(suite.name)}\" tests=\"${suite.tests.length}\" failures=\"${suite.failed}\" skipped=\"${suite.skipped}\" time=\"${(suite.duration / 1000).toFixed(3)}\">`\n );\n\n // Properties (optional)\n if (includeProperties) {\n lines.push(' <properties>');\n lines.push(` <property name=\"component\" value=\"${escapeXml(suite.name)}\"/>`);\n lines.push(' </properties>');\n }\n\n // Test cases\n for (const test of suite.tests) {\n lines.push(generateTestCaseXml(test));\n }\n\n lines.push(' </testsuite>');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate XML for a single test case\n */\nfunction generateTestCaseXml(result: TestResult): string {\n const { testCase, status, duration, error, steps, accessibility } = result;\n const lines: string[] = [];\n\n const testName = testCase.variant;\n const className = testCase.component;\n const time = (duration / 1000).toFixed(3);\n\n // Opening tag\n if (status === 'passed' && !accessibility?.violations.length) {\n // Simple passed test - self-closing tag\n lines.push(` <testcase name=\"${escapeXml(testName)}\" classname=\"${escapeXml(className)}\" time=\"${time}\"/>`);\n } else {\n // Test with failure, skip, or a11y info\n lines.push(` <testcase name=\"${escapeXml(testName)}\" classname=\"${escapeXml(className)}\" time=\"${time}\">`);\n\n if (status === 'failed') {\n // Failure element\n const message = error?.message || 'Test failed';\n lines.push(` <failure message=\"${escapeXml(message)}\" type=\"AssertionError\">`);\n\n // Add detailed failure info\n const details: string[] = [];\n\n // Add step failures\n const failedSteps = steps.filter((s) => s.status === 'failed');\n if (failedSteps.length > 0) {\n details.push('Failed steps:');\n for (const step of failedSteps) {\n details.push(` - ${step.name}: ${step.error?.message || 'Failed'}`);\n }\n }\n\n // Add stack trace if available\n if (error?.stack) {\n details.push('');\n details.push('Stack trace:');\n details.push(error.stack);\n }\n\n if (details.length > 0) {\n lines.push(escapeXml(details.join('\\n')));\n }\n\n lines.push(' </failure>');\n } else if (status === 'skipped') {\n lines.push(' <skipped/>');\n }\n\n // Add system-out for accessibility violations\n if (accessibility?.violations.length) {\n lines.push(' <system-out>');\n lines.push(`Accessibility violations (${accessibility.violations.length}):`);\n for (const violation of accessibility.violations) {\n lines.push(` [${violation.impact}] ${violation.id}: ${violation.description}`);\n lines.push(` Help: ${violation.help}`);\n for (const node of violation.nodes.slice(0, 3)) {\n lines.push(` Element: ${node.html.substring(0, 100)}`);\n }\n if (violation.nodes.length > 3) {\n lines.push(` ... and ${violation.nodes.length - 3} more elements`);\n }\n }\n lines.push(' </system-out>');\n }\n\n lines.push(' </testcase>');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Escape special XML characters\n */\nfunction escapeXml(str: string): string {\n const cleaned = Array.from(str).filter((ch) => {\n const code = ch.charCodeAt(0);\n return code === 0x09 || code === 0x0A || code === 0x0D || code >= 0x20;\n }).join('');\n\n return cleaned\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n","/**\n * JSON reporter - machine-readable output\n *\n * Outputs structured JSON for:\n * - AI analysis and processing\n * - Custom dashboards\n * - Integration with other tools\n */\n\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { TestRunResult, TestReporter } from '../types.js';\n\nexport interface JsonReporterOptions {\n /** Output file path */\n outputPath: string;\n /** Pretty print the JSON */\n pretty?: boolean;\n /** Include full step details */\n includeSteps?: boolean;\n /** Include stack traces in errors */\n includeStacks?: boolean;\n}\n\n/**\n * JSON report structure\n */\nexport interface JsonReport {\n /** Report metadata */\n meta: {\n /** Report version */\n version: string;\n /** Test run start time */\n startTime: string;\n /** Test run end time */\n endTime: string;\n /** Total duration in milliseconds */\n duration: number;\n };\n /** Summary statistics */\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n passRate: number;\n a11yViolations?: number;\n };\n /** Test suites with results */\n suites: Array<{\n name: string;\n tests: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n results: Array<{\n id: string;\n component: string;\n variant: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n steps?: Array<{\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: string;\n }>;\n error?: {\n message: string;\n stack?: string;\n };\n accessibility?: {\n violations: number;\n passes: number;\n details?: Array<{\n id: string;\n impact: string;\n description: string;\n elements: number;\n }>;\n };\n retryAttempt?: number;\n }>;\n }>;\n}\n\n/**\n * Create a JSON reporter\n */\nexport function createJsonReporter(options: JsonReporterOptions): TestReporter {\n const { outputPath, pretty = true, includeSteps = true, includeStacks = false } = options;\n\n return {\n async onRunComplete(result: TestRunResult) {\n const report = generateJsonReport(result, includeSteps, includeStacks);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n // Write the JSON file\n const json = pretty ? JSON.stringify(report, null, 2) : JSON.stringify(report);\n await writeFile(outputPath, json, 'utf-8');\n },\n };\n}\n\n/**\n * Generate JSON report from test results\n */\nfunction generateJsonReport(\n result: TestRunResult,\n includeSteps: boolean,\n includeStacks: boolean\n): JsonReport {\n const { suites, totalTests, totalPassed, totalFailed, totalSkipped, totalDuration, startTime, endTime } = result;\n\n return {\n meta: {\n version: '1.0.0',\n startTime: startTime.toISOString(),\n endTime: endTime.toISOString(),\n duration: totalDuration,\n },\n summary: {\n total: totalTests,\n passed: totalPassed,\n failed: totalFailed,\n skipped: totalSkipped,\n passRate: totalTests > 0 ? Math.round((totalPassed / totalTests) * 100) : 0,\n a11yViolations: result.totalA11yViolations,\n },\n suites: suites.map((suite) => ({\n name: suite.name,\n tests: suite.tests.length,\n passed: suite.passed,\n failed: suite.failed,\n skipped: suite.skipped,\n duration: suite.duration,\n results: suite.tests.map((test) => {\n const resultObj: JsonReport['suites'][0]['results'][0] = {\n id: test.testCase.id,\n component: test.testCase.component,\n variant: test.testCase.variant,\n status: test.status,\n duration: test.duration,\n };\n\n // Include steps if requested\n if (includeSteps && test.steps.length > 0) {\n resultObj.steps = test.steps.map((step) => ({\n name: step.name,\n status: step.status,\n duration: step.duration,\n error: step.error?.message,\n }));\n }\n\n // Include error if present\n if (test.error) {\n resultObj.error = {\n message: test.error.message,\n stack: includeStacks ? test.error.stack : undefined,\n };\n }\n\n // Include accessibility results if present\n if (test.accessibility) {\n resultObj.accessibility = {\n violations: test.accessibility.violations.length,\n passes: test.accessibility.passes,\n details: test.accessibility.violations.map((v) => ({\n id: v.id,\n impact: v.impact,\n description: v.description,\n elements: v.nodes.length,\n })),\n };\n }\n\n // Include retry info if applicable\n if (test.retryAttempt) {\n resultObj.retryAttempt = test.retryAttempt;\n }\n\n return resultObj;\n }),\n })),\n };\n}\n","/**\n * Watch mode - file watcher with selective re-run\n */\n\nimport { watch } from 'node:fs';\nimport { resolve, relative } from 'node:path';\nimport pc from 'picocolors';\nimport type { SegmentsConfig } from '../core/index.js';\nimport { discoverSegmentFiles } from '../core/node.js';\nimport type { TestCase, RunnerOptions, TestReporter } from './types.js';\nimport { discoverTests } from './discovery.js';\nimport { runTests } from './runner.js';\n\nexport interface WatchOptions {\n /** Debounce delay in milliseconds */\n debounceMs?: number;\n /** Clear console on each run */\n clearConsole?: boolean;\n /** Run all tests initially */\n runOnStart?: boolean;\n}\n\n/**\n * Start watch mode\n */\nexport async function startWatchMode(\n config: SegmentsConfig,\n configDir: string,\n runnerOptions: RunnerOptions,\n reporters: TestReporter[],\n options: WatchOptions = {}\n): Promise<void> {\n const { debounceMs = 300, clearConsole = true, runOnStart = true } = options;\n\n let debounceTimer: NodeJS.Timeout | null = null;\n let isRunning = false;\n const pendingFiles = new Set<string>();\n\n // Get files to watch\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n const watchPaths = new Set<string>();\n\n for (const file of segmentFiles) {\n watchPaths.add(file.absolutePath);\n }\n\n // Also watch the directories containing segment files\n const watchDirs = new Set<string>();\n for (const path of watchPaths) {\n const dir = resolve(path, '..');\n watchDirs.add(dir);\n }\n\n console.log();\n console.log(pc.cyan(pc.bold('Segments Test Runner - Watch Mode')));\n console.log(pc.dim(`Watching ${watchPaths.size} files in ${watchDirs.size} directories`));\n console.log(pc.dim('Press Ctrl+C to stop'));\n console.log();\n\n // Function to run tests\n const runTestsForFiles = async (changedFiles: string[]): Promise<void> => {\n if (isRunning) {\n // Queue up changed files for next run\n for (const file of changedFiles) {\n pendingFiles.add(file);\n }\n return;\n }\n\n isRunning = true;\n\n try {\n if (clearConsole) {\n console.clear();\n }\n\n console.log(pc.cyan('Changes detected, running tests...'));\n console.log(pc.dim(`Changed: ${changedFiles.map((f) => relative(configDir, f)).join(', ')}`));\n console.log();\n\n // Discover tests (filter to changed files if possible)\n const allTests = await discoverTests(config, configDir, {});\n\n // Filter to tests from changed files\n const changedRelativePaths = changedFiles.map((f) => relative(configDir, f));\n const testsToRun = changedRelativePaths.length > 0\n ? allTests.filter((t) => changedRelativePaths.some((p) => t.sourceFile.includes(p)))\n : allTests;\n\n if (testsToRun.length === 0) {\n console.log(pc.yellow('No tests found in changed files'));\n console.log();\n return;\n }\n\n // Run the tests\n await runTests(testsToRun, runnerOptions, reporters);\n } catch (error) {\n console.error(pc.red('Error running tests:'), error);\n } finally {\n isRunning = false;\n\n // Check if there are pending files to run\n if (pendingFiles.size > 0) {\n const files = Array.from(pendingFiles);\n pendingFiles.clear();\n await runTestsForFiles(files);\n }\n }\n };\n\n // Run initial tests if configured\n if (runOnStart) {\n const allTests = await discoverTests(config, configDir, {});\n if (allTests.length > 0) {\n await runTests(allTests, runnerOptions, reporters);\n } else {\n console.log(pc.yellow('No tests with play functions found'));\n }\n console.log();\n console.log(pc.dim('Watching for changes...'));\n console.log();\n }\n\n // Set up file watchers\n const watchers: ReturnType<typeof watch>[] = [];\n\n for (const dir of watchDirs) {\n try {\n const watcher = watch(dir, { recursive: false }, (eventType, filename) => {\n if (!filename) return;\n\n const fullPath = resolve(dir, filename);\n\n // Check if this is a segment file we care about\n if (!watchPaths.has(fullPath)) return;\n\n // Debounce the run\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n pendingFiles.add(fullPath);\n\n debounceTimer = setTimeout(() => {\n const files = Array.from(pendingFiles);\n pendingFiles.clear();\n runTestsForFiles(files);\n }, debounceMs);\n });\n\n watchers.push(watcher);\n } catch (error) {\n console.warn(pc.yellow(`Warning: Could not watch directory ${dir}`), error);\n }\n }\n\n // Handle process termination\n const cleanup = () => {\n console.log();\n console.log(pc.dim('Stopping watch mode...'));\n\n for (const watcher of watchers) {\n watcher.close();\n }\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n process.exit(0);\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n // Keep process alive\n await new Promise(() => {\n // This promise never resolves, keeping the process alive\n // until terminated\n });\n}\n\n/**\n * Interactive watch mode with keyboard controls\n */\nexport async function startInteractiveWatchMode(\n config: SegmentsConfig,\n configDir: string,\n runnerOptions: RunnerOptions,\n reporters: TestReporter[]\n): Promise<void> {\n const lastFailedTests: TestCase[] = [];\n\n // Start basic watch mode\n await startWatchMode(config, configDir, runnerOptions, reporters, {\n runOnStart: true,\n clearConsole: true,\n });\n}\n"],"mappings":"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","names":["resolve","join","mkdir","pc","timeout","resolve","mkdir","writeFile","join","writeFile","mkdir","dirname","pc","pc","resolve","pc","mkdir","join"]}