@fragments-sdk/cli 0.6.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 (178) hide show
  1. package/dist/bin.js +529 -285
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-F7ITZPDJ.js → chunk-32VIEOQY.js} +18 -18
  4. package/dist/chunk-32VIEOQY.js.map +1 -0
  5. package/dist/{chunk-SSLQXHNX.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-Q7GOHVOK.js → chunk-GCZMFLDI.js} +67 -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-D35RGPAG.js → chunk-U6VTHBNI.js} +499 -83
  16. package/dist/chunk-U6VTHBNI.js.map +1 -0
  17. package/dist/{core-SKRPJQZG.js → core-SFHPYR5H.js} +24 -26
  18. package/dist/{generate-7AF7WRVK.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-WKGDPYI4.js → init-EIM5WNMP.js} +5 -5
  23. package/dist/{init-WKGDPYI4.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-F3E4JJM7.js → service-ED2LNCTU.js} +6 -6
  28. package/dist/{static-viewer-4LQZ5AGA.js → static-viewer-Q4F4QP5M.js} +4 -4
  29. package/dist/{test-CJDNJTPZ.js → test-6VN2DA3S.js} +19 -19
  30. package/dist/test-6VN2DA3S.js.map +1 -0
  31. package/dist/{tokens-JAJABYXP.js → tokens-P2B7ZAM3.js} +5 -5
  32. package/dist/{viewer-R3Q6WAMJ.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 +24 -1
  38. package/src/build.ts +64 -21
  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 +274 -0
  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 +83 -20
  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 +542 -0
  67. package/src/core/graph-extractor.ts +601 -0
  68. package/src/core/importAnalyzer.ts +6 -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 +201 -103
  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/Icons.tsx +53 -1
  126. package/src/viewer/components/InteractionsPanel.tsx +2 -2
  127. package/src/viewer/components/IsolatedPreviewFrame.tsx +6 -6
  128. package/src/viewer/components/IsolatedRender.tsx +10 -10
  129. package/src/viewer/components/Layout.tsx +7 -3
  130. package/src/viewer/components/LeftSidebar.tsx +92 -114
  131. package/src/viewer/components/MultiViewportPreview.tsx +14 -14
  132. package/src/viewer/components/PreviewArea.tsx +11 -11
  133. package/src/viewer/components/PreviewFrameHost.tsx +77 -48
  134. package/src/viewer/components/PreviewToolbar.tsx +57 -10
  135. package/src/viewer/components/RightSidebar.tsx +9 -9
  136. package/src/viewer/components/Sidebar.tsx +17 -17
  137. package/src/viewer/components/StoryRenderer.tsx +2 -2
  138. package/src/viewer/components/TokenStylePanel.tsx +1 -1
  139. package/src/viewer/components/UsageSection.tsx +2 -2
  140. package/src/viewer/components/VariantMatrix.tsx +11 -11
  141. package/src/viewer/components/VariantRenderer.tsx +3 -3
  142. package/src/viewer/components/VariantTabs.tsx +2 -2
  143. package/src/viewer/components/ViewportSelector.tsx +56 -45
  144. package/src/viewer/components/_future/CreatePage.tsx +6 -6
  145. package/src/viewer/composition-renderer.ts +11 -11
  146. package/src/viewer/constants/ui.ts +4 -4
  147. package/src/viewer/entry.tsx +40 -40
  148. package/src/viewer/hooks/useFigmaIntegration.ts +1 -1
  149. package/src/viewer/hooks/usePreviewBridge.ts +5 -5
  150. package/src/viewer/hooks/useUrlState.ts +6 -6
  151. package/src/viewer/index.ts +2 -2
  152. package/src/viewer/intelligence/healthReport.ts +17 -17
  153. package/src/viewer/intelligence/styleDrift.ts +1 -1
  154. package/src/viewer/intelligence/usageScanner.ts +1 -1
  155. package/src/viewer/preview-frame.html +22 -13
  156. package/src/viewer/render-template.html +1 -1
  157. package/src/viewer/render-utils.ts +21 -21
  158. package/src/viewer/server.ts +18 -18
  159. package/src/viewer/styles/globals.css +42 -81
  160. package/src/viewer/utils/detectRelationships.ts +22 -22
  161. package/src/viewer/vite-plugin.ts +213 -213
  162. package/dist/chunk-6JBGU74P.js.map +0 -1
  163. package/dist/chunk-D35RGPAG.js.map +0 -1
  164. package/dist/chunk-F7ITZPDJ.js.map +0 -1
  165. package/dist/chunk-NWQ4CJOQ.js.map +0 -1
  166. package/dist/chunk-Q7GOHVOK.js.map +0 -1
  167. package/dist/chunk-RVRTRESS.js.map +0 -1
  168. package/dist/chunk-SSLQXHNX.js.map +0 -1
  169. package/dist/generate-7AF7WRVK.js.map +0 -1
  170. package/dist/scan-K6JNMCGM.js +0 -12
  171. package/dist/test-CJDNJTPZ.js.map +0 -1
  172. package/dist/viewer-R3Q6WAMJ.js.map +0 -1
  173. package/src/shared/segment-loader.ts +0 -59
  174. /package/dist/{core-SKRPJQZG.js.map → core-SFHPYR5H.js.map} +0 -0
  175. /package/dist/{scan-K6JNMCGM.js.map → scan-KQBKUS64.js.map} +0 -0
  176. /package/dist/{service-F3E4JJM7.js.map → service-ED2LNCTU.js.map} +0 -0
  177. /package/dist/{static-viewer-4LQZ5AGA.js.map → static-viewer-Q4F4QP5M.js.map} +0 -0
  178. /package/dist/{tokens-JAJABYXP.js.map → tokens-P2B7ZAM3.js.map} +0 -0
@@ -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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/viewer/server.ts","../src/viewer/vite-plugin.ts","../src/viewer/render-utils.ts","../src/viewer/style-utils.ts"],"sourcesContent":["/**\n * Segments Dev Server\n *\n * Runs a Vite dev server that:\n * 1. Uses the project's existing Vite/build configuration\n * 2. Has access to all project dependencies\n * 3. Can render actual components with proper styling\n * 4. Supports HMR for segment file changes\n *\n * This is the \"Storybook-like\" experience for Segments.\n */\n\nimport {\n createServer,\n mergeConfig,\n loadConfigFromFile,\n type ViteDevServer,\n type InlineConfig,\n} from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { resolve, dirname, join } from \"node:path\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { loadConfig, discoverSegmentFiles, discoverInstalledFragments } from \"../core/node.js\";\nimport { segmentsPlugin } from \"./vite-plugin.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n// At runtime, __dirname is dist/. Viewer assets live in src/viewer/.\nconst cliPackageRoot = resolve(__dirname, \"..\");\nconst viewerRoot = resolve(cliPackageRoot, \"src/viewer\");\nconst packagesRoot = resolve(cliPackageRoot, \"..\");\nconst uiLibRoot = resolve(packagesRoot, \"../libs/ui/src\");\n\nexport interface DevServerOptions {\n /** Port to run the server on */\n port?: number;\n /** Path to segments config file */\n configPath?: string;\n /** Open browser on start */\n open?: boolean;\n /** Project root (defaults to cwd) */\n projectRoot?: string;\n}\n\n/**\n * Create and start the Segments dev server.\n *\n * The server runs WITHIN the project's context, meaning:\n * - All project dependencies are available\n * - SCSS, CSS modules, etc. work automatically\n * - Path aliases from tsconfig.json work\n * - Components render exactly as they would in the app\n */\nexport async function createDevServer(\n options: DevServerOptions = {}\n): Promise<ViteDevServer> {\n const startTime = performance.now();\n const {\n port = 6006,\n configPath,\n open = true,\n projectRoot = process.cwd(),\n } = options;\n\n console.log(\"\\n🔧 Loading configuration...\");\n\n // Load segments config\n const { config, configDir } = await loadConfig(configPath);\n\n // Discover segment files (local + installed packages)\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n const installedFiles = await discoverInstalledFragments(projectRoot);\n const allSegmentFiles = [...segmentFiles, ...installedFiles];\n console.log(`📦 Found ${segmentFiles.length} local + ${installedFiles.length} installed fragment file(s)`);\n\n // Try to load project's Vite config\n let projectViteConfig: InlineConfig = {};\n const viteConfigPath = findViteConfig(projectRoot);\n\n if (viteConfigPath) {\n console.log(`📄 Using project Vite config: ${viteConfigPath}`);\n try {\n const loaded = await loadConfigFromFile(\n { command: \"serve\", mode: \"development\" },\n viteConfigPath,\n projectRoot\n );\n if (loaded) {\n projectViteConfig = loaded.config;\n }\n } catch (error) {\n console.warn(\"⚠️ Could not load project Vite config:\", error);\n }\n } else {\n console.log(\"ℹ️ No project Vite config found, using defaults\");\n }\n\n // Find node_modules (handles monorepo setups)\n const nodeModulesPath = findNodeModules(projectRoot);\n console.log(`📁 Using node_modules: ${nodeModulesPath}`);\n\n // Collect installed package roots so Vite can serve files from node_modules\n const installedPkgRoots = [...new Set(\n installedFiles.map(f => {\n const idx = f.absolutePath.indexOf('/node_modules/');\n if (idx === -1) return dirname(f.absolutePath);\n const afterNm = f.absolutePath.slice(idx + '/node_modules/'.length);\n const pkgName = afterNm.startsWith('@')\n ? afterNm.split('/').slice(0, 2).join('/')\n : afterNm.split('/')[0];\n return resolve(projectRoot, 'node_modules', pkgName);\n })\n )];\n\n // Our Segments-specific configuration\n const segmentsConfig: InlineConfig = {\n configFile: false, // Don't load config again\n root: projectRoot, // Run from PROJECT root\n base: \"/\",\n\n server: {\n port,\n open: open ? \"/fragments/\" : false,\n fs: {\n // Allow serving files from viewer package, project, UI library, and node_modules root\n allow: [viewerRoot, uiLibRoot, projectRoot, configDir, dirname(nodeModulesPath), ...installedPkgRoots],\n },\n },\n\n plugins: [\n // React support (if not already in project config)\n ...(hasReactPlugin(projectViteConfig) ? [] : [react()]),\n\n // Segments plugins (array including SVGR)\n ...segmentsPlugin({\n segmentFiles: allSegmentFiles,\n config,\n projectRoot,\n }),\n ],\n\n // CSS configuration\n css: {},\n\n optimizeDeps: {\n // Include common dependencies for faster startup\n include: [\"react\", \"react-dom\", \"react/jsx-runtime\", \"react/jsx-dev-runtime\"],\n },\n\n // Ensure we can resolve viewer's dependencies\n resolve: {\n // Dedupe ensures all imports of these packages resolve to the same copy\n dedupe: [\"react\", \"react-dom\"],\n alias: {\n // Allow importing from viewer package\n \"@fragments/viewer\": viewerRoot,\n // Resolve @fragments/ui to the UI library source for dogfooding\n \"@fragments/ui\": resolve(uiLibRoot, \"index.ts\"),\n // Resolve @fragments/core to the consolidated core source\n \"@fragments/core\": resolve(cliPackageRoot, \"src/core/index.ts\"),\n // Ensure ALL react imports resolve to project's node_modules\n // This is critical for viewer files loaded from outside project root\n \"react\": safeRealpath(join(nodeModulesPath, \"react\")),\n \"react-dom\": safeRealpath(join(nodeModulesPath, \"react-dom\")),\n \"react/jsx-runtime\": safeRealpath(join(nodeModulesPath, \"react/jsx-runtime\")),\n \"react/jsx-dev-runtime\": safeRealpath(join(nodeModulesPath, \"react/jsx-dev-runtime\")),\n },\n },\n };\n\n // Merge project config with our config\n // Project config takes precedence for most things\n const mergedConfig = mergeConfig(projectViteConfig, segmentsConfig);\n\n console.log(\"🚀 Starting dev server...\\n\");\n\n // Create and start the server\n const server = await createServer(mergedConfig);\n await server.listen();\n\n // Log startup time\n const startupTime = ((performance.now() - startTime) / 1000).toFixed(2);\n console.log(`⚡ Server ready in ${startupTime}s`);\n\n return server;\n}\n\n/**\n * Resolve symlinks to real paths, with fallback.\n */\nfunction safeRealpath(p: string): string {\n try {\n return realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * Resolve @fragments packages with fallback to monorepo packages.\n * This handles the case where the viewer is served from the fragments monorepo\n * but the user's project doesn't have @fragments packages installed.\n */\nfunction resolveFragmentsPackage(packageName: string, nodeModulesPath: string): string {\n // Try project's node_modules first\n const projectPath = join(nodeModulesPath, `@fragments/${packageName}/dist/index.js`);\n if (existsSync(projectPath)) {\n return safeRealpath(projectPath);\n }\n\n // Fall back to monorepo packages (sibling to viewer)\n const monorepoPath = resolve(packagesRoot, packageName, \"dist/index.js\");\n if (existsSync(monorepoPath)) {\n return safeRealpath(monorepoPath);\n }\n\n // Return project path anyway (will error with helpful message)\n return projectPath;\n}\n\n/**\n * Find node_modules directory by walking up from projectRoot.\n * This handles monorepo setups where node_modules is at the root.\n */\nfunction findNodeModules(startDir: string): string {\n let current = startDir;\n while (current !== dirname(current)) {\n const nodeModulesPath = join(current, \"node_modules\");\n if (existsSync(join(nodeModulesPath, \"react\"))) {\n return nodeModulesPath;\n }\n current = dirname(current);\n }\n // Fallback to projectRoot/node_modules\n return join(startDir, \"node_modules\");\n}\n\n/**\n * Find Vite config file in project.\n */\nfunction findViteConfig(projectRoot: string): string | null {\n const configFiles = [\n \"vite.config.ts\",\n \"vite.config.js\",\n \"vite.config.mts\",\n \"vite.config.mjs\",\n ];\n\n for (const file of configFiles) {\n const path = join(projectRoot, file);\n if (existsSync(path)) {\n return path;\n }\n }\n\n return null;\n}\n\n/**\n * Check if project config already has React plugin.\n */\nfunction hasReactPlugin(config: InlineConfig): boolean {\n if (!config.plugins) return false;\n\n const plugins = Array.isArray(config.plugins)\n ? config.plugins\n : [config.plugins];\n\n return plugins.some((plugin) => {\n if (!plugin) return false;\n if (Array.isArray(plugin)) {\n return plugin.some(\n (p) =>\n p && typeof p === \"object\" && \"name\" in p && p.name?.includes(\"react\")\n );\n }\n return (\n typeof plugin === \"object\" &&\n \"name\" in plugin &&\n plugin.name?.includes(\"react\")\n );\n });\n}\n","/**\n * Segments Vite Plugin\n *\n * This plugin runs WITHIN the project's Vite context, giving it access to:\n * - All project dependencies (React, UI libraries, etc.)\n * - Project's loaders (SCSS, CSS modules, etc.)\n * - Project's path aliases (@/components, etc.)\n * - Project's tsconfig paths\n *\n * It provides:\n * - Virtual module for segment imports\n * - Viewer UI served at /fragments/\n * - HMR support for segment file changes\n */\n\nimport type { Plugin, ViteDevServer, ResolvedConfig } from \"vite\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { readFile } from \"node:fs/promises\";\nimport { transform } from \"esbuild\";\nimport type { SegmentsConfig, CompiledSegment } from \"../core/index.js\";\nimport { generateContext, BRAND } from \"../core/index.js\";\nimport {\n findStorybookDir,\n findPreviewConfigPath,\n generatePreviewModule,\n} from \"../core/node.js\";\nimport svgr from \"vite-plugin-svgr\";\nimport {\n generateRenderScript,\n findSegmentByName,\n getAvailableComponents,\n type RenderRequest,\n} from \"./render-utils.js\";\nimport {\n compareStyles,\n type StyleDiffItem,\n} from \"./style-utils.js\";\n\n/**\n * Request body for /fragments/compare endpoint\n */\ninterface CompareRequest {\n /** Component name */\n component: string;\n /** Variant name (optional, uses first variant if not specified) */\n variant?: string;\n /** Props to render with */\n props?: Record<string, unknown>;\n /** Figma URL (optional if segment has figma link) */\n figmaUrl?: string;\n /** Viewport dimensions */\n viewport?: { width: number; height: number };\n /** Figma access token (can be passed from CLI) */\n figmaToken?: string;\n /** Diff threshold percentage (default: 1.0) */\n threshold?: number;\n /** Include style comparison from Figma design properties */\n includeStyleDiff?: boolean;\n}\n\n/**\n * Response from /fragments/compare endpoint\n */\ninterface CompareResponse {\n /** Whether diff is within threshold */\n match: boolean;\n /** Diff percentage (0-100) */\n diffPercentage: number;\n /** Threshold that was used */\n threshold: number;\n /** Rendered component screenshot (base64 PNG) */\n rendered: string;\n /** Figma design image (base64 PNG) */\n figma: string;\n /** Diff image highlighting differences (base64 PNG) */\n diff: string;\n /** The Figma URL that was used */\n figmaUrl: string;\n /** Regions that changed */\n changedRegions: Array<{\n x: number;\n y: number;\n width: number;\n height: number;\n }>;\n /** Style comparison results (when includeStyleDiff is true) */\n styleDiff?: {\n /** Whether all styles match */\n match: boolean;\n /** Individual property comparisons */\n properties: StyleDiffItem[];\n /** CSS properties from Figma design */\n figmaStyles: Record<string, string>;\n /** Computed CSS properties from rendered component */\n renderedStyles: Record<string, string>;\n };\n}\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n// At runtime, __dirname is dist/. Viewer assets live in src/viewer/.\nconst viewerAssetsRoot = resolve(__dirname, \"..\", \"src/viewer\");\n\n// Store pending render requests (for internal render page to pick up)\nconst pendingRenders = new Map<\n string,\n { script: string; viewport?: { width: number; height: number } }\n>();\n\n// Shared browser pool for render captures (lazy initialized)\nlet sharedRenderPool: any = null;\nlet browserPoolModule: any = null;\n\n/**\n * Get or create the shared browser pool for render captures.\n * The pool is lazily initialized on first use and reused across requests.\n */\nasync function getSharedRenderPool() {\n if (!browserPoolModule) {\n browserPoolModule = await import(\"../service/index.js\");\n }\n\n if (!sharedRenderPool) {\n sharedRenderPool = new browserPoolModule.BrowserPool({\n viewport: { width: 800, height: 600 }, // Default viewport, will be overridden per page\n poolSize: 2, // Keep 2 contexts warm for parallel requests\n idleTimeoutMs: 60000, // Keep warm for 60 seconds\n });\n }\n\n return { pool: sharedRenderPool, bufferToBase64Url: browserPoolModule.bufferToBase64Url };\n}\n\nexport interface SegmentsPluginOptions {\n /** Discovered segment files */\n segmentFiles: Array<{\n absolutePath: string;\n relativePath: string;\n }>;\n\n /** Segments configuration */\n config: SegmentsConfig;\n\n /** Project root directory */\n projectRoot: string;\n}\n\n/**\n * Create the Segments Vite plugin.\n * Returns an array of plugins to support SVGR and other transforms.\n */\nexport function segmentsPlugin(options: SegmentsPluginOptions): Plugin[] {\n const { segmentFiles, config, projectRoot } = options;\n\n // Virtual module IDs\n const VIRTUAL_SEGMENTS = `virtual:${BRAND.nameLower}`;\n const VIRTUAL_SEGMENTS_RESOLVED = `\\0virtual:${BRAND.nameLower}`;\n\n const VIRTUAL_VIEWER_ENTRY = `virtual:${BRAND.nameLower}-viewer-entry`;\n const VIRTUAL_VIEWER_ENTRY_RESOLVED = `\\0virtual:${BRAND.nameLower}-viewer-entry`;\n\n const VIRTUAL_PREVIEW = `virtual:${BRAND.nameLower}-preview`;\n const VIRTUAL_PREVIEW_RESOLVED = `\\0virtual:${BRAND.nameLower}-preview`;\n\n let server: ViteDevServer | null = null;\n let resolvedConfig: ResolvedConfig | null = null;\n\n // Detect Storybook preview config path\n const storybookDir = findStorybookDir(projectRoot);\n const previewConfigPath = storybookDir\n ? findPreviewConfigPath(storybookDir)\n : null;\n\n // Track segment files for HMR\n const segmentFileSet = new Set(segmentFiles.map((f) => f.absolutePath));\n\n const mainPlugin: Plugin = {\n name: \"segments\",\n\n // Add process.env shim and esbuild config for Storybook compatibility\n config() {\n return {\n define: {\n // Shim process.env for story files that use it (e.g., process.env.STORYBOOK_*)\n \"process.env\": \"{}\",\n },\n esbuild: {\n // Handle JSX in .js files (common in Storybook preview.js files)\n loader: \"tsx\",\n include: /\\.(tsx?|jsx?)$/,\n },\n optimizeDeps: {\n // Force esbuild to handle .js files with JSX\n esbuildOptions: {\n loader: {\n \".js\": \"jsx\",\n },\n },\n },\n };\n },\n\n // Store resolved config\n configResolved(config) {\n resolvedConfig = config;\n },\n\n // Store server reference for HMR\n configureServer(_server) {\n server = _server;\n\n // Serve the viewer UI at /fragments/\n _server.middlewares.use(async (req, res, next) => {\n // Handle /fragments/render endpoint for AI preview\n if (req.url === \"/fragments/render\" && req.method === \"POST\") {\n try {\n // Parse JSON body\n const body = await parseJsonBody(req);\n const { component, props = {}, viewport } = body as RenderRequest;\n\n if (!component) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Missing required field: component\" })\n );\n return;\n }\n\n // Load segments to find the component\n const loadedSegments = await loadSegmentsForRender(\n segmentFiles,\n projectRoot\n );\n const segmentInfo = findSegmentByName(component, loadedSegments);\n\n if (!segmentInfo) {\n const available = getAvailableComponents(loadedSegments);\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Component '${component}' not found. Available: ${available.join(\n \", \"\n )}`,\n })\n );\n return;\n }\n\n // Find the absolute path for the segment\n const segmentFile = segmentFiles.find(\n (f) => f.relativePath === segmentInfo.path\n );\n if (!segmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Could not resolve segment file path\" })\n );\n return;\n }\n\n // Generate render script\n const renderScript = generateRenderScript(\n segmentFile.absolutePath,\n segmentInfo.name,\n props\n );\n\n // Store the render request for the render page to pick up\n const requestId =\n Date.now().toString(36) + Math.random().toString(36).slice(2);\n pendingRenders.set(requestId, { script: renderScript, viewport });\n\n // Get server address\n const address = _server.httpServer?.address();\n const port =\n typeof address === \"object\" && address ? address.port : 6006;\n\n // Use Playwright to render and capture\n const screenshot = await captureRender(\n `http://localhost:${port}/fragments/__render__/${requestId}`,\n viewport || { width: 800, height: 600 }\n );\n\n // Clean up\n pendingRenders.delete(requestId);\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ screenshot }));\n } catch (error) {\n console.error(\"[Fragments] Error rendering:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: error instanceof Error ? error.message : \"Render failed\",\n })\n );\n }\n return;\n }\n\n // Serve render page for AI preview (internal use)\n if (req.url?.startsWith(\"/fragments/__render__/\")) {\n const requestId = req.url\n .split(\"/fragments/__render__/\")[1]\n ?.split(\"?\")[0];\n const renderData = pendingRenders.get(requestId || \"\");\n\n if (!renderData) {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Render request not found or expired\");\n return;\n }\n\n await serveRenderHTML(res, _server, renderData.script);\n return;\n }\n\n // Handle /fragments/compare endpoint for Figma design verification\n if (req.url === \"/fragments/compare\" && req.method === \"POST\") {\n try {\n const body = (await parseJsonBody(req)) as CompareRequest;\n const {\n component,\n variant,\n props = {},\n figmaUrl,\n viewport,\n threshold = 1.0,\n includeStyleDiff = false,\n } = body;\n\n if (!component) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Missing required field: component\" })\n );\n return;\n }\n\n // Check for Figma access token (request body > env var > config)\n const figmaToken =\n body.figmaToken ||\n process.env.FIGMA_ACCESS_TOKEN ||\n config.figmaToken;\n if (!figmaToken && !figmaUrl) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `No Figma access token configured. Figma token: ${figmaToken}`,\n suggestion:\n \"Set FIGMA_ACCESS_TOKEN env var, add figmaToken to fragments.config.ts, or provide in request\",\n })\n );\n return;\n }\n\n // Debug: Log segment files\n console.log(\"[Fragments] Compare request for:\", component);\n console.log(\"[Fragments] segmentFiles count:\", segmentFiles.length);\n console.log(\"[Fragments] First 3 segment files:\", segmentFiles.slice(0, 3).map(f => f.relativePath));\n console.log(\"[Fragments] projectRoot:\", projectRoot);\n\n // Load segments to find the component and its figma URL\n const loadedSegments = await loadSegmentsForRender(\n segmentFiles,\n projectRoot\n );\n console.log(\"[Fragments] loadedSegments count:\", loadedSegments.length);\n console.log(\"[Fragments] First 3 loaded:\", loadedSegments.slice(0, 3).map(s => s.segment.meta.name));\n const segmentInfo = findSegmentByName(component, loadedSegments);\n\n if (!segmentInfo) {\n const available = getAvailableComponents(loadedSegments);\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Component '${component}' not found. Available: ${available.join(\n \", \"\n )}`,\n })\n );\n return;\n }\n\n // Find full segment data to get figma URL\n const fullSegmentData = await loadFullSegmentForCompare(\n _server,\n segmentFiles,\n component,\n variant,\n projectRoot\n );\n\n // Determine which Figma URL to use (request > variant > meta)\n const effectiveFigmaUrl = figmaUrl || fullSegmentData?.figmaUrl;\n\n if (!effectiveFigmaUrl) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `No Figma URL for component '${component}'`,\n suggestion:\n \"Add 'figma' field to segment definition or provide figmaUrl in request\",\n })\n );\n return;\n }\n\n if (!figmaToken) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Figma access token required for comparison\",\n suggestion:\n \"Set FIGMA_ACCESS_TOKEN env var or add figmaToken to fragments.config.ts\",\n })\n );\n return;\n }\n\n // Find segment file for rendering\n const segmentFile = segmentFiles.find(\n (f) => f.relativePath === segmentInfo.path\n );\n if (!segmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Could not resolve segment file path\" })\n );\n return;\n }\n\n // Get server port\n const address = _server.httpServer?.address();\n const port =\n typeof address === \"object\" && address ? address.port : 6006;\n const renderViewport = viewport || { width: 800, height: 600 };\n\n // Import Figma service\n const { FigmaClient, bufferToBase64Url } = await import(\n \"../service/index.js\"\n );\n const figmaClient = new FigmaClient({\n accessToken: figmaToken,\n });\n\n // Parse Figma URL to get file key and node ID for style diff\n const { fileKey, nodeId } = figmaClient.parseUrl(effectiveFigmaUrl);\n\n // Generate render script and request ID for component capture\n const renderScript = generateRenderScript(\n segmentFile.absolutePath,\n segmentInfo.name,\n props\n );\n const requestId =\n Date.now().toString(36) + Math.random().toString(36).slice(2);\n pendingRenders.set(requestId, {\n script: renderScript,\n viewport: renderViewport,\n });\n\n try {\n // Execute render, Figma fetch, and optionally style fetch in parallel\n const [captureResult, figmaImageResult, figmaDesignProps] = await Promise.all([\n // Render and capture the component (with optional computed styles)\n captureRenderWithStyles(\n `http://localhost:${port}/fragments/__render__/${requestId}`,\n renderViewport,\n includeStyleDiff\n ),\n // Fetch Figma image\n figmaClient.getImageFromUrl(effectiveFigmaUrl),\n // Fetch Figma design properties (only if includeStyleDiff is true)\n includeStyleDiff\n ? figmaClient.getNodeProperties(fileKey, nodeId)\n : Promise.resolve(null),\n ]);\n\n const renderedImage = captureResult.screenshot;\n const renderedStyles = captureResult.computedStyles;\n const figmaImage = bufferToBase64Url(figmaImageResult.data);\n\n // Compare the images\n const compareResult = await compareImages(\n renderedImage,\n figmaImage,\n threshold\n );\n\n // Build response\n const response: CompareResponse = {\n match: compareResult.matches,\n diffPercentage: compareResult.diffPercentage,\n threshold,\n rendered: renderedImage,\n figma: figmaImage,\n diff: compareResult.diffImage || renderedImage,\n figmaUrl: effectiveFigmaUrl,\n changedRegions: compareResult.changedRegions,\n };\n\n // Add style diff if requested\n if (includeStyleDiff && figmaDesignProps && renderedStyles) {\n const figmaStyles = figmaClient.convertToCSS(figmaDesignProps);\n // Convert CSSDesignProperties to Record<string, string | undefined>\n const figmaStylesRecord: Record<string, string | undefined> = { ...figmaStyles };\n const styleDiffResult = compareStyles(figmaStylesRecord, renderedStyles);\n response.styleDiff = styleDiffResult;\n\n // Update overall match to include style match\n if (!styleDiffResult.match) {\n response.match = false;\n }\n }\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(response));\n } finally {\n pendingRenders.delete(requestId);\n }\n } catch (error) {\n console.error(\"[Fragments] Error comparing:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error:\n error instanceof Error ? error.message : \"Compare failed\",\n })\n );\n }\n return;\n }\n\n // Handle /fragments/figma-styles endpoint for lightweight style fetching\n // This avoids the heavy Playwright rendering just to get styles\n if (req.url === \"/fragments/figma-styles\" && req.method === \"POST\") {\n try {\n const body = (await parseJsonBody(req)) as {\n figmaUrl: string;\n };\n\n const { figmaUrl } = body;\n\n if (!figmaUrl) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing figmaUrl\" }));\n return;\n }\n\n // Check for Figma access token\n const figmaToken =\n process.env.FIGMA_ACCESS_TOKEN || config.figmaToken;\n if (!figmaToken) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"No Figma access token configured\",\n suggestion:\n \"Set FIGMA_ACCESS_TOKEN env var or add figmaToken to fragments.config.ts\",\n })\n );\n return;\n }\n\n // Import Figma service\n const { FigmaClient } = await import(\"../service/index.js\");\n const figmaClient = new FigmaClient({ accessToken: figmaToken });\n\n // Parse Figma URL\n const { fileKey, nodeId } = figmaClient.parseUrl(figmaUrl);\n\n // Fetch design properties\n const figmaDesignProps = await figmaClient.getNodeProperties(\n fileKey,\n nodeId\n );\n const figmaStyles = figmaClient.convertToCSS(figmaDesignProps);\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ styles: figmaStyles }));\n } catch (error) {\n console.error(\"[Fragments] Error fetching Figma styles:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error:\n error instanceof Error\n ? error.message\n : \"Failed to fetch Figma styles\",\n })\n );\n }\n return;\n }\n\n // Handle /fragments/tokens endpoint for token registry\n if (req.url?.startsWith(\"/fragments/tokens\")) {\n try {\n const url = new URL(req.url, \"http://localhost\");\n const format = url.searchParams.get(\"format\") || \"json\";\n const category = url.searchParams.get(\"category\");\n const theme = url.searchParams.get(\"theme\");\n\n // Check if tokens are configured\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"No token configuration found\",\n suggestion: \"Add 'tokens' config to fragments.config.ts with 'include' patterns for CSS/SCSS files\",\n example: {\n tokens: {\n include: [\"src/styles/theme.scss\", \"src/styles/variables.css\"],\n themeSelectors: { \":root\": \"default\", \"[data-theme='dark']\": \"dark\" },\n },\n },\n }));\n return;\n }\n\n // Import token registry\n const { getSharedTokenRegistry } = await import(\"../service/index.js\");\n const registry = getSharedTokenRegistry();\n\n // Initialize if not already\n if (!registry.isInitialized()) {\n await registry.initialize(config.tokens, projectRoot);\n }\n\n let tokens = registry.getAllTokens();\n\n // Filter by category if specified\n if (category) {\n tokens = tokens.filter(t => t.category === category);\n }\n\n // Filter by theme if specified\n if (theme) {\n tokens = tokens.filter(t => t.theme === theme || t.theme === \"default\");\n }\n\n const meta = registry.getMeta();\n\n if (format === \"summary\") {\n // Return summary only\n const summary = {\n totalTokens: meta?.totalTokens || 0,\n byCategory: {} as Record<string, number>,\n byTheme: {} as Record<string, number>,\n parseTimeMs: meta?.parseTimeMs || 0,\n sourceFiles: meta?.sourceFiles || [],\n };\n\n for (const token of registry.getAllTokens()) {\n summary.byCategory[token.category] = (summary.byCategory[token.category] || 0) + 1;\n summary.byTheme[token.theme] = (summary.byTheme[token.theme] || 0) + 1;\n }\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(summary, null, 2));\n } else {\n // Return full token list\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n tokens,\n meta,\n }, null, 2));\n }\n } catch (error) {\n console.error(\"[Fragments] Error fetching tokens:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : \"Failed to fetch tokens\",\n }));\n }\n return;\n }\n\n // Handle /fragments/token-match endpoint for reverse token lookup\n if (req.url === \"/fragments/token-match\" && req.method === \"POST\") {\n try {\n const body = (await parseJsonBody(req)) as {\n value: string;\n propertyType?: \"color\" | \"spacing\" | \"typography\" | \"other\";\n theme?: string;\n };\n\n const { value, propertyType, theme } = body;\n\n if (!value) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing required field: value\" }));\n return;\n }\n\n // Check if tokens are configured\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"No token configuration found\",\n suggestion: \"Add 'tokens' config to fragments.config.ts\",\n }));\n return;\n }\n\n // Import token registry\n const { getSharedTokenRegistry } = await import(\"../service/index.js\");\n const registry = getSharedTokenRegistry();\n\n // Initialize if not already\n if (!registry.isInitialized()) {\n await registry.initialize(config.tokens, projectRoot);\n }\n\n // Match the value\n const result = registry.matchValue({\n value,\n propertyType,\n theme,\n });\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(result));\n } catch (error) {\n console.error(\"[Fragments] Error matching token:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : \"Failed to match token\",\n }));\n }\n return;\n }\n\n // Handle /fragments/compliance endpoint for token compliance checking\n if (req.url === \"/fragments/compliance\" && req.method === \"POST\") {\n try {\n const body = (await parseJsonBody(req)) as {\n component: string;\n variant?: string;\n theme?: string;\n };\n\n const { component, variant, theme = \"default\" } = body;\n\n if (!component) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing required field: component\" }));\n return;\n }\n\n // Check if tokens are configured\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n // Return 100% compliance if no tokens configured (can't check)\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n component,\n variant,\n compliance: 100,\n totalProperties: 0,\n hardcoded: 0,\n usingTokens: 0,\n violations: [],\n note: \"No token configuration found - token compliance checking disabled\",\n }));\n return;\n }\n\n // Load segment data\n const loadedSegments = await loadSegmentsForRender(segmentFiles, projectRoot);\n const segmentInfo = findSegmentByName(component, loadedSegments);\n\n if (!segmentInfo) {\n const available = getAvailableComponents(loadedSegments);\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: `Component '${component}' not found. Available: ${available.join(\", \")}`,\n }));\n return;\n }\n\n // Find segment file for rendering\n const segmentFile = segmentFiles.find(\n (f) => f.relativePath === segmentInfo.path\n );\n if (!segmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Could not resolve segment file path\" }));\n return;\n }\n\n // Import token registry\n const { getSharedTokenRegistry } = await import(\"../service/index.js\");\n const registry = getSharedTokenRegistry();\n\n // Initialize if not already\n if (!registry.isInitialized()) {\n await registry.initialize(config.tokens, projectRoot);\n }\n\n // Get server port\n const address = _server.httpServer?.address();\n const port = typeof address === \"object\" && address ? address.port : 6006;\n const renderViewport = { width: 800, height: 600 };\n\n // Generate render script and capture with styles\n const renderScript = generateRenderScript(\n segmentFile.absolutePath,\n segmentInfo.name,\n {}\n );\n const requestId = Date.now().toString(36) + Math.random().toString(36).slice(2);\n pendingRenders.set(requestId, { script: renderScript, viewport: renderViewport });\n\n try {\n // Render the component and extract computed styles\n const captureResult = await captureRenderWithStyles(\n `http://localhost:${port}/fragments/__render__/${requestId}`,\n renderViewport,\n true // extractStyles = true\n );\n\n const computedStyles = captureResult.computedStyles || {};\n\n // Convert computed styles to style diff format for calculateUsageSummary\n const styleDiffs: Array<{\n property: string;\n figma: string;\n rendered: string;\n match: boolean;\n }> = [];\n\n // Check each computed style property\n for (const [property, value] of Object.entries(computedStyles)) {\n if (!value) continue;\n\n // Try to find a matching token\n const matchResult = registry.matchValue({\n value,\n propertyType: property.toLowerCase().includes(\"color\") ? \"color\" :\n property.toLowerCase().includes(\"font\") ? \"typography\" :\n property.toLowerCase().includes(\"spacing\") || property.toLowerCase().includes(\"padding\") || property.toLowerCase().includes(\"margin\") ? \"spacing\" : undefined,\n theme,\n });\n\n // If we found an exact match, the value is using a token\n const isUsingToken = matchResult.exactMatches.length > 0;\n\n styleDiffs.push({\n property,\n figma: value, // Use the value as both figma and rendered for self-comparison\n rendered: value,\n match: isUsingToken,\n });\n }\n\n // Calculate compliance using token registry\n const usageSummary = registry.calculateUsageSummary(styleDiffs, theme);\n\n // Build violations list from hardcoded properties\n interface ViolationItem {\n property: string;\n issue: string;\n severity: \"error\" | \"warning\";\n suggestion?: string;\n expected?: string;\n actual?: string;\n }\n\n const violations: ViolationItem[] = usageSummary.hardcodedProperties.map(hp => {\n const suggestion = hp.suggestedFix\n ? `Use ${hp.suggestedFix.tokenName} (${hp.suggestedFix.tokenValue})`\n : undefined;\n\n return {\n property: hp.property,\n issue: `Hardcoded value \"${hp.rendered}\" should use a design token`,\n severity: \"warning\" as const,\n suggestion,\n expected: hp.figmaToken,\n actual: hp.rendered,\n };\n });\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n component,\n variant,\n compliance: usageSummary.compliancePercent,\n totalProperties: usageSummary.totalProperties,\n hardcoded: usageSummary.hardcoded,\n usingTokens: usageSummary.usingTokens,\n violations,\n }));\n } finally {\n pendingRenders.delete(requestId);\n }\n } catch (error) {\n console.error(\"[Fragments] Error checking compliance:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : \"Compliance check failed\",\n }));\n }\n return;\n }\n\n // Handle /fragments/context endpoint for AI context generation\n if (req.url?.startsWith(\"/fragments/context\")) {\n try {\n const url = new URL(req.url, \"http://localhost\");\n const format = (url.searchParams.get(\"format\") || \"markdown\") as\n | \"markdown\"\n | \"json\";\n const compact = url.searchParams.get(\"compact\") === \"true\";\n\n // Load all segments from BRAND.outFile\n const compiledSegments = await loadSegmentsForContext(\n _server,\n segmentFiles,\n config,\n projectRoot\n );\n\n const { content, tokenEstimate } = generateContext(\n compiledSegments,\n {\n format,\n compact,\n include: {\n code: url.searchParams.get(\"code\") === \"true\",\n relations: url.searchParams.get(\"relations\") === \"true\",\n },\n }\n );\n\n res.setHeader(\"X-Token-Estimate\", String(tokenEstimate));\n res.setHeader(\n \"Content-Type\",\n format === \"json\"\n ? \"application/json\"\n : \"text/markdown; charset=utf-8\"\n );\n res.end(content);\n } catch (error) {\n console.error(\"[Fragments] Error generating context:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\n \"Error generating context: \" +\n (error instanceof Error ? error.message : error)\n );\n }\n return;\n }\n\n // Handle /fragments/save endpoint for saving fragment metadata\n if (req.url === \"/fragments/save\" && req.method === \"POST\") {\n try {\n const body = await parseJsonBody(req);\n const { componentName, fragment } = body as {\n componentName: string;\n fragment: Record<string, unknown>;\n };\n\n if (!componentName || !fragment) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Missing required fields: componentName, fragment\",\n })\n );\n return;\n }\n\n // Import writeFile for saving\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { BRAND } = await import(\"../core/index.js\");\n\n // Ensure .fragments/components directory exists\n const fragmentsDir = join(projectRoot, BRAND.dataDir, BRAND.componentsDir);\n await mkdir(fragmentsDir, { recursive: true });\n\n // Write fragment file\n const fragmentPath = join(\n fragmentsDir,\n `${componentName}${BRAND.fileExtension}`\n );\n await writeFile(\n fragmentPath,\n JSON.stringify(fragment, null, 2),\n \"utf-8\"\n );\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ success: true, path: fragmentPath }));\n } catch (error) {\n console.error(\"[Fragments] Error saving fragment:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: error instanceof Error ? error.message : \"Save failed\",\n })\n );\n }\n return;\n }\n\n // Handle /fragments/fix endpoint for generating token fix patches\n if (req.url === \"/fragments/fix\" && req.method === \"POST\") {\n try {\n const body = (await parseJsonBody(req)) as {\n component: string;\n variant?: string;\n fixType?: \"token\" | \"all\";\n };\n\n const { component, variant, fixType = \"all\" } = body;\n\n if (!component) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing required field: component\" }));\n return;\n }\n\n // Check if tokens are configured\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"No token configuration found\",\n suggestion: \"Add 'tokens' config to fragments.config.ts to enable fix generation\",\n }));\n return;\n }\n\n // Load segment data\n const loadedSegments = await loadSegmentsForRender(segmentFiles, projectRoot);\n const segmentInfo = findSegmentByName(component, loadedSegments);\n\n if (!segmentInfo) {\n const available = getAvailableComponents(loadedSegments);\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: `Component '${component}' not found. Available: ${available.join(\", \")}`,\n }));\n return;\n }\n\n // Import services\n const {\n getSharedTokenRegistry,\n generateTokenPatches,\n } = await import(\"../service/index.js\");\n const registry = getSharedTokenRegistry();\n\n // Initialize token registry if not already\n if (!registry.isInitialized()) {\n await registry.initialize(config.tokens, projectRoot);\n }\n\n // For now, we generate patches based on style diff data\n // In a full implementation, we would:\n // 1. Render the component and get computed styles\n // 2. Compare with Figma styles to find hardcoded values\n // 3. Generate patches for each hardcoded value\n\n // Get source file path from segment\n const segmentFile = segmentFiles.find(\n (f) => f.relativePath === segmentInfo.path\n );\n const sourceFile = segmentFile?.relativePath || `${component}.tsx`;\n\n // For demonstration, we'll create a placeholder response\n // In production, this would use style comparison + AST patching\n const result = generateTokenPatches(\n component,\n [], // Would be populated by actual style diffs\n registry,\n { sourceFile }\n );\n\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n patches: result.patches,\n summary: result.summary,\n fixableCount: result.fixableCount,\n unfixableCount: result.unfixableCount,\n }));\n } catch (error) {\n console.error(\"[Fragments] Error generating fixes:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : \"Fix generation failed\",\n }));\n }\n return;\n }\n\n // Handle /fragments/preview/ - isolated iframe for component previews\n if (req.url?.startsWith(\"/fragments/preview\")) {\n // Redirect to trailing slash\n if (req.url === \"/fragments/preview\") {\n res.writeHead(302, { Location: \"/fragments/preview/\" });\n res.end();\n return;\n }\n\n // Serve the preview frame HTML\n await servePreviewFrameHTML(res, _server);\n return;\n }\n\n if (req.url === \"/segments\" || req.url === \"/fragments/\") {\n // Redirect to /fragments/\n if (!req.url.endsWith(\"/\")) {\n res.writeHead(302, { Location: \"/fragments/\" });\n res.end();\n return;\n }\n\n // Serve the viewer HTML\n serveViewerHTML(res, _server);\n return;\n }\n\n next();\n });\n\n // Log startup message\n _server.httpServer?.once(\"listening\", () => {\n const address = _server.httpServer?.address();\n const port =\n typeof address === \"object\" && address ? address.port : 6006;\n console.log(\n `\\n 📦 Fragments Viewer: http://localhost:${port}/fragments/\\n`\n );\n });\n },\n\n // Resolve virtual modules\n resolveId(id) {\n if (id === VIRTUAL_SEGMENTS) {\n return VIRTUAL_SEGMENTS_RESOLVED;\n }\n if (id === VIRTUAL_VIEWER_ENTRY) {\n return VIRTUAL_VIEWER_ENTRY_RESOLVED;\n }\n if (id === VIRTUAL_PREVIEW) {\n return VIRTUAL_PREVIEW_RESOLVED;\n }\n return null;\n },\n\n // Load virtual modules\n load(id) {\n if (id === VIRTUAL_SEGMENTS_RESOLVED) {\n return generateSegmentsModule(segmentFiles, config, previewConfigPath);\n }\n if (id === VIRTUAL_VIEWER_ENTRY_RESOLVED) {\n return generateViewerEntry();\n }\n if (id === VIRTUAL_PREVIEW_RESOLVED) {\n return generatePreviewModule(previewConfigPath);\n }\n return null;\n },\n\n // Handle HMR for segment files\n handleHotUpdate({ file, server }) {\n if (segmentFileSet.has(file)) {\n // Invalidate the virtual segments module\n const mod = server.moduleGraph.getModuleById(VIRTUAL_SEGMENTS_RESOLVED);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n // Send HMR update\n server.ws.send({\n type: \"custom\",\n event: \"segments:update\",\n data: { file },\n });\n\n // Return empty array to prevent full reload\n // The component HMR will handle the actual update\n return [];\n }\n },\n };\n\n // Plugin to transform JSX in .js files (common in Storybook preview.js)\n // Uses the `load` hook instead of `transform` because we need to intercept\n // the file BEFORE Vite's import-analysis tries to parse it\n const jsxTransformPlugin: Plugin = {\n name: \"segments-jsx-transform\",\n enforce: \"pre\",\n async load(id) {\n // Only handle .js files that might contain JSX (like preview.js)\n if (!id.endsWith(\".js\")) return null;\n\n // Only handle .storybook directory files (most common case for JSX in .js)\n if (!id.includes(\".storybook\")) return null;\n\n // Read the file content\n const fs = await import(\"node:fs/promises\");\n let code: string;\n try {\n code = await fs.readFile(id, \"utf-8\");\n } catch {\n return null;\n }\n\n // Check if the file contains JSX syntax\n const hasOpeningTag = code.includes(\"<\");\n const hasSelfClosingTag = code.includes(\"/>\");\n const hasClosingTag = code.includes(\"</\");\n\n // Skip if no JSX detected\n if (!hasOpeningTag || (!hasSelfClosingTag && !hasClosingTag)) return null;\n\n try {\n const result = await transform(code, {\n loader: \"jsx\",\n jsx: \"automatic\",\n sourcefile: id,\n sourcemap: true,\n });\n return {\n code: result.code,\n map: result.map,\n };\n } catch (error) {\n // Log error for debugging but don't block\n console.warn(`[Fragments] JSX transform failed for ${id}:`, error instanceof Error ? error.message : error);\n return null;\n }\n },\n };\n\n // Return array of plugins including SVGR for SVG imports\n return [\n // JSX transform for .js files (must run first)\n jsxTransformPlugin,\n // SVGR plugin to handle `import { ReactComponent } from \"*.svg\"` pattern\n svgr({\n svgrOptions: {\n exportType: \"named\", // Export as { ReactComponent }\n },\n include: \"**/*.svg\",\n }),\n // Main segments plugin\n mainPlugin,\n ];\n}\n\n/**\n * Check if a file path is a Storybook story file\n */\nfunction isStoryFile(filePath: string): boolean {\n return /\\.stories\\.(tsx?|jsx?)$/.test(filePath);\n}\n\n/**\n * Get the base component path from a segment or story file path.\n * e.g., \"src/components/Button/Button.segment.tsx\" -> \"src/components/Button/Button\"\n * e.g., \"src/components/Button/Button.stories.tsx\" -> \"src/components/Button/Button\"\n */\nfunction getBaseComponentPath(filePath: string): string {\n return filePath.replace(/\\.(segment|stories)\\.(tsx?|jsx?)$/, \"\");\n}\n\n/**\n * Generate the virtual segments module.\n * Uses dynamic imports for lazy loading - segments are loaded on demand.\n * Supports both native .segment.tsx files and Storybook .stories.tsx files.\n * Integrates Storybook preview config for global decorators, parameters, etc.\n *\n * MERGE STRATEGY: When both .segment.tsx and .stories.tsx exist for the same component:\n * - Use .stories.tsx for RENDERING (variants, props, etc.) - it's the source of truth\n * - Merge METADATA from .segment.tsx (Figma URLs, AI descriptions, usage guidelines)\n * - This gives us the best of both worlds: working renders + rich metadata\n */\nfunction generateSegmentsModule(\n segmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n config: SegmentsConfig,\n previewConfigPath: string | null\n): string {\n // Group files by base component path to identify pairs\n const filesByBasePath = new Map<string, {\n storyFile?: { absolutePath: string; relativePath: string };\n segmentFile?: { absolutePath: string; relativePath: string };\n }>();\n\n for (const file of segmentFiles) {\n const basePath = getBaseComponentPath(file.relativePath);\n const isStory = isStoryFile(file.relativePath);\n\n const existing = filesByBasePath.get(basePath) || {};\n\n if (isStory) {\n existing.storyFile = file;\n } else {\n existing.segmentFile = file;\n }\n\n filesByBasePath.set(basePath, existing);\n }\n\n // Generate loaders with metadata merge support\n // Priority: stories for rendering, segment for metadata (Figma URLs, etc.)\n const loaders = Array.from(filesByBasePath.values())\n .map((files) => {\n // Determine which file to use for rendering\n const primaryFile = files.storyFile || files.segmentFile;\n if (!primaryFile) return null;\n\n const isStory = !!files.storyFile;\n\n // If we have both, include the segment file path for metadata merge\n const metadataPath = (files.storyFile && files.segmentFile)\n ? files.segmentFile.absolutePath\n : null;\n\n return ` {\n path: \"${primaryFile.relativePath}\",\n isStory: ${isStory},\n loader: () => import(\"${primaryFile.absolutePath}\"),\n metadataLoader: ${metadataPath ? `() => import(\"${metadataPath}\")` : 'null'}\n }`;\n })\n .filter(Boolean)\n .join(\",\\n\");\n\n // Generate preview config import if available\n const previewImport = previewConfigPath\n ? `import * as previewConfig from \"virtual:segments-preview\";`\n : \"\";\n const previewSetup = previewConfigPath\n ? `\n// Set global preview config before loading segments\nsetPreviewConfig({\n decorators: previewConfig.decorators,\n parameters: previewConfig.parameters,\n globalTypes: previewConfig.globalTypes,\n args: previewConfig.args,\n argTypes: previewConfig.argTypes,\n loaders: previewConfig.loaders,\n});\n`\n : \"\";\n\n return `\nimport { storyModuleToSegment, setPreviewConfig } from \"@fragments/core\";\n${previewImport}\n${previewSetup}\n// Lazy segment loaders (supports both .segment.tsx and .stories.tsx)\nconst segmentLoaders = [\n${loaders}\n];\n\n// Cache for loaded segments\nconst loadedSegments = new Map();\n\n/**\n * Merge metadata from a segment file into a story-based segment.\n * This preserves Figma URLs and other AI-agent focused data.\n */\nfunction mergeMetadata(segment, metadataModule) {\n if (!metadataModule?.default) return segment;\n\n const metadata = metadataModule.default;\n\n // Merge meta-level Figma URL\n if (metadata.meta?.figma && !segment.meta.figma) {\n segment.meta.figma = metadata.meta.figma;\n }\n\n // Merge description if not present\n if (metadata.meta?.description && !segment.meta.description) {\n segment.meta.description = metadata.meta.description;\n }\n\n // Merge variant-level Figma URLs\n if (metadata.variants && segment.variants) {\n for (const metaVariant of metadata.variants) {\n const segmentVariant = segment.variants.find(v => v.name === metaVariant.name);\n if (segmentVariant && metaVariant.figma && !segmentVariant.figma) {\n segmentVariant.figma = metaVariant.figma;\n }\n }\n }\n\n return segment;\n}\n\n// Load all segments (for initial render)\n// Gracefully handles individual failures - one bad story won't break all segments\nexport async function loadAllSegments() {\n const results = await Promise.all(\n segmentLoaders.map(async (loader) => {\n try {\n if (loadedSegments.has(loader.path)) {\n const cached = loadedSegments.get(loader.path);\n return cached ? { path: loader.path, segment: cached } : null;\n }\n\n const module = await loader.loader();\n\n // Convert story modules to segments at runtime\n let segment;\n if (loader.isStory) {\n segment = storyModuleToSegment(module, loader.path);\n // storyModuleToSegment returns null for stories without a component\n if (!segment) {\n loadedSegments.set(loader.path, null);\n return null;\n }\n } else {\n segment = module.default;\n }\n\n // Merge metadata from corresponding segment file if available\n if (loader.metadataLoader) {\n try {\n const metadataModule = await loader.metadataLoader();\n segment = mergeMetadata(segment, metadataModule);\n } catch (metaError) {\n // Metadata loading is optional - don't fail if it errors\n console.warn(\"[Fragments] Could not load metadata for \" + loader.path + \":\", metaError.message);\n }\n }\n\n loadedSegments.set(loader.path, segment);\n return { path: loader.path, segment };\n } catch (error) {\n console.warn(\"[Fragments] Failed to load \" + loader.path + \":\", error.message);\n return null;\n }\n })\n );\n // Filter out failed loads\n return results.filter(r => r !== null);\n}\n\n// Load a single segment by path\nexport async function loadSegment(path) {\n const loader = segmentLoaders.find(l => l.path === path);\n if (!loader) return null;\n\n if (loadedSegments.has(path)) {\n return loadedSegments.get(path);\n }\n\n const module = await loader.loader();\n\n // Convert story modules to segments at runtime\n let segment;\n if (loader.isStory) {\n segment = storyModuleToSegment(module, path);\n } else {\n segment = module.default;\n }\n\n // Merge metadata from corresponding segment file if available\n if (loader.metadataLoader && segment) {\n try {\n const metadataModule = await loader.metadataLoader();\n segment = mergeMetadata(segment, metadataModule);\n } catch (metaError) {\n console.warn(\"[Fragments] Could not load metadata for \" + path + \":\", metaError.message);\n }\n }\n\n loadedSegments.set(path, segment);\n return segment;\n}\n\n// For backwards compatibility, load all segments synchronously on import\n// This is still lazy per-file but awaited at module load\nlet segments = [];\nconst segmentsPromise = loadAllSegments().then(s => { segments = s; return s; });\n\nexport { segments, segmentsPromise };\nexport const config = ${JSON.stringify(config)};\n\n// HMR support\nif (import.meta.hot) {\n import.meta.hot.accept();\n\n import.meta.hot.on(\"segments:update\", (data) => {\n console.log(\"[Fragments] File updated:\", data.file);\n // Clear cache for the updated file (handles both .segment and .stories)\n for (const [path, _] of loadedSegments) {\n const basePath = path.replace(/\\\\.(segment|stories)\\\\.tsx?$/, '');\n if (data.file.includes(basePath)) {\n loadedSegments.delete(path);\n }\n }\n // Trigger re-render in viewer\n window.dispatchEvent(new CustomEvent(\"segments:update\"));\n });\n}\n`;\n}\n\n/**\n * Generate the viewer entry point.\n */\nfunction generateViewerEntry(): string {\n return `\nimport { segments, config } from \"virtual:segments\";\n\n// Re-export for viewer\nexport { segments, config };\n\n// Initialize viewer\nconsole.log(\"[Fragments] Loaded\", segments.length, \"segment(s)\");\n`;\n}\n\n/**\n * Load segments for context generation.\n * Uses BRAND.outFile to avoid SSR module loading issues with React CJS modules.\n */\nasync function loadSegmentsForContext(\n _server: ViteDevServer,\n _segmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n _config: SegmentsConfig,\n configDir?: string\n): Promise<CompiledSegment[]> {\n const { join } = await import(\"node:path\");\n\n // Read from outFile (avoids SSR issues with React CJS)\n const segmentsJsonPath = join(configDir || process.cwd(), BRAND.outFile);\n\n try {\n const content = await readFile(segmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n segments: Record<string, CompiledSegment>;\n };\n\n return Object.values(data.segments || {});\n } catch (error) {\n console.warn(\n `[${BRAND.name}] Failed to load ${BRAND.outFile} for context:`,\n error\n );\n console.warn(`[${BRAND.name}] Run '${BRAND.cliCommand} build' to generate ${BRAND.outFile}`);\n return [];\n }\n}\n\n/**\n * Serve the viewer HTML page.\n */\nasync function serveViewerHTML(res: any, server: ViteDevServer): Promise<void> {\n const viewerRoot = viewerAssetsRoot;\n const entryPath = resolve(viewerRoot, \"entry.tsx\");\n\n try {\n // Read the viewer HTML template\n let html = await readFile(resolve(viewerRoot, \"index.html\"), \"utf-8\");\n\n // Rewrite the entry.tsx path to use absolute path to viewer package\n html = html.replace(\"/src/entry.tsx\", entryPath);\n\n // Transform HTML through Vite's pipeline\n html = await server.transformIndexHtml(\"/fragments/\", html);\n\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } catch (error) {\n console.error(\"[Fragments] Error serving viewer:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Error loading Segments viewer\");\n }\n}\n\n/**\n * Serve the isolated preview frame HTML page.\n * This is used for iframe-based component preview with CSS isolation.\n */\nasync function servePreviewFrameHTML(res: any, server: ViteDevServer): Promise<void> {\n const viewerRoot = viewerAssetsRoot;\n const entryPath = resolve(viewerRoot, \"preview-frame-entry.tsx\");\n\n try {\n // Read the preview frame HTML template\n let html = await readFile(resolve(viewerRoot, \"preview-frame.html\"), \"utf-8\");\n\n // Rewrite the entry path to use absolute path to viewer package\n html = html.replace(\"/src/preview-frame-entry.tsx\", entryPath);\n\n // Transform HTML through Vite's pipeline\n html = await server.transformIndexHtml(\"/fragments/preview/\", html);\n\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } catch (error) {\n console.error(\"[Fragments] Error serving preview frame:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Error loading preview frame\");\n }\n}\n\n/**\n * Parse JSON body from an HTTP request.\n */\nasync function parseJsonBody(req: any): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = \"\";\n req.on(\"data\", (chunk: Buffer) => {\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n try {\n resolve(JSON.parse(body));\n } catch (error) {\n reject(new Error(\"Invalid JSON body\"));\n }\n });\n req.on(\"error\", reject);\n });\n}\n\n/**\n * Load segments for render from BRAND.outFile or by building on-the-fly.\n * This avoids SSR issues with React components.\n */\nasync function loadSegmentsForRender(\n segmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n configDir: string\n): Promise<Array<{ path: string; segment: { meta: { name: string } } }>> {\n const { join } = await import(\"node:path\");\n\n // Try to read from the project directory\n const segmentsJsonPath = join(configDir, BRAND.outFile);\n\n try {\n const content = await readFile(segmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n segments: Record<string, { filePath: string; meta: { name: string } }>;\n };\n\n // Convert to the expected format if we have entries\n const segmentEntries = Object.values(data.segments || {});\n if (segmentEntries.length > 0) {\n return segmentEntries.map((segment) => ({\n path: segment.filePath,\n segment: { meta: { name: segment.meta.name } },\n }));\n }\n // Fall through to file-based extraction if outFile is empty\n } catch {\n // outFile doesn't exist or is invalid - fall through to file-based extraction\n }\n\n // Extract component names from file paths (fallback)\n return segmentFiles.map((f) => {\n let name: string;\n if (isStoryFile(f.relativePath)) {\n // Extract name from path like \"src/components/Button/Button.stories.tsx\"\n const match = f.relativePath.match(/\\/([^/]+)\\.stories\\./);\n name = match ? match[1] : f.relativePath;\n } else {\n // Extract name from path like \"src/components/Button/Button.segment.tsx\"\n const match = f.relativePath.match(/\\/([^/]+)\\.segment\\./);\n name = match ? match[1] : f.relativePath;\n }\n return {\n path: f.relativePath,\n segment: { meta: { name } },\n };\n });\n}\n\n/**\n * Serve the render HTML page for AI preview.\n */\nasync function serveRenderHTML(\n res: any,\n server: ViteDevServer,\n renderScript: string\n): Promise<void> {\n const viewerRoot = viewerAssetsRoot;\n\n try {\n // Read the render template\n let html = await readFile(\n resolve(viewerRoot, \"render-template.html\"),\n \"utf-8\"\n );\n\n // Inject the render script\n html = html.replace(\n \"<!-- RENDER_SCRIPT_PLACEHOLDER -->\",\n `<script type=\"module\">${renderScript}</script>`\n );\n\n // Transform HTML through Vite's pipeline to process imports\n // Use a unique URL to prevent Vite from caching the transformed HTML\n const uniqueUrl = `/fragments/__render__/${Date.now()}`;\n html = await server.transformIndexHtml(uniqueUrl, html);\n\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } catch (error) {\n console.error(\"[Fragments] Error serving render page:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Error loading render page\");\n }\n}\n\n/**\n * Capture a render using the shared browser pool from @fragments/service.\n * Uses a shared pool for efficiency - browser stays warm across requests.\n */\nasync function captureRender(\n url: string,\n viewport: { width: number; height: number }\n): Promise<string> {\n const { pool, bufferToBase64Url } = await getSharedRenderPool();\n\n const ctx = await pool.acquire();\n const page = await ctx.newPage();\n\n try {\n // Set viewport for this specific render\n await page.setViewportSize(viewport);\n\n // Navigate to the render page\n await page.goto(url, { waitUntil: \"networkidle\" });\n\n // Wait for render to complete (indicated by ready class or timeout)\n await page.waitForFunction(\n () => (window as any).__RENDER_READY__ === true,\n { timeout: 10000 }\n );\n\n // Check for render error\n const error = await page.evaluate(() => (window as any).__RENDER_ERROR__);\n if (error) {\n throw new Error(`Render error: ${error}`);\n }\n\n // Screenshot the render root element\n const element = await page.$(\"#render-root\");\n if (!element) {\n throw new Error(\"Render root element not found\");\n }\n\n const screenshot = await element.screenshot({ type: \"png\" });\n\n return bufferToBase64Url(screenshot);\n } finally {\n await page.close();\n pool.release(ctx);\n }\n}\n\n/**\n * Capture a render with optional computed styles extraction.\n * Uses the shared browser pool for efficiency.\n */\nasync function captureRenderWithStyles(\n url: string,\n viewport: { width: number; height: number },\n extractStyles: boolean\n): Promise<{ screenshot: string; computedStyles: Record<string, string> | null }> {\n const { pool, bufferToBase64Url } = await getSharedRenderPool();\n\n const ctx = await pool.acquire();\n const page = await ctx.newPage();\n\n try {\n // Set viewport for this specific render\n await page.setViewportSize(viewport);\n\n await page.goto(url, { waitUntil: \"networkidle\" });\n\n await page.waitForFunction(\n () => (window as any).__RENDER_READY__ === true,\n { timeout: 10000 }\n );\n\n const error = await page.evaluate(() => (window as any).__RENDER_ERROR__);\n if (error) {\n throw new Error(`Render error: ${error}`);\n }\n\n const element = await page.$(\"#render-root\");\n if (!element) {\n throw new Error(\"Render root element not found\");\n }\n\n // Extract computed styles if requested\n let computedStyles: Record<string, string> | null = null;\n if (extractStyles) {\n computedStyles = await page.evaluate(() => {\n const root = document.getElementById(\"render-root\");\n if (!root) return null;\n\n // Helper function to check if a color is visible (not transparent)\n const isVisibleColor = (color: string | undefined): boolean => {\n if (!color) return false;\n if (color === \"transparent\") return false;\n if (color === \"rgba(0, 0, 0, 0)\") return false;\n if (color.includes(\"rgba\") && color.includes(\", 0)\")) return false;\n return true;\n };\n\n // Helper to extract styles from an element\n const extractStylesFromElement = (el: HTMLElement): Record<string, string> => {\n const styles = window.getComputedStyle(el);\n const relevantProps = [\n \"backgroundColor\",\n \"borderColor\",\n \"borderWidth\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"lineHeight\",\n \"letterSpacing\",\n \"textAlign\",\n \"boxShadow\",\n \"padding\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"gap\",\n \"opacity\",\n \"width\",\n \"height\",\n ];\n\n const result: Record<string, string> = {};\n for (const prop of relevantProps) {\n const value = styles.getPropertyValue(\n prop.replace(/([A-Z])/g, \"-$1\").toLowerCase()\n );\n if (value) {\n result[prop] = value;\n }\n }\n return result;\n };\n\n // Strategy: Find the element with the most visible styles\n // Start by looking at all elements and score them based on visual presence\n const candidates = root.querySelectorAll(\"*\");\n let bestElement: HTMLElement | null = null;\n let bestScore = -1;\n\n for (const el of candidates) {\n const htmlEl = el as HTMLElement;\n const styles = window.getComputedStyle(htmlEl);\n let score = 0;\n\n // Score based on visual properties\n const bg = styles.backgroundColor;\n if (isVisibleColor(bg)) {\n score += 10; // Visible background is a strong signal\n }\n\n const border = styles.borderWidth;\n if (border && border !== \"0px\") {\n score += 3;\n }\n\n const boxShadow = styles.boxShadow;\n if (boxShadow && boxShadow !== \"none\") {\n score += 3;\n }\n\n // Bonus for being an interactive element\n const tagName = htmlEl.tagName.toLowerCase();\n if ([\"button\", \"a\", \"input\", \"select\", \"textarea\"].includes(tagName)) {\n score += 5;\n }\n\n // Bonus for having role=\"button\"\n if (htmlEl.getAttribute(\"role\") === \"button\") {\n score += 5;\n }\n\n // Penalty for being too small (likely not the main component)\n const rect = htmlEl.getBoundingClientRect();\n if (rect.width < 10 || rect.height < 10) {\n score -= 10;\n }\n\n // Penalty for very large elements (likely containers)\n if (rect.width > 500 || rect.height > 500) {\n score -= 3;\n }\n\n if (score > bestScore) {\n bestScore = score;\n bestElement = htmlEl;\n }\n }\n\n // If we still have no good element, fall back to first child\n if (!bestElement) {\n bestElement = root.firstElementChild as HTMLElement | null;\n }\n\n if (!bestElement) return null;\n\n const result = extractStylesFromElement(bestElement);\n\n // Normalize padding into shorthand if individual values exist\n if (result.paddingTop && result.paddingRight && result.paddingBottom && result.paddingLeft) {\n const t = result.paddingTop;\n const r = result.paddingRight;\n const b = result.paddingBottom;\n const l = result.paddingLeft;\n if (t === r && r === b && b === l) {\n result.padding = t;\n } else if (t === b && r === l) {\n result.padding = `${t} ${r}`;\n } else {\n result.padding = `${t} ${r} ${b} ${l}`;\n }\n }\n\n return result;\n });\n }\n\n const screenshot = await element.screenshot({ type: \"png\" });\n\n return {\n screenshot: bufferToBase64Url(screenshot),\n computedStyles,\n };\n } finally {\n await page.close();\n pool.release(ctx);\n }\n}\n\n/**\n * Load full segment data to get figma URL from segment or variant.\n * Uses BRAND.outFile to avoid SSR module loading issues with React CJS modules.\n */\nasync function loadFullSegmentForCompare(\n _server: ViteDevServer,\n _segmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n componentName: string,\n variantName?: string,\n configDir?: string\n): Promise<{ figmaUrl?: string } | null> {\n const { join } = await import(\"node:path\");\n\n // Try to read from outFile (avoids SSR issues with React CJS)\n const segmentsJsonPath = join(configDir || process.cwd(), BRAND.outFile);\n\n try {\n const content = await readFile(segmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n segments: Record<\n string,\n {\n meta: { name: string; figma?: string };\n variants?: Array<{ name: string; figma?: string }>;\n }\n >;\n };\n\n const segment = data.segments[componentName];\n if (!segment) {\n return null;\n }\n\n // Priority: variant.figma > meta.figma\n if (variantName && segment.variants) {\n const variant = segment.variants.find((v) => v.name === variantName);\n if (variant?.figma) {\n return { figmaUrl: variant.figma };\n }\n }\n\n // Fall back to meta.figma\n if (segment.meta.figma) {\n return { figmaUrl: segment.meta.figma };\n }\n\n return null;\n } catch {\n // outFile not found or invalid\n console.warn(\n `[${BRAND.name}] ${BRAND.outFile} not found, run '${BRAND.cliCommand} build' first`\n );\n return null;\n }\n}\n\n/**\n * Compare two base64 images and return diff result.\n */\nasync function compareImages(\n image1Base64: string,\n image2Base64: string,\n threshold: number\n): Promise<{\n matches: boolean;\n diffPercentage: number;\n diffImage?: string;\n changedRegions: Array<{\n x: number;\n y: number;\n width: number;\n height: number;\n }>;\n}> {\n const { DiffEngine, base64UrlToBuffer, bufferToBase64Url } = await import(\n \"../service/index.js\"\n );\n const { PNG } = await import(\"pngjs\");\n\n // Convert base64 to buffers\n const buffer1 = base64UrlToBuffer(image1Base64);\n const buffer2 = base64UrlToBuffer(image2Base64);\n\n // Parse PNGs to get dimensions\n const png1 = PNG.sync.read(buffer1);\n const png2 = PNG.sync.read(buffer2);\n\n // If dimensions don't match, resize the smaller one to match the larger\n let finalBuffer1 = buffer1;\n let finalBuffer2 = buffer2;\n\n if (png1.width !== png2.width || png1.height !== png2.height) {\n // Resize to the larger dimensions by padding the smaller image\n const targetWidth = Math.max(png1.width, png2.width);\n const targetHeight = Math.max(png1.height, png2.height);\n\n if (png1.width !== targetWidth || png1.height !== targetHeight) {\n finalBuffer1 = await resizePng(\n buffer1,\n png1.width,\n png1.height,\n targetWidth,\n targetHeight\n );\n }\n if (png2.width !== targetWidth || png2.height !== targetHeight) {\n finalBuffer2 = await resizePng(\n buffer2,\n png2.width,\n png2.height,\n targetWidth,\n targetHeight\n );\n }\n }\n\n // Create Screenshot-like objects for DiffEngine\n const screenshot1 = {\n data: finalBuffer1,\n hash: \"\",\n viewport: { width: png1.width, height: png1.height },\n capturedAt: new Date(),\n metadata: {\n component: \"\",\n variant: \"\",\n theme: \"light\" as const,\n renderTimeMs: 0,\n captureTimeMs: 0,\n },\n };\n\n const screenshot2 = {\n data: finalBuffer2,\n hash: \"\",\n viewport: { width: png2.width, height: png2.height },\n capturedAt: new Date(),\n metadata: {\n component: \"\",\n variant: \"\",\n theme: \"light\" as const,\n renderTimeMs: 0,\n captureTimeMs: 0,\n },\n };\n\n const diffEngine = new DiffEngine(threshold);\n const result = diffEngine.compare(screenshot1, screenshot2, { threshold });\n\n return {\n matches: result.matches,\n diffPercentage: result.diffPercentage,\n diffImage: result.diffImage\n ? bufferToBase64Url(result.diffImage)\n : undefined,\n changedRegions: result.changedRegions,\n };\n}\n\n/**\n * Resize a PNG by padding with transparent pixels to match target dimensions.\n */\nasync function resizePng(\n buffer: Buffer,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n): Promise<Buffer> {\n const { PNG } = await import(\"pngjs\");\n\n const srcPng = PNG.sync.read(buffer);\n const dstPng = new PNG({\n width: targetWidth,\n height: targetHeight,\n fill: true,\n });\n\n // Fill with transparent white\n for (let y = 0; y < targetHeight; y++) {\n for (let x = 0; x < targetWidth; x++) {\n const idx = (y * targetWidth + x) * 4;\n dstPng.data[idx] = 255; // R\n dstPng.data[idx + 1] = 255; // G\n dstPng.data[idx + 2] = 255; // B\n dstPng.data[idx + 3] = 255; // A (opaque white background)\n }\n }\n\n // Copy source image data\n for (let y = 0; y < srcHeight; y++) {\n for (let x = 0; x < srcWidth; x++) {\n const srcIdx = (y * srcWidth + x) * 4;\n const dstIdx = (y * targetWidth + x) * 4;\n dstPng.data[dstIdx] = srcPng.data[srcIdx];\n dstPng.data[dstIdx + 1] = srcPng.data[srcIdx + 1];\n dstPng.data[dstIdx + 2] = srcPng.data[srcIdx + 2];\n dstPng.data[dstIdx + 3] = srcPng.data[srcIdx + 3];\n }\n }\n\n return PNG.sync.write(dstPng);\n}\n","/**\n * Render utilities for AI preview endpoint.\n * Generates code to render design system components in isolation.\n */\n\nexport interface RenderRequest {\n /** Component name (e.g., \"Button\", \"Card\") */\n component: string;\n /** Props to pass to the component */\n props?: Record<string, unknown>;\n /** Viewport dimensions */\n viewport?: {\n width: number;\n height: number;\n };\n}\n\nexport interface SegmentInfo {\n name: string;\n path: string;\n}\n\n/**\n * Serialize a value to JavaScript code string.\n * Handles strings, numbers, booleans, null, undefined, arrays, and objects.\n */\nexport function serializeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"boolean\") return String(value);\n if (Array.isArray(value)) {\n return `[${value.map(serializeValue).join(\", \")}]`;\n }\n if (typeof value === \"object\") {\n const entries = Object.entries(value)\n .map(([k, v]) => `${JSON.stringify(k)}: ${serializeValue(v)}`)\n .join(\", \");\n return `{${entries}}`;\n }\n // Functions and other types - skip\n return \"undefined\";\n}\n\n/**\n * Serialize props object to JSX attribute string.\n * Example: { variant: \"primary\", disabled: true } -> variant=\"primary\" disabled={true}\n */\nexport function serializePropsToJsx(props: Record<string, unknown>): string {\n return Object.entries(props)\n .filter(([_, v]) => v !== undefined)\n .map(([key, value]) => {\n if (typeof value === \"string\") {\n return `${key}=${JSON.stringify(value)}`;\n }\n return `${key}={${serializeValue(value)}}`;\n })\n .join(\" \");\n}\n\n/**\n * Find a segment by component name.\n * Returns the segment info if found, null otherwise.\n */\nexport function findSegmentByName(\n componentName: string,\n segments: Array<{ path: string; segment: { meta: { name: string } } }>\n): SegmentInfo | null {\n const match = segments.find(\n (s) => s.segment.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!match) return null;\n\n return {\n name: match.segment.meta.name,\n path: match.path,\n };\n}\n\n/**\n * Get list of available component names from loaded segments.\n */\nexport function getAvailableComponents(\n segments: Array<{ segment: { meta: { name: string } } }>\n): string[] {\n return segments.map((s) => s.segment.meta.name).sort();\n}\n\n/**\n * Generate the render script that will be injected into the template.\n * This script imports the component and renders it with the given props.\n */\nexport function generateRenderScript(\n segmentPath: string,\n componentName: string,\n props: Record<string, unknown> = {}\n): string {\n const propsJsx = serializePropsToJsx(props);\n const propsString = propsJsx ? ` ${propsJsx}` : \"\";\n\n // Handle children prop specially - render as content between tags\n const hasChildren = \"children\" in props && props.children !== undefined;\n const childrenContent = hasChildren ? String(props.children) : \"\";\n const propsWithoutChildren = { ...props };\n delete propsWithoutChildren.children;\n const propsJsxNoChildren = serializePropsToJsx(propsWithoutChildren);\n const propsStringNoChildren = propsJsxNoChildren ? ` ${propsJsxNoChildren}` : \"\";\n\n return `\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\n// Import the segment to get the component\nasync function render() {\n const root = document.getElementById(\"render-root\");\n\n try {\n // Dynamic import of the segment file\n const segmentModule = await import(\"${segmentPath}\");\n const segment = segmentModule.default;\n\n if (!segment || !segment.component) {\n throw new Error(\"Segment does not export a component\");\n }\n\n const Component = segment.component;\n\n // Create React root and render\n const reactRoot = createRoot(root);\n ${\n hasChildren\n ? `reactRoot.render(React.createElement(Component, ${JSON.stringify(propsWithoutChildren)}, ${JSON.stringify(childrenContent)}));`\n : `reactRoot.render(React.createElement(Component, ${JSON.stringify(props)}));`\n }\n\n // Signal that rendering is complete\n // Wait a frame for React to flush\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n root.classList.add(\"ready\");\n window.__RENDER_READY__ = true;\n });\n });\n } catch (error) {\n console.error(\"Render error:\", error);\n root.innerHTML = \\`\n <div class=\"render-error\">\n <strong>Render Error</strong>\n <pre>\\${error.message}</pre>\n </div>\n \\`;\n root.classList.add(\"ready\");\n window.__RENDER_READY__ = true;\n window.__RENDER_ERROR__ = error.message;\n }\n}\n\nrender();\n`;\n}\n\n/**\n * Generate a virtual module ID for a render request.\n * This creates a unique ID that Vite can resolve.\n */\nexport function generateRenderModuleId(componentName: string, requestId: string): string {\n return `virtual:segments-render-${componentName}-${requestId}`;\n}\n","/**\n * Style comparison utilities for comparing Figma design properties\n * with rendered component computed styles.\n */\n\n/**\n * Style diff result for a single CSS property\n */\nexport interface StyleDiffItem {\n /** CSS property name */\n property: string;\n /** Expected value from Figma */\n figma: string;\n /** Actual value from rendered component */\n rendered: string;\n /** Whether values match (within tolerance) */\n match: boolean;\n}\n\n/**\n * Result of comparing styles\n */\nexport interface StyleComparisonResult {\n /** Whether all styles match */\n match: boolean;\n /** Individual property comparisons */\n properties: StyleDiffItem[];\n /** CSS properties from Figma design */\n figmaStyles: Record<string, string>;\n /** Computed CSS properties from rendered component */\n renderedStyles: Record<string, string>;\n}\n\n/**\n * Compare Figma CSS properties with rendered computed styles.\n */\nexport function compareStyles(\n figmaStyles: Record<string, string | undefined>,\n renderedStyles: Record<string, string>\n): StyleComparisonResult {\n const properties: StyleDiffItem[] = [];\n const cleanFigmaStyles: Record<string, string> = {};\n\n // Properties to compare\n const propsToCompare = [\n \"backgroundColor\",\n \"borderColor\",\n \"borderWidth\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"lineHeight\",\n \"letterSpacing\",\n \"textAlign\",\n \"boxShadow\",\n \"padding\",\n \"gap\",\n \"opacity\",\n ];\n\n for (const prop of propsToCompare) {\n const figmaValue = figmaStyles[prop];\n const renderedValue = renderedStyles[prop];\n\n if (figmaValue !== undefined) {\n cleanFigmaStyles[prop] = figmaValue;\n\n const match = compareStyleValue(prop, figmaValue, renderedValue || \"\");\n properties.push({\n property: prop,\n figma: figmaValue,\n rendered: renderedValue || \"(not set)\",\n match,\n });\n }\n }\n\n const allMatch = properties.every((p) => p.match);\n\n return {\n match: allMatch,\n properties,\n figmaStyles: cleanFigmaStyles,\n renderedStyles,\n };\n}\n\n/**\n * Compare a single style value with tolerance for color and numeric differences.\n */\nexport function compareStyleValue(\n prop: string,\n figma: string,\n rendered: string\n): boolean {\n // Normalize values for comparison\n const normalizedFigma = normalizeStyleValue(prop, figma);\n const normalizedRendered = normalizeStyleValue(prop, rendered);\n\n // Direct match\n if (normalizedFigma === normalizedRendered) {\n return true;\n }\n\n // Color comparison with tolerance\n if (prop === \"backgroundColor\" || prop === \"borderColor\") {\n return compareColors(normalizedFigma, normalizedRendered, 5);\n }\n\n // Numeric comparison with tolerance (for pixels)\n if (\n [\"borderWidth\", \"borderRadius\", \"fontSize\", \"padding\", \"gap\"].includes(prop)\n ) {\n return compareNumericValues(normalizedFigma, normalizedRendered, 1);\n }\n\n return false;\n}\n\n/**\n * Normalize a style value for comparison.\n */\nexport function normalizeStyleValue(prop: string, value: string): string {\n // Remove extra whitespace\n let normalized = value.trim().replace(/\\s+/g, \" \");\n\n // Normalize \"none\" shadow to empty\n if (prop === \"boxShadow\" && normalized === \"none\") {\n normalized = \"\";\n }\n\n // Normalize rgba(0, 0, 0, 0) to \"transparent\"\n if (normalized.match(/rgba\\(\\s*0\\s*,\\s*0\\s*,\\s*0\\s*,\\s*0\\s*\\)/)) {\n normalized = \"transparent\";\n }\n\n return normalized;\n}\n\n/**\n * Compare two color values with tolerance.\n */\nexport function compareColors(\n color1: string,\n color2: string,\n tolerance: number\n): boolean {\n const rgb1 = parseColor(color1);\n const rgb2 = parseColor(color2);\n\n if (!rgb1 || !rgb2) {\n return color1 === color2;\n }\n\n return (\n Math.abs(rgb1.r - rgb2.r) <= tolerance &&\n Math.abs(rgb1.g - rgb2.g) <= tolerance &&\n Math.abs(rgb1.b - rgb2.b) <= tolerance &&\n Math.abs((rgb1.a ?? 1) - (rgb2.a ?? 1)) <= 0.05\n );\n}\n\n/**\n * Parse a color string to RGB values.\n */\nexport function parseColor(\n color: string\n): { r: number; g: number; b: number; a?: number } | null {\n // Handle hex colors\n const hexMatch = color.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);\n if (hexMatch) {\n return {\n r: parseInt(hexMatch[1], 16),\n g: parseInt(hexMatch[2], 16),\n b: parseInt(hexMatch[3], 16),\n };\n }\n\n // Handle rgb/rgba\n const rgbaMatch = color.match(\n /rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+))?\\s*\\)/\n );\n if (rgbaMatch) {\n return {\n r: parseInt(rgbaMatch[1], 10),\n g: parseInt(rgbaMatch[2], 10),\n b: parseInt(rgbaMatch[3], 10),\n a: rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1,\n };\n }\n\n return null;\n}\n\n/**\n * Compare numeric values (e.g., \"10px\" vs \"11px\") with tolerance.\n */\nexport function compareNumericValues(\n value1: string,\n value2: string,\n tolerance: number\n): boolean {\n const num1 = parseFloat(value1);\n const num2 = parseFloat(value2);\n\n if (isNaN(num1) || isNaN(num2)) {\n return value1 === value2;\n }\n\n return Math.abs(num1 - num2) <= tolerance;\n}\n\n// ----- Enhanced Token-Aware Style Comparison -----\n\nimport type {\n EnhancedStyleDiffItem,\n TokenFix,\n TokenUsageSummary,\n DesignToken,\n} from \"../core/index.js\";\n\n/**\n * Enhanced style diff result with token information\n */\nexport interface EnhancedStyleComparisonResult extends StyleComparisonResult {\n /** Individual property comparisons with token info */\n properties: EnhancedStyleDiffItem[];\n /** Token usage summary */\n tokenSummary?: TokenUsageSummary;\n}\n\n/**\n * Token registry interface for style comparison\n * (subset of TokenRegistryManager methods needed here)\n */\nexport interface TokenLookup {\n findByValue(value: string, theme?: string): string[];\n getToken(name: string): DesignToken | undefined;\n calculateUsageSummary(\n styleDiffs: Array<{\n property: string;\n figma: string;\n rendered: string;\n match: boolean;\n }>,\n theme?: string\n ): TokenUsageSummary;\n}\n\n/**\n * Compare styles with token awareness.\n *\n * This enhanced version:\n * 1. Performs normal style comparison\n * 2. Identifies which values match design tokens\n * 3. Flags hardcoded values that should use tokens\n * 4. Generates fix suggestions\n */\nexport function compareStylesWithTokens(\n figmaStyles: Record<string, string | undefined>,\n renderedStyles: Record<string, string>,\n tokenLookup?: TokenLookup,\n theme = \"default\"\n): EnhancedStyleComparisonResult {\n const properties: EnhancedStyleDiffItem[] = [];\n const cleanFigmaStyles: Record<string, string> = {};\n\n // Properties to compare\n const propsToCompare = [\n \"backgroundColor\",\n \"borderColor\",\n \"borderWidth\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"lineHeight\",\n \"letterSpacing\",\n \"textAlign\",\n \"boxShadow\",\n \"padding\",\n \"gap\",\n \"opacity\",\n \"color\",\n ];\n\n for (const prop of propsToCompare) {\n const figmaValue = figmaStyles[prop];\n const renderedValue = renderedStyles[prop];\n\n if (figmaValue !== undefined) {\n cleanFigmaStyles[prop] = figmaValue;\n\n const match = compareStyleValue(prop, figmaValue, renderedValue || \"\");\n\n // Build enhanced diff item\n const item: EnhancedStyleDiffItem = {\n property: prop,\n figma: figmaValue,\n rendered: renderedValue || \"(not set)\",\n match,\n isHardcoded: false,\n };\n\n // Add token information if registry is available\n if (tokenLookup) {\n const figmaTokens = tokenLookup.findByValue(figmaValue, theme);\n const renderedTokens = renderedValue\n ? tokenLookup.findByValue(renderedValue, theme)\n : [];\n\n if (figmaTokens.length > 0) {\n item.figmaToken = figmaTokens[0];\n }\n\n if (renderedTokens.length > 0) {\n item.renderedToken = renderedTokens[0];\n }\n\n // Determine if this is a hardcoded value\n // Hardcoded = Figma matches a token, but rendered doesn't use a token\n item.isHardcoded = !!item.figmaToken && !item.renderedToken;\n\n // Generate fix suggestion if hardcoded\n if (item.isHardcoded && item.figmaToken) {\n const token = tokenLookup.getToken(item.figmaToken);\n if (token) {\n const cssProperty = toCssProperty(prop);\n item.suggestedFix = {\n tokenName: item.figmaToken,\n tokenValue: token.resolvedValue,\n codeFix: `${cssProperty}: var(${item.figmaToken});`,\n confidence: 0.9,\n reason: `Figma uses token ${item.figmaToken} (${token.resolvedValue}). Replace hardcoded value with token for consistency.`,\n };\n }\n }\n }\n\n properties.push(item);\n }\n }\n\n const allMatch = properties.every((p) => p.match);\n\n // Calculate token summary if registry available\n let tokenSummary: TokenUsageSummary | undefined;\n if (tokenLookup) {\n tokenSummary = tokenLookup.calculateUsageSummary(\n properties.map((p) => ({\n property: p.property,\n figma: p.figma,\n rendered: p.rendered,\n match: p.match,\n })),\n theme\n );\n }\n\n return {\n match: allMatch,\n properties,\n figmaStyles: cleanFigmaStyles,\n renderedStyles,\n tokenSummary,\n };\n}\n\n/**\n * Convert camelCase to kebab-case CSS property\n */\nfunction toCssProperty(prop: string): string {\n return prop.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n}\n\n/**\n * Format token summary for display\n */\nexport function formatTokenSummary(summary: TokenUsageSummary): string {\n const lines: string[] = [];\n\n lines.push(`Token Compliance: ${summary.compliancePercent}%`);\n lines.push(\n `${summary.usingTokens}/${summary.totalProperties} properties using tokens`\n );\n\n if (summary.hardcoded > 0) {\n lines.push(`${summary.hardcoded} hardcoded value(s) detected`);\n }\n\n if (summary.implicitMatches > 0) {\n lines.push(`${summary.implicitMatches} implicit match(es)`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Get status badge for token compliance\n */\nexport function getComplianceBadge(\n compliancePercent: number\n): { label: string; color: string } {\n if (compliancePercent >= 100) {\n return { label: \"Excellent\", color: \"green\" };\n } else if (compliancePercent >= 80) {\n return { label: \"Good\", color: \"blue\" };\n } else if (compliancePercent >= 50) {\n return { label: \"Fair\", color: \"yellow\" };\n } else {\n return { label: \"Poor\", color: \"red\" };\n }\n}\n"],"mappings":"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","names":["resolve","dirname","fileURLToPath","config","join","BRAND","server","viewerRoot","resolve","result","__dirname","dirname","fileURLToPath","resolve","dirname"]}
@@ -1,59 +0,0 @@
1
- /**
2
- * Segment Loader
3
- *
4
- * Utilities for loading segment data from the dev server or segments.json
5
- */
6
-
7
- import type { SegmentInfo } from './types.js';
8
- import { DevServerClient, createDevServerClient } from './dev-server-client.js';
9
-
10
- /**
11
- * Options for loading segments
12
- */
13
- export interface LoadSegmentsOptions {
14
- /** Dev server port */
15
- port?: number | string;
16
- /** Filter by component name */
17
- component?: string;
18
- }
19
-
20
- /**
21
- * Load segments from the dev server
22
- */
23
- export async function loadSegments(options: LoadSegmentsOptions = {}): Promise<SegmentInfo[]> {
24
- const { port = 6006, component } = options;
25
-
26
- const client = createDevServerClient(port);
27
- let segments = await client.getSegments();
28
-
29
- // Filter by component if specified
30
- if (component) {
31
- segments = segments.filter(
32
- s => s.name.toLowerCase() === component.toLowerCase()
33
- );
34
- }
35
-
36
- return segments;
37
- }
38
-
39
- /**
40
- * Load a single segment by name
41
- */
42
- export async function loadSegment(
43
- name: string,
44
- options: { port?: number | string } = {}
45
- ): Promise<SegmentInfo | null> {
46
- const segments = await loadSegments({ ...options, component: name });
47
- return segments.length > 0 ? segments[0] : null;
48
- }
49
-
50
- /**
51
- * Check if a segment exists
52
- */
53
- export async function segmentExists(
54
- name: string,
55
- options: { port?: number | string } = {}
56
- ): Promise<boolean> {
57
- const segment = await loadSegment(name, options);
58
- return segment !== null;
59
- }