@fragments-sdk/cli 0.7.2 → 0.7.3

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 (64) hide show
  1. package/dist/bin.js +20 -16
  2. package/dist/bin.js.map +1 -1
  3. package/dist/chunk-D34Q6A7S.js +266 -0
  4. package/dist/chunk-D34Q6A7S.js.map +1 -0
  5. package/dist/chunk-EKLMXTWU.js +80 -0
  6. package/dist/chunk-EKLMXTWU.js.map +1 -0
  7. package/dist/{chunk-GHYYFAQN.js → chunk-P33AKQJW.js} +1 -76
  8. package/dist/chunk-P33AKQJW.js.map +1 -0
  9. package/dist/{chunk-7KUSBMI4.js → chunk-QPY4DUFB.js} +174 -45
  10. package/dist/chunk-QPY4DUFB.js.map +1 -0
  11. package/dist/{chunk-DH4ETVSM.js → chunk-R2YH7NLN.js} +9 -7
  12. package/dist/{chunk-DH4ETVSM.js.map → chunk-R2YH7NLN.js.map} +1 -1
  13. package/dist/{chunk-3T6QL7IY.js → chunk-R6IZZSE7.js} +23 -275
  14. package/dist/chunk-R6IZZSE7.js.map +1 -0
  15. package/dist/{chunk-DQHWLAUV.js → chunk-TOIE7VXF.js} +2 -2
  16. package/dist/{chunk-OOGTG5FM.js → chunk-UXLGIGSX.js} +56 -2
  17. package/dist/chunk-UXLGIGSX.js.map +1 -0
  18. package/dist/{chunk-GKX2HPZ6.js → chunk-YMPGYEWK.js} +9 -3
  19. package/dist/chunk-YMPGYEWK.js.map +1 -0
  20. package/dist/chunk-Z7EY4VHE.js +50 -0
  21. package/dist/{core-UQXZTBFZ.js → core-3NMNCLFW.js} +8 -5
  22. package/dist/discovery-AKGA6CJD.js +28 -0
  23. package/dist/{generate-GP6ZLAQB.js → generate-JAUEHKK7.js} +7 -4
  24. package/dist/{generate-GP6ZLAQB.js.map → generate-JAUEHKK7.js.map} +1 -1
  25. package/dist/index.js +15 -11
  26. package/dist/index.js.map +1 -1
  27. package/dist/{init-W72WBSU2.js → init-DZQOT54X.js} +6 -4
  28. package/dist/{init-W72WBSU2.js.map → init-DZQOT54X.js.map} +1 -1
  29. package/dist/mcp-bin.js +5 -3
  30. package/dist/mcp-bin.js.map +1 -1
  31. package/dist/sass.node-4XJK6YBF.js +130708 -0
  32. package/dist/sass.node-4XJK6YBF.js.map +1 -0
  33. package/dist/scan-OJRCVKK2.js +15 -0
  34. package/dist/{service-PVGTYUKX.js → service-CFFBHW4X.js} +6 -4
  35. package/dist/service-CFFBHW4X.js.map +1 -0
  36. package/dist/{static-viewer-KILKIVN7.js → static-viewer-VA2JXSCX.js} +6 -4
  37. package/dist/static-viewer-VA2JXSCX.js.map +1 -0
  38. package/dist/{test-3YRYQRGV.js → test-O7DZNKDC.js} +8 -4
  39. package/dist/{test-3YRYQRGV.js.map → test-O7DZNKDC.js.map} +1 -1
  40. package/dist/{tokens-IXSQHPQK.js → tokens-N7THFD6J.js} +10 -7
  41. package/dist/{tokens-IXSQHPQK.js.map → tokens-N7THFD6J.js.map} +1 -1
  42. package/dist/{viewer-K42REJU2.js → viewer-QTR7QJMM.js} +390 -25
  43. package/dist/viewer-QTR7QJMM.js.map +1 -0
  44. package/package.json +1 -1
  45. package/src/build.ts +57 -5
  46. package/src/core/__tests__/token-resolver.test.ts +82 -0
  47. package/src/core/token-parser.ts +102 -0
  48. package/src/core/token-resolver.ts +155 -0
  49. package/src/service/__tests__/patch-generator.test.ts +2 -2
  50. package/src/service/patch-generator.ts +8 -1
  51. package/src/viewer/render-utils.ts +141 -0
  52. package/src/viewer/vite-plugin.ts +381 -23
  53. package/dist/chunk-3T6QL7IY.js.map +0 -1
  54. package/dist/chunk-7KUSBMI4.js.map +0 -1
  55. package/dist/chunk-GHYYFAQN.js.map +0 -1
  56. package/dist/chunk-GKX2HPZ6.js.map +0 -1
  57. package/dist/chunk-OOGTG5FM.js.map +0 -1
  58. package/dist/scan-V54HWRDY.js +0 -12
  59. package/dist/viewer-K42REJU2.js.map +0 -1
  60. /package/dist/{chunk-DQHWLAUV.js.map → chunk-TOIE7VXF.js.map} +0 -0
  61. /package/dist/{core-UQXZTBFZ.js.map → chunk-Z7EY4VHE.js.map} +0 -0
  62. /package/dist/{scan-V54HWRDY.js.map → core-3NMNCLFW.js.map} +0 -0
  63. /package/dist/{service-PVGTYUKX.js.map → discovery-AKGA6CJD.js.map} +0 -0
  64. /package/dist/{static-viewer-KILKIVN7.js.map → scan-OJRCVKK2.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/defineFragment.ts","../src/core/storyAdapter.ts","../src/core/storybook-csf.ts","../src/core/context.ts","../src/core/figma.ts","../src/core/token-parser.ts","../src/core/composition.ts"],"sourcesContent":["import type { FragmentDefinition, CompiledFragment, FragmentComponent, BlockDefinition, CompiledBlock } from './types.js';\nimport { fragmentDefinitionSchema, blockDefinitionSchema } from './schema.js';\n\n/**\n * Define a fragment for a component.\n *\n * This is the main API for creating fragment documentation.\n * It provides runtime validation and type safety.\n *\n * @example\n * ```tsx\n * import { defineFragment } from '@fragments/core';\n * import { Button } from './Button';\n *\n * export default defineFragment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * },\n * usage: {\n * when: ['User needs to trigger an action'],\n * whenNot: ['Navigation without side effects'],\n * },\n * props: {\n * variant: {\n * type: 'enum',\n * values: ['primary', 'secondary'],\n * default: 'primary',\n * description: 'Visual style',\n * },\n * },\n * variants: [\n * {\n * name: 'Default',\n * description: 'Default button',\n * render: () => <Button>Click me</Button>,\n * },\n * ],\n * });\n * ```\n */\nexport function defineFragment<TProps>(\n definition: FragmentDefinition<TProps>\n): FragmentDefinition<TProps> {\n // Validate at runtime in development\n if (process.env.NODE_ENV !== 'production') {\n const result = fragmentDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid fragment definition for \"${definition.meta?.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * Compile a fragment definition to JSON-serializable format.\n * Used for generating fragments.json for AI consumption.\n */\nexport function compileFragment(\n definition: FragmentDefinition,\n filePath: string\n): CompiledFragment {\n return {\n filePath,\n meta: definition.meta,\n usage: definition.usage,\n props: definition.props,\n relations: definition.relations,\n variants: definition.variants.map((v) => ({\n name: v.name,\n description: v.description,\n code: v.code,\n figma: v.figma,\n })),\n contract: definition.contract,\n _generated: definition._generated,\n };\n}\n\n/**\n * Define a composition block.\n *\n * Blocks are pure data describing how design system components\n * wire together for common use cases.\n */\nexport function defineBlock(definition: BlockDefinition): BlockDefinition {\n if (process.env.NODE_ENV !== 'production') {\n const result = blockDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid block definition for \"${definition.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * @deprecated Use defineBlock instead\n */\nexport const defineRecipe = defineBlock;\n\n/**\n * Compile a block definition to JSON-serializable format.\n */\nexport function compileBlock(\n definition: BlockDefinition,\n filePath: string\n): CompiledBlock {\n return {\n filePath,\n name: definition.name,\n description: definition.description,\n category: definition.category,\n components: definition.components,\n code: definition.code,\n tags: definition.tags,\n };\n}\n\n/**\n * @deprecated Use compileBlock instead\n */\nexport const compileRecipe = compileBlock;\n\n/**\n * Type helper for extracting props type from a component\n */\nexport type InferProps<T> = T extends FragmentComponent<infer P> ? P : never;\n","/**\n * Runtime adapter for converting Storybook CSF modules to Fragment definitions.\n *\n * This operates on IMPORTED modules at runtime, not source code parsing.\n * By leveraging Vite's module system, we get 100% accurate render functions\n * without any regex or AST parsing complexity.\n *\n * Supports Storybook 8.x with both CSF2 (Template.bind) and CSF3 (object stories).\n */\n\nimport { createElement, type ComponentType, type ReactNode } from \"react\";\nimport { toId, storyNameFromExport, isExportStory } from \"./storybook-csf.js\";\nimport type {\n FragmentDefinition,\n FragmentMeta,\n FragmentUsage,\n PropDefinition,\n FragmentVariant,\n ControlType,\n VariantLoader,\n PlayFunction,\n PlayFunctionContext,\n VariantRenderOptions,\n} from \"./types.js\";\n\n// Re-export @storybook/csf utilities for use in other modules\nexport { toId, storyNameFromExport, isExportStory };\n\n/**\n * Storybook decorator function signature\n */\nexport type Decorator = (\n Story: () => ReactNode,\n context: StoryContext\n) => ReactNode;\n\n/**\n * Storybook loader function signature\n */\nexport type Loader = (context: StoryContext) => Promise<Record<string, unknown>>;\n\n/**\n * Storybook play function signature (internal, extends StoryContext)\n */\ntype StorybookPlayFunction = (context: StorybookPlayFunctionContext) => Promise<void>;\n\n/**\n * Context passed to Storybook play functions (extends StoryContext for compatibility)\n */\ninterface StorybookPlayFunctionContext extends StoryContext {\n canvasElement: HTMLElement;\n step: (name: string, fn: () => Promise<void>) => Promise<void>;\n}\n\n/**\n * Context passed to decorators and render functions\n */\nexport interface StoryContext {\n args: Record<string, unknown>;\n argTypes: Record<string, StoryArgType>;\n globals: Record<string, unknown>;\n parameters: Record<string, unknown>;\n id: string;\n kind: string;\n name: string;\n story: string;\n viewMode: \"story\" | \"docs\";\n loaded: Record<string, unknown>;\n abortSignal: AbortSignal;\n componentId: string;\n title: string;\n}\n\n/**\n * Storybook Meta (default export)\n */\nexport interface StoryMeta {\n title?: string;\n component?: ComponentType<unknown>;\n subcomponents?: Record<string, ComponentType<unknown>>;\n tags?: string[];\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n component?: string;\n };\n };\n };\n argTypes?: Record<string, StoryArgType>;\n args?: Record<string, unknown>;\n decorators?: Decorator[];\n loaders?: Loader[];\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n // Story filtering\n includeStories?: string[] | RegExp;\n excludeStories?: string[] | RegExp;\n}\n\n/**\n * Storybook argType definition\n */\nexport interface StoryArgType {\n control?:\n | string\n | false\n | { type: string; min?: number; max?: number; step?: number; presetColors?: string[] };\n options?: string[];\n description?: string;\n table?: {\n defaultValue?: { summary: string };\n type?: { summary: string };\n category?: string;\n subcategory?: string;\n disable?: boolean;\n };\n type?: { name: string; required?: boolean };\n name?: string;\n defaultValue?: unknown;\n if?: { arg?: string; exists?: boolean };\n mapping?: Record<string, unknown>;\n action?: string;\n}\n\n/**\n * Storybook Story export (CSF3)\n */\nexport interface Story {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n story?: string;\n };\n };\n };\n name?: string;\n storyName?: string; // Legacy CSF2\n tags?: string[];\n}\n\n/**\n * CSF2 story function (from Template.bind({})) with args attached\n */\nexport type CSF2Story = ((args: Record<string, unknown>) => ReactNode) & {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown>;\n storyName?: string;\n};\n\n/**\n * A complete Storybook module with default meta and named story exports\n */\nexport interface StoryModule {\n default: StoryMeta;\n [exportName: string]: Story | CSF2Story | StoryMeta | unknown;\n}\n\n/**\n * Global configuration from preview.tsx\n */\nexport interface PreviewConfig {\n decorators?: Decorator[];\n parameters?: Record<string, unknown>;\n globalTypes?: Record<string, unknown>;\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n loaders?: Loader[];\n}\n\n// Store for global preview config (set by previewLoader)\nlet globalPreviewConfig: PreviewConfig = {};\n\n/**\n * Set the global preview configuration loaded from .storybook/preview.tsx\n */\nexport function setPreviewConfig(config: PreviewConfig): void {\n globalPreviewConfig = config;\n}\n\n/**\n * Get the current global preview configuration\n */\nexport function getPreviewConfig(): PreviewConfig {\n return globalPreviewConfig;\n}\n\n/**\n * Convert a Storybook module to a Fragment definition at runtime.\n *\n * @param storyModule - The imported Storybook module\n * @param filePath - File path for metadata extraction\n * @returns A complete FragmentDefinition ready for the viewer\n */\nexport function storyModuleToFragment(\n storyModule: StoryModule,\n filePath: string\n): FragmentDefinition | null {\n const meta = storyModule.default;\n const component = meta.component;\n\n // Stories without a component (e.g., documentation pages, icon galleries) are skipped\n if (!component) {\n return null;\n }\n\n const componentName = extractComponentName(meta, filePath);\n const category = extractCategory(meta.title);\n const props = convertArgTypes(meta.argTypes ?? {}, globalPreviewConfig.argTypes);\n const variants = extractVariants(storyModule, component, meta);\n\n // Extract Figma URL from parameters.design.url (storybook-addon-designs) or parameters.figma\n const figmaUrl = extractFigmaUrl(meta.parameters);\n\n const fragmentMeta: FragmentMeta = {\n name: componentName,\n description:\n meta.parameters?.docs?.description?.component ??\n `${componentName} component`,\n category,\n tags: meta.tags?.filter((t) => t !== \"autodocs\"),\n status: \"stable\",\n figma: figmaUrl,\n };\n\n const usage: FragmentUsage = {\n when: [`Use ${componentName} for its intended purpose`],\n whenNot: [\"When a more specific component is available\"],\n };\n\n return {\n component,\n meta: fragmentMeta,\n usage,\n props,\n variants,\n };\n}\n\n/**\n * Extract component name from meta or file path\n */\nfunction extractComponentName(meta: StoryMeta, filePath: string): string {\n // Try title (last fragment of path like \"Components/Forms/Button\" -> \"Button\")\n if (meta.title) {\n const parts = meta.title.split(\"/\");\n return parts[parts.length - 1];\n }\n\n // Try component displayName\n if (meta.component?.displayName) {\n return meta.component.displayName;\n }\n\n // Try component name\n if (meta.component?.name && meta.component.name !== \"Component\") {\n return meta.component.name;\n }\n\n // Fallback: extract from file path\n const match = filePath.match(/([^/\\\\]+)\\.stories\\.(tsx?|jsx?)$/);\n return match?.[1] ?? \"Unknown\";\n}\n\n/**\n * Extract category from Storybook title path\n */\nfunction extractCategory(title?: string): string {\n if (!title) return \"general\";\n\n const parts = title.split(\"/\");\n // \"Components/Forms/Button\" -> \"forms\" (need at least 3 parts for a subcategory)\n if (parts.length >= 3) {\n return parts[parts.length - 2].toLowerCase();\n }\n // \"Components/Button\" -> \"general\" (no subcategory specified)\n return \"general\";\n}\n\n/**\n * Extract Figma URL from Storybook parameters\n * Supports storybook-addon-designs format and custom figma parameter\n */\nfunction extractFigmaUrl(parameters?: Record<string, unknown>): string | undefined {\n if (!parameters) return undefined;\n\n // Try storybook-addon-designs format: parameters.design.url\n const design = parameters.design as { url?: string; type?: string } | undefined;\n if (design?.url && typeof design.url === \"string\") {\n return design.url;\n }\n\n // Try custom figma parameter: parameters.figma\n if (typeof parameters.figma === \"string\") {\n return parameters.figma;\n }\n\n return undefined;\n}\n\n/**\n * Convert Storybook argTypes to Fragment props\n * Merges global argTypes from preview config with meta argTypes\n */\nfunction convertArgTypes(\n argTypes: Record<string, StoryArgType>,\n globalArgTypes?: Record<string, StoryArgType>\n): Record<string, PropDefinition> {\n const props: Record<string, PropDefinition> = {};\n\n // Merge global and meta argTypes (meta takes precedence)\n const mergedArgTypes = { ...globalArgTypes, ...argTypes };\n\n for (const [name, argType] of Object.entries(mergedArgTypes)) {\n // Skip disabled argTypes\n if (argType.table?.disable) continue;\n // Skip action-only argTypes (no control)\n if (argType.control === false && argType.action) continue;\n\n // Extract control type and options\n const { controlType, controlOptions } = extractControlInfo(argType);\n\n props[name] = {\n type: inferPropType(argType),\n description: argType.description ?? `${name} prop`,\n ...(argType.options && { values: argType.options }),\n ...(argType.table?.defaultValue && {\n default: argType.table.defaultValue.summary,\n }),\n ...(argType.defaultValue !== undefined && {\n default: argType.defaultValue,\n }),\n ...(argType.type?.required && { required: true }),\n ...(controlType && { controlType }),\n ...(controlOptions && Object.keys(controlOptions).length > 0 && { controlOptions }),\n };\n }\n\n return props;\n}\n\n/**\n * Extract control type and options from a Storybook argType\n */\nfunction extractControlInfo(argType: StoryArgType): {\n controlType?: ControlType;\n controlOptions?: PropDefinition[\"controlOptions\"];\n} {\n // Handle no control or explicitly disabled control\n if (argType.control === undefined || argType.control === false) {\n return {};\n }\n\n const control = typeof argType.control === \"string\"\n ? { type: argType.control }\n : argType.control;\n\n // Map control type string to ControlType\n const validControlTypes: ControlType[] = [\n \"text\", \"number\", \"range\", \"boolean\", \"select\", \"multi-select\",\n \"radio\", \"inline-radio\", \"check\", \"inline-check\", \"object\", \"file\", \"color\", \"date\"\n ];\n\n const controlType = validControlTypes.includes(control.type as ControlType)\n ? (control.type as ControlType)\n : undefined;\n\n // Extract control options for controls that need them\n const controlOptions: PropDefinition[\"controlOptions\"] = {};\n\n if (control.min !== undefined) controlOptions.min = control.min;\n if (control.max !== undefined) controlOptions.max = control.max;\n if (control.step !== undefined) controlOptions.step = control.step;\n if (control.presetColors) controlOptions.presetColors = control.presetColors;\n\n return {\n controlType,\n controlOptions: Object.keys(controlOptions).length > 0 ? controlOptions : undefined,\n };\n}\n\n/**\n * Infer prop type from Storybook control/type\n * Handles all Storybook 8.x control types\n */\nfunction inferPropType(argType: StoryArgType): PropDefinition[\"type\"] {\n // Action argType → function\n if (argType.action) return \"function\";\n\n // If has options, it's an enum\n if (argType.options?.length) return \"enum\";\n\n // Check explicit type\n if (argType.type?.name) {\n const typeMap: Record<string, PropDefinition[\"type\"]> = {\n string: \"string\",\n number: \"number\",\n boolean: \"boolean\",\n object: \"object\",\n array: \"array\",\n function: \"function\",\n };\n const mapped = typeMap[argType.type.name];\n if (mapped) return mapped;\n }\n\n // Check control type\n const control =\n typeof argType.control === \"string\"\n ? argType.control\n : argType.control\n ? argType.control.type\n : undefined;\n\n if (control) {\n const controlMap: Record<string, PropDefinition[\"type\"]> = {\n // Text controls\n text: \"string\",\n\n // Number controls\n number: \"number\",\n range: \"number\",\n\n // Boolean controls\n boolean: \"boolean\",\n check: \"boolean\",\n \"inline-check\": \"boolean\",\n\n // Enum/selection controls\n select: \"enum\",\n \"multi-select\": \"enum\",\n radio: \"enum\",\n \"inline-radio\": \"enum\",\n\n // Object controls\n object: \"object\",\n file: \"object\",\n\n // Special string controls\n color: \"string\",\n date: \"string\",\n };\n const mapped = controlMap[control];\n if (mapped) return mapped;\n }\n\n return \"string\";\n}\n\n/**\n * Check if a value looks like a Storybook story\n * Handles both CSF 3 (objects) and CSF 2 (functions from Template.bind({}))\n */\nfunction isStory(value: unknown): value is Story | CSF2Story {\n // CSF 3: Story is an object with args/render/play\n if (typeof value === \"object\" && value !== null) {\n const obj = value as Record<string, unknown>;\n if (\"args\" in obj || \"render\" in obj || \"play\" in obj) return true;\n }\n\n // CSF 2: Story is a function (from Template.bind({})) with args attached\n if (typeof value === \"function\") {\n const fn = value as ((...args: unknown[]) => unknown) & { args?: unknown };\n if (\"args\" in fn) return true;\n }\n\n return false;\n}\n\n/**\n * Extract variants from story exports using @storybook/csf utilities\n */\nfunction extractVariants(\n storyModule: StoryModule,\n component: ComponentType<unknown>,\n meta: StoryMeta\n): FragmentVariant[] {\n const variants: FragmentVariant[] = [];\n\n for (const [exportName, exportValue] of Object.entries(storyModule)) {\n // Skip default export\n if (exportName === \"default\") continue;\n\n // Use isExportStory to filter based on includeStories/excludeStories\n if (!isExportStory(exportName, meta)) continue;\n\n // Check if it's a story\n if (!isStory(exportValue)) continue;\n\n const story = exportValue as Story | CSF2Story;\n\n // Get story name using storyNameFromExport\n const storyName =\n (typeof story === \"object\" && story.name) ||\n (typeof story === \"object\" && story.storyName) ||\n (typeof story === \"function\" && story.storyName) ||\n storyNameFromExport(exportName);\n\n // Generate story ID matching Storybook format\n const storyId = toId(meta.title || \"Unknown\", exportName);\n\n // Extract description based on story format\n let description = `${storyName} variant`;\n if (typeof story === \"object\" && story.parameters?.docs?.description?.story) {\n description = story.parameters.docs.description.story;\n }\n\n // Check for play function and capture it\n const storyPlayFn = typeof story === \"object\" ? story.play : story.play;\n const hasPlayFunction = !!storyPlayFn;\n\n // Create wrapped play function that adapts Storybook context to our PlayFunctionContext\n const wrappedPlay: PlayFunction | undefined = storyPlayFn\n ? async (context: PlayFunctionContext): Promise<void> => {\n // Build full Storybook context for compatibility\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n const fullContext = buildStoryContext(meta, story, args, storyId, storyName);\n\n // Merge our context with Storybook context\n const playContext = {\n ...fullContext,\n canvasElement: context.canvasElement,\n args: context.args,\n step: context.step,\n };\n\n await storyPlayFn(playContext as unknown as StorybookPlayFunctionContext);\n }\n : undefined;\n\n // Get story tags\n const storyTags = typeof story === \"object\" ? story.tags : undefined;\n\n // Collect loaders from global, meta, and story (in order)\n const loaders = collectLoaders(meta, story);\n\n // Compute the merged args for this variant (for code generation)\n const variantArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n\n // Only include args if there are any defined\n const hasArgs = Object.keys(variantArgs).length > 0;\n\n variants.push({\n name: storyName,\n description,\n render: createRenderFunction(story, component, meta, storyId, storyName),\n // Store Storybook-specific metadata\n ...(hasPlayFunction && { hasPlayFunction: true }),\n ...(wrappedPlay && { play: wrappedPlay }),\n ...(storyId && { storyId }),\n ...(storyTags && { tags: storyTags }),\n ...(loaders.length > 0 && { loaders }),\n ...(hasArgs && { args: variantArgs }),\n });\n }\n\n return variants;\n}\n\n/**\n * Collect loaders from global, meta, and story levels\n * Returns wrapped loader functions that execute with context\n */\nfunction collectLoaders(\n meta: StoryMeta,\n story: Story | CSF2Story\n): VariantLoader[] {\n const allLoaders: Loader[] = [\n ...(globalPreviewConfig.loaders ?? []),\n ...(meta.loaders ?? []),\n ...(typeof story === \"function\" ? story.loaders ?? [] : story.loaders ?? []),\n ];\n\n if (allLoaders.length === 0) {\n return [];\n }\n\n // Wrap each loader to execute without requiring context at call time\n // The actual context will be built when the loader is executed\n return allLoaders.map((loader) => {\n return async (): Promise<Record<string, unknown>> => {\n // Create a minimal context for loader execution\n const minimalContext: StoryContext = {\n args: {},\n argTypes: {},\n globals: {},\n parameters: {},\n id: \"\",\n kind: meta.title || \"Unknown\",\n name: \"\",\n story: \"\",\n viewMode: \"story\",\n loaded: {},\n abortSignal: new AbortController().signal,\n componentId: \"\",\n title: meta.title || \"Unknown\",\n };\n return loader(minimalContext);\n };\n });\n}\n\n/**\n * Build a StoryContext for decorators and render functions\n */\nfunction buildStoryContext(\n meta: StoryMeta,\n story: Story | CSF2Story,\n args: Record<string, unknown>,\n storyId: string,\n storyName: string,\n loadedData?: Record<string, unknown>\n): StoryContext {\n const mergedArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"object\" ? story.args : story.args),\n ...args,\n };\n\n const mergedArgTypes = {\n ...globalPreviewConfig.argTypes,\n ...meta.argTypes,\n ...(typeof story === \"object\" ? story.argTypes : story.argTypes),\n };\n\n const mergedParameters = {\n ...globalPreviewConfig.parameters,\n ...meta.parameters,\n ...(typeof story === \"object\" ? story.parameters : story.parameters),\n };\n\n return {\n args: mergedArgs,\n argTypes: mergedArgTypes ?? {},\n globals: {},\n parameters: mergedParameters ?? {},\n id: storyId,\n kind: meta.title || \"Unknown\",\n name: storyName,\n story: storyName,\n viewMode: \"story\",\n loaded: loadedData ?? {},\n abortSignal: new AbortController().signal,\n componentId: toId(meta.title || \"Unknown\", \"\"),\n title: meta.title || \"Unknown\",\n };\n}\n\n/**\n * Create a render function for a story\n * Handles both CSF 3 (objects) and CSF 2 (functions)\n * Applies decorators in correct order: story → meta → global (innermost first)\n * Accepts optional args overrides and loaded data from loaders\n */\nfunction createRenderFunction(\n story: Story | CSF2Story,\n component: ComponentType<unknown>,\n meta: StoryMeta,\n storyId: string,\n storyName: string\n): (options?: VariantRenderOptions) => ReactNode {\n return (options?: VariantRenderOptions) => {\n // Merge args: global → meta → story → runtime overrides\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n ...options?.args, // Runtime overrides from viewer props panel\n };\n\n const loadedData = options?.loadedData;\n\n // Build the story context with loaded data\n const context = buildStoryContext(meta, story, args, storyId, storyName, loadedData);\n\n // Create the base render function\n let renderFn: () => ReactNode;\n\n if (typeof story === \"function\") {\n // CSF 2: Story is a function (from Template.bind({}))\n renderFn = () => story(args);\n } else if (story.render) {\n // CSF 3: Story has custom render function\n // Support both render(args) and render(args, context) signatures\n renderFn = () =>\n story.render!.length >= 2\n ? story.render!(args, context)\n : story.render!(args);\n } else if (meta.render) {\n // CSF 3: Meta has default render function\n renderFn = () =>\n meta.render!.length >= 2\n ? meta.render!(args, context)\n : meta.render!(args);\n } else {\n // Default: render component with args\n renderFn = () => createElement(component, args);\n }\n\n // Collect decorators in Storybook order\n // story → meta → global, then reverse to apply innermost first\n const allDecorators = [\n ...(globalPreviewConfig.decorators ?? []),\n ...(meta.decorators ?? []),\n ...(typeof story === \"function\" ? story.decorators ?? [] : story.decorators ?? []),\n ].reverse();\n\n // Apply decorators if any\n if (allDecorators.length > 0) {\n return applyDecorators(renderFn, allDecorators, context);\n }\n\n return renderFn();\n };\n}\n\n/**\n * Apply decorators in the correct order\n * Decorators wrap from innermost to outermost\n */\nfunction applyDecorators(\n renderFn: () => ReactNode,\n decorators: Decorator[],\n context: StoryContext\n): ReactNode {\n // Start with the base render function\n let storyFn: () => ReactNode = renderFn;\n\n // Each decorator wraps the previous one\n for (const decorator of decorators) {\n const wrappedFn = storyFn;\n storyFn = () => decorator(wrappedFn, context);\n }\n\n return storyFn();\n}\n\n/**\n * Convert PascalCase to Title Case\n * @deprecated Use storyNameFromExport from @storybook/csf instead\n */\nfunction pascalToTitle(name: string): string {\n return name.replace(/([A-Z])/g, \" $1\").trim();\n}\n","import {\n toId as storybookToId,\n storyNameFromExport as storybookStoryNameFromExport,\n isExportStory as storybookIsExportStory,\n} from \"@storybook/csf\";\n\nexport const toId: typeof storybookToId = (...args) => storybookToId(...args);\nexport const storyNameFromExport: typeof storybookStoryNameFromExport = (...args) =>\n storybookStoryNameFromExport(...args);\nexport const isExportStory: typeof storybookIsExportStory = (...args) =>\n storybookIsExportStory(...args);\n","export { generateContext, filterPlaceholders, PLACEHOLDER_PATTERNS } from '@fragments-sdk/context/generate';\nexport type { ContextOptions, ContextResult } from '@fragments-sdk/context/generate';\n","/**\n * Figma property mapping DSL\n *\n * Provides helpers for mapping Figma component properties to code props.\n * Inspired by Figma Code Connect's API.\n *\n * @example\n * ```tsx\n * import { defineFragment, figma } from '@fragments/core';\n *\n * export default defineFragment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * figma: 'https://figma.com/file/abc/Design?node-id=1-2',\n * figmaProps: {\n * children: figma.string('Label'),\n * disabled: figma.boolean('Disabled'),\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * }),\n * },\n * },\n * // ...\n * });\n * ```\n */\n\nimport type {\n FigmaStringMapping,\n FigmaBooleanMapping,\n FigmaEnumMapping,\n FigmaInstanceMapping,\n FigmaChildrenMapping,\n FigmaTextContentMapping,\n} from './types.js';\n\n/**\n * Map a Figma text property to a string prop.\n *\n * @param figmaProperty - The name of the text property in Figma\n * @returns A string mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * label: figma.string('Button Text'),\n * placeholder: figma.string('Placeholder'),\n * }\n * ```\n */\nfunction string(figmaProperty: string): FigmaStringMapping {\n return {\n __type: 'figma-string',\n figmaProperty,\n };\n}\n\n/**\n * Map a Figma boolean property to a boolean prop.\n * Optionally map true/false to different values.\n *\n * @param figmaProperty - The name of the boolean property in Figma\n * @param valueMapping - Optional mapping of true/false to other values\n * @returns A boolean mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * disabled: figma.boolean('Disabled'),\n * // Map boolean to string values\n * size: figma.boolean('Large', { true: 'lg', false: 'md' }),\n * }\n * ```\n */\nfunction boolean(\n figmaProperty: string,\n valueMapping?: { true: unknown; false: unknown }\n): FigmaBooleanMapping {\n return {\n __type: 'figma-boolean',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Map a Figma variant property to an enum prop.\n *\n * @param figmaProperty - The name of the variant property in Figma\n * @param valueMapping - Mapping of Figma values to code values\n * @returns An enum mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * 'Outline': 'outline',\n * }),\n * size: figma.enum('Size', {\n * 'Small': 'sm',\n * 'Medium': 'md',\n * 'Large': 'lg',\n * }),\n * }\n * ```\n */\nfunction enumValue<T extends Record<string, unknown>>(\n figmaProperty: string,\n valueMapping: T\n): FigmaEnumMapping {\n return {\n __type: 'figma-enum',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Reference a nested Figma component instance.\n * Use this when a prop accepts a component that's represented\n * as an instance swap in Figma.\n *\n * @param figmaProperty - The name of the instance property in Figma\n * @returns An instance mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * icon: figma.instance('Icon'),\n * avatar: figma.instance('Avatar'),\n * }\n * ```\n */\nfunction instance(figmaProperty: string): FigmaInstanceMapping {\n return {\n __type: 'figma-instance',\n figmaProperty,\n };\n}\n\n/**\n * Render children from specific Figma layers.\n * Use this when children are represented as named layers in Figma.\n *\n * @param layers - Array of layer names to include as children\n * @returns A children mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * children: figma.children(['Title', 'Description', 'Actions']),\n * }\n * ```\n */\nfunction children(layers: string[]): FigmaChildrenMapping {\n return {\n __type: 'figma-children',\n layers,\n };\n}\n\n/**\n * Extract text content from a Figma text layer.\n * Use this when a prop should be the actual text from a layer.\n *\n * @param layer - The name of the text layer in Figma\n * @returns A text content mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * title: figma.textContent('Header Text'),\n * description: figma.textContent('Body Text'),\n * }\n * ```\n */\nfunction textContent(layer: string): FigmaTextContentMapping {\n return {\n __type: 'figma-text-content',\n layer,\n };\n}\n\n/**\n * Figma property mapping helpers.\n *\n * Use these to define how Figma properties map to your component props.\n * The mappings are used for:\n * - Generating accurate code snippets in Figma Dev Mode\n * - AI agents understanding the design-to-code relationship\n * - Automated design verification\n */\nexport const figma = {\n string,\n boolean,\n enum: enumValue,\n instance,\n children,\n textContent,\n} as const;\n\n/**\n * Helper type to check if a value is a Figma prop mapping\n */\nexport function isFigmaPropMapping(\n value: unknown\n): value is FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping {\n if (typeof value !== 'object' || value === null || !('__type' in value)) {\n return false;\n }\n const typeValue = (value as Record<string, unknown>).__type;\n return typeof typeValue === 'string' && typeValue.startsWith('figma-');\n}\n\n/**\n * Resolve a Figma prop mapping to an actual value given Figma property values.\n *\n * @param mapping - The Figma prop mapping\n * @param figmaValues - Object containing Figma property values\n * @returns The resolved value for the code prop\n */\nexport function resolveFigmaMapping(\n mapping: FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping,\n figmaValues: Record<string, unknown>\n): unknown {\n switch (mapping.__type) {\n case 'figma-string':\n return figmaValues[mapping.figmaProperty] ?? '';\n\n case 'figma-boolean': {\n const boolValue = figmaValues[mapping.figmaProperty] as boolean;\n if (mapping.valueMapping) {\n return boolValue ? mapping.valueMapping.true : mapping.valueMapping.false;\n }\n return boolValue;\n }\n\n case 'figma-enum': {\n const enumKey = figmaValues[mapping.figmaProperty] as string;\n return mapping.valueMapping[enumKey] ?? enumKey;\n }\n\n case 'figma-instance':\n // Instance mappings return the instance reference\n return figmaValues[mapping.figmaProperty];\n\n case 'figma-children':\n // Children mappings return array of layer contents\n return mapping.layers.map((layer) => figmaValues[layer]);\n\n case 'figma-text-content':\n return figmaValues[mapping.layer] ?? '';\n\n default:\n return undefined;\n }\n}\n","/**\n * Token Parser — extracts CSS custom property declarations from SCSS/CSS files.\n *\n * Parses files for `--prefix-*: value;` declarations and groups them\n * by SCSS comment sections (e.g., `// Typography`, `// Colors`).\n * Falls back to naming-convention-based categorization when comments\n * are absent.\n */\n\nexport interface ParsedToken {\n /** Full CSS variable name (e.g., \"--fui-color-accent\") */\n name: string;\n /** Raw value from the declaration (e.g., \"#{$fui-space-4}\" or \"16px\") */\n value?: string;\n /** Category inferred from SCSS comment or naming convention */\n category: string;\n /** Description from inline comment, if any */\n description?: string;\n}\n\nexport interface TokenParseOutput {\n /** Detected prefix (e.g., \"--fui-\") */\n prefix: string;\n /** Tokens grouped by category */\n categories: Record<string, ParsedToken[]>;\n /** Total number of tokens found */\n total: number;\n}\n\n/**\n * Category inference from naming conventions.\n * Order matters — first match wins.\n */\nconst NAMING_RULES: Array<{ pattern: RegExp; category: string }> = [\n { pattern: /--\\w+-font-/, category: 'typography' },\n { pattern: /--\\w+-line-height-/, category: 'typography' },\n { pattern: /--\\w+-space-/, category: 'spacing' },\n { pattern: /--\\w+-padding-/, category: 'spacing' },\n { pattern: /--\\w+-radius-/, category: 'radius' },\n { pattern: /--\\w+-color-/, category: 'colors' },\n { pattern: /--\\w+-bg-/, category: 'surfaces' },\n { pattern: /--\\w+-text-/, category: 'text' },\n { pattern: /--\\w+-border/, category: 'borders' },\n { pattern: /--\\w+-shadow-/, category: 'shadows' },\n { pattern: /--\\w+-focus-/, category: 'focus' },\n { pattern: /--\\w+-transition-/, category: 'transitions' },\n { pattern: /--\\w+-scrollbar-/, category: 'scrollbar' },\n { pattern: /--\\w+-z-index/, category: 'z-index' },\n { pattern: /--\\w+-(button|input|touch)-/, category: 'component-sizing' },\n { pattern: /--\\w+-appshell-/, category: 'layout' },\n { pattern: /--\\w+-header-/, category: 'layout' },\n { pattern: /--\\w+-code-/, category: 'code' },\n { pattern: /--\\w+-tooltip-/, category: 'tooltip' },\n { pattern: /--\\w+-hero-/, category: 'marketing' },\n];\n\n/**\n * Infer category from a CSS variable name using naming conventions.\n */\nfunction inferCategory(name: string): string {\n for (const rule of NAMING_RULES) {\n if (rule.pattern.test(name)) {\n return rule.category;\n }\n }\n return 'other';\n}\n\n/**\n * Detect the most common prefix from a list of CSS variable names.\n * E.g., given [\"--fui-color-accent\", \"--fui-bg-primary\"] → \"--fui-\"\n */\nfunction detectPrefix(names: string[]): string {\n if (names.length === 0) return '--';\n\n // Find common prefix after \"--\"\n const stripped = names.map((n) => n.slice(2)); // remove \"--\"\n let prefix = '';\n const first = stripped[0];\n\n for (let i = 0; i < first.length; i++) {\n const ch = first[i];\n if (stripped.every((s) => s[i] === ch)) {\n prefix += ch;\n } else {\n break;\n }\n }\n\n // Trim to last hyphen to get clean prefix\n const lastHyphen = prefix.lastIndexOf('-');\n if (lastHyphen > 0) {\n prefix = prefix.slice(0, lastHyphen + 1);\n }\n\n return `--${prefix}`;\n}\n\n/**\n * Normalize a SCSS comment into a category name.\n * \"// Typography\" → \"typography\"\n * \"// Component heights\" → \"component-sizing\"\n * \"// Hero/Marketing gradient\" → \"marketing\"\n */\nfunction normalizeCategory(comment: string): string {\n const text = comment\n .trim()\n .replace(/^\\/\\/\\s*/, '')\n .replace(/^\\/\\*+\\s*/, '')\n .replace(/\\s*\\*+\\/$/, '')\n .trim()\n .toLowerCase();\n\n // Map common comment headings to clean category names\n const mappings: Record<string, string> = {\n 'base configuration': 'base',\n 'typography': 'typography',\n 'spacing (micro)': 'spacing',\n 'spacing': 'spacing',\n 'density padding': 'spacing',\n 'border radius': 'radius',\n 'transitions': 'transitions',\n 'colors': 'colors',\n 'surfaces': 'surfaces',\n 'text': 'text',\n 'borders': 'borders',\n 'shadows': 'shadows',\n 'focus': 'focus',\n 'scrollbar': 'scrollbar',\n 'component heights': 'component-sizing',\n 'appshell layout': 'layout',\n 'codeblock': 'code',\n 'tooltip': 'tooltip',\n 'hero/marketing gradient': 'marketing',\n };\n\n return mappings[text] ?? text.replace(/\\s+/g, '-');\n}\n\n/**\n * Parse a SCSS or CSS file and extract CSS custom property declarations.\n *\n * Handles two grouping strategies:\n * 1. Comment-based: Uses `// Category` comments above groups of declarations\n * 2. Naming-based: Falls back to inferring category from variable name patterns\n */\nexport function parseTokenFile(content: string, filePath: string): TokenParseOutput {\n const lines = content.split('\\n');\n const tokens: ParsedToken[] = [];\n const seenNames = new Set<string>();\n let currentCategory = 'other';\n let hasCommentCategories = false;\n\n // Regex for CSS custom property declarations\n // Matches: --name: value; (with optional SCSS interpolation)\n // Captures both the variable name and its value\n const varDeclRegex = /^\\s*(--[\\w-]+)\\s*:\\s*(.+?)\\s*;/;\n // Regex for section comments (// Category or /* Category */)\n // Allow any characters after uppercase start (including / for \"Hero/Marketing\")\n const sectionCommentRegex = /^\\s*\\/\\/\\s+([A-Z].+)$/;\n\n for (const line of lines) {\n // Check for section comment\n const commentMatch = line.match(sectionCommentRegex);\n if (commentMatch) {\n const normalized = normalizeCategory(commentMatch[0]);\n if (normalized) {\n currentCategory = normalized;\n hasCommentCategories = true;\n }\n continue;\n }\n\n // Check for CSS variable declaration\n const varMatch = line.match(varDeclRegex);\n if (varMatch) {\n const name = varMatch[1];\n const rawValue = varMatch[2];\n\n // Deduplicate: keep only the first occurrence of each variable.\n // Dark mode and high contrast blocks redefine the same variables\n // with different values — we only want the canonical list.\n if (seenNames.has(name)) continue;\n seenNames.add(name);\n\n // Extract inline comment if present\n const inlineComment = line.match(/\\/\\/\\s*(.+)$/);\n const description = inlineComment ? inlineComment[1].trim() : undefined;\n\n // Clean the value: strip trailing inline comments\n const cleanValue = rawValue.replace(/\\s*\\/\\/.*$/, '').trim();\n\n tokens.push({\n name,\n value: cleanValue || undefined,\n category: hasCommentCategories ? currentCategory : inferCategory(name),\n description,\n });\n }\n }\n\n // Group by category\n const categories: Record<string, ParsedToken[]> = {};\n for (const token of tokens) {\n if (!categories[token.category]) {\n categories[token.category] = [];\n }\n categories[token.category].push(token);\n }\n\n // Detect prefix\n const prefix = detectPrefix(tokens.map((t) => t.name));\n\n return {\n prefix,\n categories,\n total: tokens.length,\n };\n}\n","import type { CompiledFragment, RelationshipType } from \"./types.js\";\nimport type { ComponentGraph } from \"@fragments-sdk/context/graph\";\nimport { ComponentGraphEngine } from \"@fragments-sdk/context/graph\";\n\n// --- Public types ---\n\nexport interface CompositionWarning {\n type:\n | \"missing_parent\"\n | \"missing_child\"\n | \"missing_composition\"\n | \"redundant_alternative\"\n | \"deprecated\"\n | \"experimental\";\n component: string;\n message: string;\n relatedComponent?: string;\n}\n\nexport interface CompositionSuggestion {\n component: string;\n reason: string;\n relationship: RelationshipType | \"category_gap\";\n sourceComponent: string;\n}\n\nexport interface CompositionGuideline {\n component: string;\n guideline: string;\n}\n\nexport interface CompositionAnalysis {\n /** The validated component names (filtered to those that exist) */\n components: string[];\n\n /** Components requested but not found in the registry */\n unknown: string[];\n\n /** Issues with the current selection */\n warnings: CompositionWarning[];\n\n /** Components to consider adding */\n suggestions: CompositionSuggestion[];\n\n /** Relevant usage guidelines for the selected components */\n guidelines: CompositionGuideline[];\n}\n\n// --- Category affinities ---\n\nconst CATEGORY_AFFINITIES: Record<string, string[]> = {\n forms: [\"feedback\"],\n actions: [\"feedback\"],\n};\n\n// --- Main function ---\n\n/**\n * Analyzes a set of components as a composition group.\n * Returns warnings about missing relations, usage conflicts,\n * and suggestions for additional components.\n *\n * When a ComponentGraph is provided via `options.graph`, the analysis is\n * enhanced with graph-based dependency detection and block-based suggestions.\n *\n * Browser-safe: no Node.js APIs used.\n */\nexport function analyzeComposition(\n fragments: Record<string, CompiledFragment>,\n componentNames: string[],\n _context?: string,\n options?: { graph?: ComponentGraph },\n): CompositionAnalysis {\n const allNames = new Set(Object.keys(fragments));\n\n // 1. Validate names\n const components: string[] = [];\n const unknown: string[] = [];\n for (const name of componentNames) {\n if (allNames.has(name)) {\n components.push(name);\n } else {\n unknown.push(name);\n }\n }\n\n const selectedSet = new Set(components);\n const warnings: CompositionWarning[] = [];\n const suggestions: CompositionSuggestion[] = [];\n const guidelines: CompositionGuideline[] = [];\n\n // Track suggestions to avoid duplicates\n const suggestedSet = new Set<string>();\n\n for (const name of components) {\n const fragment = fragments[name];\n\n // 2. Relation checks\n if (fragment.relations) {\n for (const rel of fragment.relations) {\n switch (rel.relationship) {\n case \"parent\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_parent\",\n component: name,\n message: `\"${name}\" expects to be wrapped by \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"child\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${name}\" typically contains \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"child\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"composition\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_composition\",\n component: name,\n message: `\"${name}\" is typically used together with \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"sibling\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${rel.component}\" is a sibling of \"${name}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"sibling\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"alternative\":\n if (selectedSet.has(rel.component)) {\n warnings.push({\n type: \"redundant_alternative\",\n component: name,\n message: `\"${name}\" and \"${rel.component}\" are alternatives — using both may be redundant${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n }\n }\n }\n\n // 3. Usage conflict checks (whenNot)\n if (fragment.usage?.whenNot) {\n for (const whenNotEntry of fragment.usage.whenNot) {\n const lower = whenNotEntry.toLowerCase();\n for (const other of components) {\n if (other !== name && lower.includes(other.toLowerCase())) {\n guidelines.push({\n component: name,\n guideline: `Potential conflict with \"${other}\": ${whenNotEntry}`,\n });\n }\n }\n }\n }\n\n // 4. Status warnings\n if (fragment.meta.status === \"deprecated\") {\n warnings.push({\n type: \"deprecated\",\n component: name,\n message: fragment.meta.description\n ? `\"${name}\" is deprecated: ${fragment.meta.description}`\n : `\"${name}\" is deprecated`,\n });\n } else if (fragment.meta.status === \"experimental\") {\n warnings.push({\n type: \"experimental\",\n component: name,\n message: `\"${name}\" is experimental and may change without notice`,\n });\n }\n }\n\n // 5. Category gap analysis\n const selectedCategories = new Set(\n components.map((name) => fragments[name].meta.category)\n );\n\n for (const [category, affinities] of Object.entries(CATEGORY_AFFINITIES)) {\n if (!selectedCategories.has(category)) continue;\n\n for (const neededCategory of affinities) {\n if (selectedCategories.has(neededCategory)) continue;\n\n // Find the best component from the needed category\n const candidate = findBestCategoryCandidate(\n fragments,\n neededCategory,\n selectedSet,\n suggestedSet\n );\n if (candidate) {\n suggestions.push({\n component: candidate,\n reason: `Compositions using \"${category}\" components often benefit from a \"${neededCategory}\" component`,\n relationship: \"category_gap\",\n sourceComponent: components.find(\n (n) => fragments[n].meta.category === category\n )!,\n });\n suggestedSet.add(candidate);\n }\n }\n }\n\n // 6. Graph-enhanced analysis (when graph data is available)\n if (options?.graph) {\n const engine = new ComponentGraphEngine(options.graph);\n\n // Add graph-based dependency warnings\n for (const name of components) {\n const deps = engine.dependencies(name, [\"imports\", \"hook-depends\"]);\n for (const dep of deps) {\n if (\n !selectedSet.has(dep.target) &&\n !suggestedSet.has(dep.target) &&\n allNames.has(dep.target)\n ) {\n suggestions.push({\n component: dep.target,\n reason: `\"${name}\" ${dep.type === \"hook-depends\" ? \"uses a hook from\" : \"imports\"} \"${dep.target}\"`,\n relationship: \"composition\",\n sourceComponent: name,\n });\n suggestedSet.add(dep.target);\n }\n }\n }\n\n // Add block-based suggestions\n for (const name of components) {\n const blocks = engine.blocksUsing(name);\n for (const blockName of blocks) {\n // Find other components in this block that aren't selected\n const blockComps = options.graph.edges\n .filter(\n (e) =>\n e.type === \"composes\" &&\n e.provenance === `block:${blockName}` &&\n (e.source === name || e.target === name)\n )\n .map((e) => (e.source === name ? e.target : e.source));\n\n for (const comp of blockComps) {\n if (\n !selectedSet.has(comp) &&\n !suggestedSet.has(comp) &&\n allNames.has(comp)\n ) {\n suggestions.push({\n component: comp,\n reason: `\"${name}\" and \"${comp}\" are used together in the \"${blockName}\" block`,\n relationship: \"composition\",\n sourceComponent: name,\n });\n suggestedSet.add(comp);\n }\n }\n }\n }\n }\n\n return { components, unknown, warnings, suggestions, guidelines };\n}\n\n/**\n * Find the best candidate component from a given category.\n * Prefers stable components and avoids already-selected or already-suggested ones.\n */\nfunction findBestCategoryCandidate(\n fragments: Record<string, CompiledFragment>,\n category: string,\n selectedSet: Set<string>,\n suggestedSet: Set<string>\n): string | null {\n let best: string | null = null;\n let bestScore = -1;\n\n for (const [name, fragment] of Object.entries(fragments)) {\n if (fragment.meta.category !== category) continue;\n if (selectedSet.has(name) || suggestedSet.has(name)) continue;\n\n const status = fragment.meta.status ?? \"stable\";\n let score = 0;\n if (status === \"stable\") score = 3;\n else if (status === \"beta\") score = 2;\n else if (status === \"experimental\") score = 1;\n // deprecated gets 0\n\n if (score > bestScore) {\n bestScore = score;\n best = name;\n }\n }\n\n return best;\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +0,0 @@
1
- import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
- import {
3
- scan
4
- } from "./chunk-DH4ETVSM.js";
5
- import "./chunk-GKX2HPZ6.js";
6
- import "./chunk-3T6QL7IY.js";
7
- import "./chunk-OOGTG5FM.js";
8
- import "./chunk-GHYYFAQN.js";
9
- export {
10
- scan
11
- };
12
- //# sourceMappingURL=scan-V54HWRDY.js.map
@@ -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 * Fragments 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 fragment file changes\n *\n * This is the \"Storybook-like\" experience for Fragments.\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, discoverFragmentFiles, discoverInstalledFragments } from \"../core/node.js\";\nimport { fragmentsPlugin } 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 fragments 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 Fragments 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 fragments config\n const { config, configDir } = await loadConfig(configPath);\n\n // Discover fragment files (local + installed packages)\n const fragmentFiles = await discoverFragmentFiles(config, configDir);\n const installedFiles = await discoverInstalledFragments(projectRoot);\n const allFragmentFiles = [...fragmentFiles, ...installedFiles];\n console.log(`📦 Found ${fragmentFiles.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 Fragments-specific configuration\n const fragmentsConfig: 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 // Fragments plugins (array including SVGR)\n ...fragmentsPlugin({\n fragmentFiles: allFragmentFiles,\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, fragmentsConfig);\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 * Fragments 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 fragment imports\n * - Viewer UI served at /fragments/\n * - HMR support for fragment 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 { FragmentsConfig, CompiledFragment } 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 findFragmentByName,\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 fragment 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 FragmentsPluginOptions {\n /** Discovered fragment files */\n fragmentFiles: Array<{\n absolutePath: string;\n relativePath: string;\n }>;\n\n /** Fragments configuration */\n config: FragmentsConfig;\n\n /** Project root directory */\n projectRoot: string;\n}\n\n/**\n * Create the Fragments Vite plugin.\n * Returns an array of plugins to support SVGR and other transforms.\n */\nexport function fragmentsPlugin(options: FragmentsPluginOptions): Plugin[] {\n const { fragmentFiles, config, projectRoot } = options;\n\n // Virtual module IDs\n const VIRTUAL_FRAGMENTS = `virtual:${BRAND.nameLower}`;\n const VIRTUAL_FRAGMENTS_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 fragment files for HMR\n const fragmentFileSet = new Set(fragmentFiles.map((f) => f.absolutePath));\n\n const mainPlugin: Plugin = {\n name: \"fragments\",\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 fragments to find the component\n const loadedFragments = await loadFragmentsForRender(\n fragmentFiles,\n projectRoot\n );\n const fragmentInfo = findFragmentByName(component, loadedFragments);\n\n if (!fragmentInfo) {\n const available = getAvailableComponents(loadedFragments);\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 fragment\n const fragmentFile = fragmentFiles.find(\n (f) => f.relativePath === fragmentInfo.path\n );\n if (!fragmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Could not resolve fragment file path\" })\n );\n return;\n }\n\n // Generate render script\n const renderScript = generateRenderScript(\n fragmentFile.absolutePath,\n fragmentInfo.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 fragment files\n console.log(\"[Fragments] Compare request for:\", component);\n console.log(\"[Fragments] fragmentFiles count:\", fragmentFiles.length);\n console.log(\"[Fragments] First 3 fragment files:\", fragmentFiles.slice(0, 3).map(f => f.relativePath));\n console.log(\"[Fragments] projectRoot:\", projectRoot);\n\n // Load fragments to find the component and its figma URL\n const loadedFragments = await loadFragmentsForRender(\n fragmentFiles,\n projectRoot\n );\n console.log(\"[Fragments] loadedFragments count:\", loadedFragments.length);\n console.log(\"[Fragments] First 3 loaded:\", loadedFragments.slice(0, 3).map(s => s.fragment.meta.name));\n const fragmentInfo = findFragmentByName(component, loadedFragments);\n\n if (!fragmentInfo) {\n const available = getAvailableComponents(loadedFragments);\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 fragment data to get figma URL\n const fullFragmentData = await loadFullFragmentForCompare(\n _server,\n fragmentFiles,\n component,\n variant,\n projectRoot\n );\n\n // Determine which Figma URL to use (request > variant > meta)\n const effectiveFigmaUrl = figmaUrl || fullFragmentData?.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 fragment 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 fragment file for rendering\n const fragmentFile = fragmentFiles.find(\n (f) => f.relativePath === fragmentInfo.path\n );\n if (!fragmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({ error: \"Could not resolve fragment 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 fragmentFile.absolutePath,\n fragmentInfo.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 fragment data\n const loadedFragments = await loadFragmentsForRender(fragmentFiles, projectRoot);\n const fragmentInfo = findFragmentByName(component, loadedFragments);\n\n if (!fragmentInfo) {\n const available = getAvailableComponents(loadedFragments);\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 fragment file for rendering\n const fragmentFile = fragmentFiles.find(\n (f) => f.relativePath === fragmentInfo.path\n );\n if (!fragmentFile) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Could not resolve fragment 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 fragmentFile.absolutePath,\n fragmentInfo.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 fragments from BRAND.outFile\n const compiledFragments = await loadFragmentsForContext(\n _server,\n fragmentFiles,\n config,\n projectRoot\n );\n\n const { content, tokenEstimate } = generateContext(\n compiledFragments,\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 fragment data\n const loadedFragments = await loadFragmentsForRender(fragmentFiles, projectRoot);\n const fragmentInfo = findFragmentByName(component, loadedFragments);\n\n if (!fragmentInfo) {\n const available = getAvailableComponents(loadedFragments);\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 fragment\n const fragmentFile = fragmentFiles.find(\n (f) => f.relativePath === fragmentInfo.path\n );\n const sourceFile = fragmentFile?.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 === \"/fragments\" || 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_FRAGMENTS) {\n return VIRTUAL_FRAGMENTS_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_FRAGMENTS_RESOLVED) {\n return generateFragmentsModule(fragmentFiles, 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 fragment files\n handleHotUpdate({ file, server }) {\n if (fragmentFileSet.has(file)) {\n // Invalidate the virtual fragments module\n const mod = server.moduleGraph.getModuleById(VIRTUAL_FRAGMENTS_RESOLVED);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n // Send HMR update\n server.ws.send({\n type: \"custom\",\n event: \"fragments: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: \"fragments-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 fragments 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 fragment or story file path.\n * e.g., \"src/components/Button/Button.fragment.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(/\\.(fragment|stories)\\.(tsx?|jsx?)$/, \"\");\n}\n\n/**\n * Generate the virtual fragments module.\n * Uses dynamic imports for lazy loading - fragments are loaded on demand.\n * Supports both native .fragment.tsx files and Storybook .stories.tsx files.\n * Integrates Storybook preview config for global decorators, parameters, etc.\n *\n * MERGE STRATEGY: When both .fragment.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 .fragment.tsx (Figma URLs, AI descriptions, usage guidelines)\n * - This gives us the best of both worlds: working renders + rich metadata\n */\nfunction generateFragmentsModule(\n fragmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n config: FragmentsConfig,\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 fragmentFile?: { absolutePath: string; relativePath: string };\n }>();\n\n for (const file of fragmentFiles) {\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.fragmentFile = file;\n }\n\n filesByBasePath.set(basePath, existing);\n }\n\n // Generate loaders with metadata merge support\n // Priority: stories for rendering, fragment 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.fragmentFile;\n if (!primaryFile) return null;\n\n const isStory = !!files.storyFile;\n\n // If we have both, include the fragment file path for metadata merge\n const metadataPath = (files.storyFile && files.fragmentFile)\n ? files.fragmentFile.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:fragments-preview\";`\n : \"\";\n const previewSetup = previewConfigPath\n ? `\n// Set global preview config before loading fragments\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 { storyModuleToFragment, setPreviewConfig } from \"@fragments/core\";\n${previewImport}\n${previewSetup}\n// Lazy fragment loaders (supports both .fragment.tsx and .stories.tsx)\nconst fragmentLoaders = [\n${loaders}\n];\n\n// Cache for loaded fragments\nconst loadedFragments = new Map();\n\n/**\n * Merge metadata from a fragment file into a story-based fragment.\n * This preserves Figma URLs and other AI-agent focused data.\n */\nfunction mergeMetadata(fragment, metadataModule) {\n if (!metadataModule?.default) return fragment;\n\n const metadata = metadataModule.default;\n\n // Merge meta-level Figma URL\n if (metadata.meta?.figma && !fragment.meta.figma) {\n fragment.meta.figma = metadata.meta.figma;\n }\n\n // Merge description if not present\n if (metadata.meta?.description && !fragment.meta.description) {\n fragment.meta.description = metadata.meta.description;\n }\n\n // Merge variant-level Figma URLs\n if (metadata.variants && fragment.variants) {\n for (const metaVariant of metadata.variants) {\n const fragmentVariant = fragment.variants.find(v => v.name === metaVariant.name);\n if (fragmentVariant && metaVariant.figma && !fragmentVariant.figma) {\n fragmentVariant.figma = metaVariant.figma;\n }\n }\n }\n\n return fragment;\n}\n\n// Load all fragments (for initial render)\n// Gracefully handles individual failures - one bad story won't break all fragments\nexport async function loadAllFragments() {\n const results = await Promise.all(\n fragmentLoaders.map(async (loader) => {\n try {\n if (loadedFragments.has(loader.path)) {\n const cached = loadedFragments.get(loader.path);\n return cached ? { path: loader.path, fragment: cached } : null;\n }\n\n const module = await loader.loader();\n\n // Convert story modules to fragments at runtime\n let fragment;\n if (loader.isStory) {\n fragment = storyModuleToFragment(module, loader.path);\n // storyModuleToFragment returns null for stories without a component\n if (!fragment) {\n loadedFragments.set(loader.path, null);\n return null;\n }\n } else {\n fragment = module.default;\n }\n\n // Merge metadata from corresponding fragment file if available\n if (loader.metadataLoader) {\n try {\n const metadataModule = await loader.metadataLoader();\n fragment = mergeMetadata(fragment, 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 loadedFragments.set(loader.path, fragment);\n return { path: loader.path, fragment };\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 fragment by path\nexport async function loadFragment(path) {\n const loader = fragmentLoaders.find(l => l.path === path);\n if (!loader) return null;\n\n if (loadedFragments.has(path)) {\n return loadedFragments.get(path);\n }\n\n const module = await loader.loader();\n\n // Convert story modules to fragments at runtime\n let fragment;\n if (loader.isStory) {\n fragment = storyModuleToFragment(module, path);\n } else {\n fragment = module.default;\n }\n\n // Merge metadata from corresponding fragment file if available\n if (loader.metadataLoader && fragment) {\n try {\n const metadataModule = await loader.metadataLoader();\n fragment = mergeMetadata(fragment, metadataModule);\n } catch (metaError) {\n console.warn(\"[Fragments] Could not load metadata for \" + path + \":\", metaError.message);\n }\n }\n\n loadedFragments.set(path, fragment);\n return fragment;\n}\n\n// For backwards compatibility, load all fragments synchronously on import\n// This is still lazy per-file but awaited at module load\nlet fragments = [];\nconst fragmentsPromise = loadAllFragments().then(s => { fragments = s; return s; });\n\nexport { fragments, fragmentsPromise };\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(\"fragments:update\", (data) => {\n console.log(\"[Fragments] File updated:\", data.file);\n // Clear cache for the updated file (handles both .fragment and .stories)\n for (const [path, _] of loadedFragments) {\n const basePath = path.replace(/\\\\.(fragment|stories)\\\\.tsx?$/, '');\n if (data.file.includes(basePath)) {\n loadedFragments.delete(path);\n }\n }\n // Trigger re-render in viewer\n window.dispatchEvent(new CustomEvent(\"fragments:update\"));\n });\n}\n`;\n}\n\n/**\n * Generate the viewer entry point.\n */\nfunction generateViewerEntry(): string {\n return `\nimport { fragments, config } from \"virtual:fragments\";\n\n// Re-export for viewer\nexport { fragments, config };\n\n// Initialize viewer\nconsole.log(\"[Fragments] Loaded\", fragments.length, \"fragment(s)\");\n`;\n}\n\n/**\n * Load fragments for context generation.\n * Uses BRAND.outFile to avoid SSR module loading issues with React CJS modules.\n */\nasync function loadFragmentsForContext(\n _server: ViteDevServer,\n _fragmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n _config: FragmentsConfig,\n configDir?: string\n): Promise<CompiledFragment[]> {\n const { join } = await import(\"node:path\");\n\n // Read from outFile (avoids SSR issues with React CJS)\n const fragmentsJsonPath = join(configDir || process.cwd(), BRAND.outFile);\n\n try {\n const content = await readFile(fragmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n fragments: Record<string, CompiledFragment>;\n };\n\n return Object.values(data.fragments || {});\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 Fragments 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 fragments for render from BRAND.outFile or by building on-the-fly.\n * This avoids SSR issues with React components.\n */\nasync function loadFragmentsForRender(\n fragmentFiles: Array<{ absolutePath: string; relativePath: string }>,\n configDir: string\n): Promise<Array<{ path: string; fragment: { meta: { name: string } } }>> {\n const { join } = await import(\"node:path\");\n\n // Try to read from the project directory\n const fragmentsJsonPath = join(configDir, BRAND.outFile);\n\n try {\n const content = await readFile(fragmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n fragments: Record<string, { filePath: string; meta: { name: string } }>;\n };\n\n // Convert to the expected format if we have entries\n const fragmentEntries = Object.values(data.fragments || {});\n if (fragmentEntries.length > 0) {\n return fragmentEntries.map((fragment) => ({\n path: fragment.filePath,\n fragment: { meta: { name: fragment.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 fragmentFiles.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.fragment.tsx\"\n const match = f.relativePath.match(/\\/([^/]+)\\.fragment\\./);\n name = match ? match[1] : f.relativePath;\n }\n return {\n path: f.relativePath,\n fragment: { 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 fragment data to get figma URL from fragment or variant.\n * Uses BRAND.outFile to avoid SSR module loading issues with React CJS modules.\n */\nasync function loadFullFragmentForCompare(\n _server: ViteDevServer,\n _fragmentFiles: 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 fragmentsJsonPath = join(configDir || process.cwd(), BRAND.outFile);\n\n try {\n const content = await readFile(fragmentsJsonPath, \"utf-8\");\n const data = JSON.parse(content) as {\n fragments: Record<\n string,\n {\n meta: { name: string; figma?: string };\n variants?: Array<{ name: string; figma?: string }>;\n }\n >;\n };\n\n const fragment = data.fragments[componentName];\n if (!fragment) {\n return null;\n }\n\n // Priority: variant.figma > meta.figma\n if (variantName && fragment.variants) {\n const variant = fragment.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 (fragment.meta.figma) {\n return { figmaUrl: fragment.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 FragmentInfo {\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 fragment by component name.\n * Returns the fragment info if found, null otherwise.\n */\nexport function findFragmentByName(\n componentName: string,\n fragments: Array<{ path: string; fragment: { meta: { name: string } } }>\n): FragmentInfo | null {\n const match = fragments.find(\n (s) => s.fragment.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!match) return null;\n\n return {\n name: match.fragment.meta.name,\n path: match.path,\n };\n}\n\n/**\n * Get list of available component names from loaded fragments.\n */\nexport function getAvailableComponents(\n fragments: Array<{ fragment: { meta: { name: string } } }>\n): string[] {\n return fragments.map((s) => s.fragment.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 fragmentPath: 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 fragment to get the component\nasync function render() {\n const root = document.getElementById(\"render-root\");\n\n try {\n // Dynamic import of the fragment file\n const fragmentModule = await import(\"${fragmentPath}\");\n const fragment = fragmentModule.default;\n\n if (!fragment || !fragment.component) {\n throw new Error(\"Fragment does not export a component\");\n }\n\n const Component = fragment.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:fragments-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"]}