@fragments-sdk/cli 0.7.8 → 0.7.10

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 (99) hide show
  1. package/dist/bin.js +13 -13
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-CWKQQR6C.js → chunk-57OW43NL.js} +3 -3
  4. package/dist/chunk-57OW43NL.js.map +1 -0
  5. package/dist/{chunk-AA6CAHCZ.js → chunk-7CRC46HV.js} +2 -2
  6. package/dist/chunk-7CRC46HV.js.map +1 -0
  7. package/dist/{chunk-3JPJTU25.js → chunk-CRTN6BIW.js} +5 -5
  8. package/dist/chunk-CRTN6BIW.js.map +1 -0
  9. package/dist/{chunk-LHIIBI6F.js → chunk-M42XIHPV.js} +2 -2
  10. package/dist/{chunk-2EFVPE5Q.js → chunk-TQOGBAOZ.js} +2 -2
  11. package/dist/chunk-TQOGBAOZ.js.map +1 -0
  12. package/dist/core/index.d.ts +1944 -0
  13. package/dist/{core-YAPWXDZW.js → core/index.js} +5 -5
  14. package/dist/defineFragment-C6PFzZyo.d.ts +656 -0
  15. package/dist/{generate-LEBVZCCH.js → generate-ZPERYZLF.js} +4 -4
  16. package/dist/index.d.ts +4 -159
  17. package/dist/index.js +9 -4
  18. package/dist/index.js.map +1 -1
  19. package/dist/{init-4VXL3Q6N.js → init-GID2DXB3.js} +69 -7
  20. package/dist/init-GID2DXB3.js.map +1 -0
  21. package/dist/mcp-bin.js +3 -3
  22. package/dist/{scan-3NYSRF6G.js → scan-BSMLGBX4.js} +5 -5
  23. package/dist/{service-HL6TMP3B.js → service-QACVPR37.js} +3 -3
  24. package/dist/{static-viewer-KLD24I4R.js → static-viewer-2RQD5QLR.js} +3 -3
  25. package/dist/{test-Y7YZOJLE.js → test-36UELXTE.js} +3 -3
  26. package/dist/{tokens-M4FCJKBK.js → tokens-A3BZIQPB.js} +4 -4
  27. package/dist/{viewer-ZWQQ74FV.js → viewer-ZA7WK3EY.js} +137 -30
  28. package/dist/viewer-ZA7WK3EY.js.map +1 -0
  29. package/package.json +6 -1
  30. package/src/commands/add.ts +1 -1
  31. package/src/commands/init.ts +84 -4
  32. package/src/core/defineFragment.ts +1 -1
  33. package/src/core/figma.ts +1 -1
  34. package/src/core/index.ts +2 -2
  35. package/src/core/loader.ts +3 -3
  36. package/src/core/schema.ts +1 -1
  37. package/src/index.ts +6 -0
  38. package/src/migrate/converter.ts +1 -1
  39. package/src/service/snippet-validation.test.ts +5 -5
  40. package/src/service/snippet-validation.ts +0 -1
  41. package/src/viewer/__tests__/viewer-integration.test.ts +16 -23
  42. package/src/viewer/assets/fragments-logo.ts +4 -0
  43. package/src/viewer/components/AccessibilityPanel.tsx +1 -1
  44. package/src/viewer/components/ActionsPanel.tsx +1 -1
  45. package/src/viewer/components/App.tsx +138 -97
  46. package/src/viewer/components/BottomPanel.tsx +1 -1
  47. package/src/viewer/components/CodePanel.naming.test.tsx +1 -1
  48. package/src/viewer/components/CodePanel.tsx +1 -1
  49. package/src/viewer/components/CommandPalette.tsx +1 -1
  50. package/src/viewer/components/ComponentGraph.tsx +1 -1
  51. package/src/viewer/components/ComponentHeader.tsx +1 -1
  52. package/src/viewer/components/ContractPanel.tsx +1 -1
  53. package/src/viewer/components/ErrorBoundary.tsx +1 -1
  54. package/src/viewer/components/HealthDashboard.tsx +1 -1
  55. package/src/viewer/components/HmrStatusIndicator.tsx +1 -1
  56. package/src/viewer/components/InteractionsPanel.tsx +1 -1
  57. package/src/viewer/components/IsolatedRender.tsx +1 -1
  58. package/src/viewer/components/KeyboardShortcutsHelp.tsx +1 -1
  59. package/src/viewer/components/LandingPage.tsx +1 -1
  60. package/src/viewer/components/Layout.tsx +1 -1
  61. package/src/viewer/components/LeftSidebar.tsx +105 -18
  62. package/src/viewer/components/MultiViewportPreview.tsx +1 -1
  63. package/src/viewer/components/PreviewArea.tsx +1 -2
  64. package/src/viewer/components/PreviewFrameHost.tsx +0 -4
  65. package/src/viewer/components/PreviewMenu.tsx +247 -0
  66. package/src/viewer/components/PreviewToolbar.tsx +1 -1
  67. package/src/viewer/components/PropsEditor.tsx +1 -1
  68. package/src/viewer/components/PropsTable.tsx +1 -1
  69. package/src/viewer/components/RightSidebar.tsx +1 -1
  70. package/src/viewer/components/ScreenshotButton.tsx +1 -1
  71. package/src/viewer/components/SkeletonLoader.tsx +1 -1
  72. package/src/viewer/components/Toast.tsx +2 -2
  73. package/src/viewer/components/TokenStylePanel.tsx +1 -1
  74. package/src/viewer/components/VariantMatrix.tsx +1 -1
  75. package/src/viewer/components/VariantTabs.tsx +1 -1
  76. package/src/viewer/components/ViewportSelector.tsx +1 -1
  77. package/src/viewer/constants/ui.ts +14 -0
  78. package/src/viewer/entry.tsx +3 -4
  79. package/src/viewer/hooks/useKeyboardShortcuts.ts +65 -17
  80. package/src/viewer/hooks/useViewSettings.ts +1 -2
  81. package/src/viewer/index.ts +1 -1
  82. package/src/viewer/preview-frame.html +6 -9
  83. package/src/viewer/server.ts +80 -7
  84. package/src/viewer/styles/globals.css +12 -51
  85. package/src/viewer/vite-plugin.ts +70 -9
  86. package/dist/chunk-2EFVPE5Q.js.map +0 -1
  87. package/dist/chunk-3JPJTU25.js.map +0 -1
  88. package/dist/chunk-AA6CAHCZ.js.map +0 -1
  89. package/dist/chunk-CWKQQR6C.js.map +0 -1
  90. package/dist/init-4VXL3Q6N.js.map +0 -1
  91. package/dist/viewer-ZWQQ74FV.js.map +0 -1
  92. /package/dist/{chunk-LHIIBI6F.js.map → chunk-M42XIHPV.js.map} +0 -0
  93. /package/dist/{core-YAPWXDZW.js.map → core/index.js.map} +0 -0
  94. /package/dist/{generate-LEBVZCCH.js.map → generate-ZPERYZLF.js.map} +0 -0
  95. /package/dist/{scan-3NYSRF6G.js.map → scan-BSMLGBX4.js.map} +0 -0
  96. /package/dist/{service-HL6TMP3B.js.map → service-QACVPR37.js.map} +0 -0
  97. /package/dist/{static-viewer-KLD24I4R.js.map → static-viewer-2RQD5QLR.js.map} +0 -0
  98. /package/dist/{test-Y7YZOJLE.js.map → test-36UELXTE.js.map} +0 -0
  99. /package/dist/{tokens-M4FCJKBK.js.map → tokens-A3BZIQPB.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 /** Resolved value after SCSS variable substitution (e.g., \"16px\") */\n resolvedValue?: 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 * Extract SCSS variable declarations ($name: value;) from file content.\n * Returns a map of variable name → value.\n */\nfunction extractScssVariables(content: string): Map<string, string> {\n const vars = new Map<string, string>();\n // Match: $var-name: value; (handles multi-word values, stops at semicolon)\n const scssVarRegex = /^\\s*(\\$[\\w-]+)\\s*:\\s*(.+?)\\s*(?:!default\\s*)?;/gm;\n\n let match: RegExpExecArray | null;\n while ((match = scssVarRegex.exec(content)) !== null) {\n const name = match[1];\n const value = match[2].replace(/\\s*\\/\\/.*$/, '').trim();\n // Only store the first occurrence (canonical definition)\n if (!vars.has(name)) {\n vars.set(name, value);\n }\n }\n\n return vars;\n}\n\n/**\n * Resolve SCSS interpolations and variable references in a token value.\n *\n * Handles:\n * - `#{$var}` → looks up $var in scssVars map\n * - `$var` standalone → looks up in scssVars map\n * - `var(--other-token, fallback)` → returns fallback if provided\n * - Recursive resolution up to 5 levels deep\n */\nfunction resolveTokenValue(\n rawValue: string,\n scssVars: Map<string, string>,\n cssVarValues: Map<string, string>,\n depth = 0\n): string {\n if (depth > 5) return rawValue; // Prevent infinite recursion\n\n let resolved = rawValue;\n\n // Resolve #{$var} interpolations\n resolved = resolved.replace(/#\\{(\\$[\\w-]+)\\}/g, (_, varName) => {\n const val = scssVars.get(varName);\n return val !== undefined\n ? resolveTokenValue(val, scssVars, cssVarValues, depth + 1)\n : `#{${varName}}`;\n });\n\n // Resolve standalone $var references (not inside #{})\n resolved = resolved.replace(/(?<![#\\{])(\\$[\\w-]+)/g, (_, varName) => {\n const val = scssVars.get(varName);\n return val !== undefined\n ? resolveTokenValue(val, scssVars, cssVarValues, depth + 1)\n : varName;\n });\n\n // Resolve var(--token, fallback) — use the referenced token value or fallback\n resolved = resolved.replace(\n /var\\((--[\\w-]+)(?:\\s*,\\s*(.+?))?\\)/g,\n (original, tokenName, fallback) => {\n const tokenVal = cssVarValues.get(tokenName);\n if (tokenVal !== undefined) {\n return resolveTokenValue(tokenVal, scssVars, cssVarValues, depth + 1);\n }\n if (fallback) {\n return resolveTokenValue(fallback.trim(), scssVars, cssVarValues, depth + 1);\n }\n return original;\n }\n );\n\n return resolved;\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 *\n * Also resolves SCSS variable interpolations (e.g., `#{$fui-space-4}` → `16px`)\n * when the SCSS variable definitions are found in the same file content.\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 // First pass: extract SCSS variable declarations for resolution\n const scssVars = extractScssVariables(content);\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 // Second pass: build a CSS custom property → raw value map for cross-references\n const cssVarValues = new Map<string, string>();\n for (const token of tokens) {\n if (token.value) {\n cssVarValues.set(token.name, token.value);\n }\n }\n\n // Third pass: resolve SCSS interpolations and var() references\n for (const token of tokens) {\n if (token.value) {\n const resolved = resolveTokenValue(token.value, scssVars, cssVarValues);\n // Only set resolvedValue if it's different from raw and doesn't still contain unresolved refs\n if (resolved !== token.value && !resolved.includes('#{') && !resolved.includes('$')) {\n token.resolvedValue = resolved;\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 +0,0 @@
1
- {"version":3,"sources":["../src/service/snippet-validation.ts","../src/validators.ts","../src/build.ts","../src/core/token-resolver.ts","../src/core/auto-props.ts","../src/core/graph-extractor.ts","../src/screenshot.ts","../src/diff.ts","../src/analyze.ts"],"sourcesContent":["import ts from 'typescript';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { FragmentsConfig, SnippetPolicyConfig } from '../core/types.js';\nimport { BRAND } from '../core/constants.js';\nimport {\n discoverBlockFiles,\n discoverFragmentFiles,\n extractComponentName,\n type DiscoveredFile,\n} from '../core/node.js';\n\nexport interface SnippetValidationOptions {\n mode?: 'warn' | 'error';\n scope?: 'snippet' | 'snippet+render';\n requireFullSnippet?: boolean;\n allowedExternalModules?: string[];\n componentStart?: string;\n componentLimit?: number;\n}\n\nexport interface SnippetValidationResult {\n errors: Array<{ file: string; message: string }>;\n warnings: Array<{ file: string; message: string }>;\n}\n\ninterface EffectiveSnippetPolicy {\n mode: 'warn' | 'error';\n scope: 'snippet' | 'snippet+render';\n requireFullSnippet: boolean;\n allowedExternalModules: Set<string>;\n componentStart?: string;\n componentLimit?: number;\n}\n\ninterface SourceContext {\n imports: Map<string, string>;\n localComponents: Set<string>;\n}\n\ninterface FileIssue {\n file: string;\n message: string;\n}\n\nconst INTRINSIC_TAGS = new Set([\n 'div',\n 'span',\n 'p',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'main',\n 'section',\n 'article',\n 'aside',\n 'nav',\n 'header',\n 'footer',\n 'ul',\n 'ol',\n 'li',\n 'button',\n 'input',\n 'textarea',\n 'label',\n 'svg',\n 'path',\n]);\n\nconst JSX_TAG_PATTERN = /<\\s*([A-Za-z][A-Za-z0-9.]*)\\b/g;\nconst STYLE_PATTERN = /\\bstyle\\s*=\\s*\\{/;\nconst TRANSPILED_PATTERN = /jsxDEV|_jsx|@__PURE__|\\bfileName\\s*:|\\blineNumber\\s*:|\\bcolumnNumber\\s*:/;\nconst ALIAS_DRIFT_PATTERN = /<\\s*[A-Z][A-Za-z0-9]*(?:Root|2)\\b/;\nconst HAS_IMPORT_PATTERN = /\\bimport\\s+[^;]+\\s+from\\s+['\"][^'\"]+['\"]/;\nconst HAS_JSX_PATTERN = /<\\s*[A-Za-z][A-Za-z0-9.]*\\b/;\n\nconst DEFAULT_POLICY: EffectiveSnippetPolicy = {\n mode: 'warn',\n scope: 'snippet+render',\n requireFullSnippet: true,\n allowedExternalModules: new Set([\n '@phosphor-icons/react',\n 'recharts',\n 'react-day-picker',\n ]),\n};\n\nfunction normalizePolicy(\n configured: SnippetPolicyConfig | undefined,\n overrides: SnippetValidationOptions\n): EffectiveSnippetPolicy {\n const fromConfig: EffectiveSnippetPolicy = {\n mode: configured?.mode ?? DEFAULT_POLICY.mode,\n scope: configured?.scope ?? DEFAULT_POLICY.scope,\n requireFullSnippet: configured?.requireFullSnippet ?? DEFAULT_POLICY.requireFullSnippet,\n allowedExternalModules: new Set(configured?.allowedExternalModules ?? [...DEFAULT_POLICY.allowedExternalModules]),\n componentStart: overrides.componentStart,\n componentLimit: overrides.componentLimit,\n };\n\n if (overrides.mode) fromConfig.mode = overrides.mode;\n if (overrides.scope) fromConfig.scope = overrides.scope;\n if (typeof overrides.requireFullSnippet === 'boolean') {\n fromConfig.requireFullSnippet = overrides.requireFullSnippet;\n }\n if (overrides.allowedExternalModules && overrides.allowedExternalModules.length > 0) {\n fromConfig.allowedExternalModules = new Set(overrides.allowedExternalModules);\n }\n\n return fromConfig;\n}\n\nfunction isFragmentsModule(modulePath: string): boolean {\n return (\n modulePath === '@fragments-sdk/ui'\n || modulePath === '@fragments/ui'\n || modulePath === '.'\n || modulePath === '..'\n || modulePath.startsWith('@/components/')\n || modulePath.startsWith('@components/')\n || modulePath.startsWith('./')\n || modulePath.startsWith('../')\n );\n}\n\nfunction collectSourceContext(sourceFile: ts.SourceFile): SourceContext {\n const imports = new Map<string, string>();\n const localComponents = new Set<string>();\n\n function markLocal(name: string | undefined): void {\n if (!name) return;\n if (/^[A-Z]/.test(name)) {\n localComponents.add(name);\n }\n }\n\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const modulePath = node.moduleSpecifier.text;\n const clause = node.importClause;\n\n if (clause?.name) {\n imports.set(clause.name.text, modulePath);\n }\n\n if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const item of clause.namedBindings.elements) {\n imports.set(item.name.text, modulePath);\n }\n }\n }\n\n if (ts.isFunctionDeclaration(node)) {\n markLocal(node.name?.text);\n }\n\n if (ts.isClassDeclaration(node)) {\n markLocal(node.name?.text);\n }\n\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {\n markLocal(node.name.text);\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return { imports, localComponents };\n}\n\nfunction getJsxTags(code: string): string[] {\n const tags: string[] = [];\n JSX_TAG_PATTERN.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = JSX_TAG_PATTERN.exec(code)) !== null) {\n tags.push(match[1]);\n }\n\n return tags;\n}\n\nfunction rootTagName(tag: string): string {\n return tag.split('.')[0];\n}\n\nfunction parseSnippetImports(snippet: string): Map<string, string> {\n const sourceFile = ts.createSourceFile(\n 'snippet.tsx',\n snippet,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TSX,\n );\n return collectSourceContext(sourceFile).imports;\n}\n\nfunction findDefineCall(sourceFile: ts.SourceFile, name: 'defineFragment' | 'defineBlock'): ts.CallExpression | null {\n let result: ts.CallExpression | null = null;\n\n function visit(node: ts.Node): void {\n if (result) return;\n\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === name) {\n result = node;\n return;\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return result;\n}\n\nfunction findProperty(obj: ts.ObjectLiteralExpression, propertyName: string): ts.Expression | null {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop)) continue;\n if (!ts.isIdentifier(prop.name)) continue;\n if (prop.name.text === propertyName) {\n return prop.initializer;\n }\n }\n\n return null;\n}\n\nfunction readStaticString(expr: ts.Expression | null): string | null {\n if (!expr) return null;\n if (ts.isStringLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) {\n return expr.text;\n }\n return null;\n}\n\nfunction readRenderBody(renderExpr: ts.Expression, sourceFile: ts.SourceFile): string | null {\n if (!ts.isArrowFunction(renderExpr) && !ts.isFunctionExpression(renderExpr)) {\n return null;\n }\n\n const body = renderExpr.body;\n const start = body.getStart(sourceFile);\n const end = body.getEnd();\n return sourceFile.text.slice(start, end).trim();\n}\n\nfunction report(issues: FileIssue[], file: string, message: string): void {\n issues.push({ file, message });\n}\n\nfunction validateRawRules(\n issues: FileIssue[],\n file: string,\n label: string,\n code: string,\n): void {\n if (STYLE_PATTERN.test(code)) {\n report(issues, file, `${label}: inline style usage is not allowed; use Box/Stack/Text props.`);\n }\n\n if (TRANSPILED_PATTERN.test(code)) {\n report(issues, file, `${label}: transpiler output detected (jsxDEV/_jsx/@__PURE__). Use authored snippet source.`);\n }\n\n if (ALIAS_DRIFT_PATTERN.test(code)) {\n report(issues, file, `${label}: alias drift tag detected (*Root/*2). Use canonical component names.`);\n }\n\n const tags = getJsxTags(code);\n const intrinsic = tags\n .map((tag) => rootTagName(tag))\n .filter((tag) => /^[a-z]/.test(tag))\n .map((tag) => tag.toLowerCase())\n .filter((tag) => INTRINSIC_TAGS.has(tag));\n\n if (intrinsic.length > 0) {\n const names = [...new Set(intrinsic)].sort().join(', ');\n report(issues, file, `${label}: raw HTML tags are not allowed (${names}). Use Fragments primitives.`);\n }\n}\n\nfunction validateComponentAllowlist(\n issues: FileIssue[],\n file: string,\n label: string,\n code: string,\n imports: Map<string, string>,\n localComponents: Set<string>,\n policy: EffectiveSnippetPolicy,\n): void {\n const tags = getJsxTags(code);\n const seen = new Set<string>();\n\n for (const tag of tags) {\n const root = rootTagName(tag);\n\n if (seen.has(root)) continue;\n seen.add(root);\n\n if (!/^[A-Z]/.test(root)) {\n continue;\n }\n\n const modulePath = imports.get(root);\n\n if (modulePath) {\n if (isFragmentsModule(modulePath)) {\n continue;\n }\n if (policy.allowedExternalModules.has(modulePath)) {\n continue;\n }\n\n report(\n issues,\n file,\n `${label}: component \"${root}\" comes from \"${modulePath}\" and is not in snippets.allowedExternalModules.`,\n );\n continue;\n }\n\n if (localComponents.has(root)) {\n report(\n issues,\n file,\n `${label}: locally defined JSX component \"${root}\" is not allowed in snippets/renders. Import approved components instead.`,\n );\n continue;\n }\n\n report(\n issues,\n file,\n `${label}: component \"${root}\" is used without an import and is not allowed.`,\n );\n }\n}\n\nfunction validateSnippetString(\n issues: FileIssue[],\n file: string,\n label: string,\n snippet: string,\n policy: EffectiveSnippetPolicy,\n): void {\n validateRawRules(issues, file, label, snippet);\n\n if (policy.requireFullSnippet) {\n if (!HAS_IMPORT_PATTERN.test(snippet)) {\n report(issues, file, `${label}: full snippet required (missing import statement).`);\n }\n\n if (!HAS_JSX_PATTERN.test(snippet)) {\n report(issues, file, `${label}: full snippet required (missing JSX usage).`);\n }\n }\n\n const imports = parseSnippetImports(snippet);\n validateComponentAllowlist(issues, file, label, snippet, imports, new Set(), policy);\n}\n\nfunction validateFragmentSource(\n sourceFile: ts.SourceFile,\n file: string,\n policy: EffectiveSnippetPolicy,\n issues: FileIssue[],\n): void {\n const context = collectSourceContext(sourceFile);\n\n const defineCall = findDefineCall(sourceFile, 'defineFragment');\n if (!defineCall) {\n return;\n }\n\n const arg = defineCall.arguments[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) {\n return;\n }\n\n const variantsExpr = findProperty(arg, 'variants');\n if (!variantsExpr || !ts.isArrayLiteralExpression(variantsExpr)) {\n return;\n }\n\n for (const variantExpr of variantsExpr.elements) {\n if (!ts.isObjectLiteralExpression(variantExpr)) continue;\n\n const name = readStaticString(findProperty(variantExpr, 'name')) ?? 'Unknown';\n const labelPrefix = `variant \"${name}\"`;\n\n const codeExpr = findProperty(variantExpr, 'code');\n const snippet = readStaticString(codeExpr);\n if (snippet) {\n validateSnippetString(issues, file, `${labelPrefix} snippet`, snippet, policy);\n } else {\n report(issues, file, `${labelPrefix}: missing explicit code snippet (variant.code).`);\n }\n\n if (policy.scope === 'snippet+render') {\n const renderExpr = findProperty(variantExpr, 'render');\n if (renderExpr) {\n const renderBody = readRenderBody(renderExpr, sourceFile);\n if (!renderBody) {\n report(issues, file, `${labelPrefix} render: expected a static render function.`);\n continue;\n }\n\n validateRawRules(issues, file, `${labelPrefix} render`, renderBody);\n validateComponentAllowlist(\n issues,\n file,\n `${labelPrefix} render`,\n renderBody,\n context.imports,\n context.localComponents,\n policy,\n );\n }\n }\n }\n}\n\nfunction validateBlockSource(\n sourceFile: ts.SourceFile,\n file: string,\n policy: EffectiveSnippetPolicy,\n issues: FileIssue[],\n): void {\n const defineCall = findDefineCall(sourceFile, 'defineBlock');\n if (!defineCall) {\n return;\n }\n\n const arg = defineCall.arguments[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) {\n return;\n }\n\n const codeExpr = findProperty(arg, 'code');\n const snippet = readStaticString(codeExpr);\n if (!snippet) {\n report(issues, file, 'block snippet: missing static code string.');\n return;\n }\n\n validateSnippetString(issues, file, 'block snippet', snippet, policy);\n}\n\nfunction validateBlockPreviewExamples(\n sourceFile: ts.SourceFile,\n file: string,\n policy: EffectiveSnippetPolicy,\n issues: FileIssue[],\n): void {\n if (policy.scope !== 'snippet+render') {\n return;\n }\n\n const code = sourceFile.text;\n const context = collectSourceContext(sourceFile);\n\n validateRawRules(issues, file, 'block preview render', code);\n validateComponentAllowlist(\n issues,\n file,\n 'block preview render',\n code,\n context.imports,\n context.localComponents,\n policy,\n );\n}\n\nfunction sourceFileFromText(filePath: string, content: string): ts.SourceFile {\n return ts.createSourceFile(\n filePath,\n content,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TSX,\n );\n}\n\nfunction sortAndFilterBatch(\n files: DiscoveredFile[],\n componentStart?: string,\n componentLimit?: number,\n): { selected: DiscoveredFile[]; warning?: string } {\n const getComponentName = (relativePath: string): string => {\n const normalized = relativePath.replace(/\\\\/g, '/');\n const fileName = normalized.split('/').pop() ?? normalized;\n if (fileName.endsWith(BRAND.fileExtension)) {\n return fileName.slice(0, -BRAND.fileExtension.length);\n }\n return extractComponentName(relativePath);\n };\n\n const sorted = [...files].sort((a, b) => {\n const nameA = getComponentName(a.relativePath).toLowerCase();\n const nameB = getComponentName(b.relativePath).toLowerCase();\n return nameA.localeCompare(nameB);\n });\n\n if (!componentStart && !componentLimit) {\n return { selected: sorted };\n }\n\n const startName = componentStart?.toLowerCase();\n let startIndex = 0;\n\n if (startName) {\n const foundIndex = sorted.findIndex((file) => getComponentName(file.relativePath).toLowerCase() === startName);\n if (foundIndex === -1) {\n return {\n selected: [],\n warning: `Component start \"${componentStart}\" not found for snippet validation batch.`,\n };\n }\n startIndex = foundIndex;\n }\n\n const limit = componentLimit && componentLimit > 0 ? componentLimit : sorted.length;\n return {\n selected: sorted.slice(startIndex, startIndex + limit),\n };\n}\n\nasync function findBlockPreviewExamplesFile(configDir: string): Promise<string | null> {\n const candidates = [\n join(configDir, 'apps/docs/src/app/(docs)/blocks/examples/index.tsx'),\n join(configDir, '../apps/docs/src/app/(docs)/blocks/examples/index.tsx'),\n join(configDir, '../../apps/docs/src/app/(docs)/blocks/examples/index.tsx'),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction toValidationResult(policy: EffectiveSnippetPolicy, issues: FileIssue[]): SnippetValidationResult {\n if (policy.mode === 'error') {\n return {\n errors: issues,\n warnings: [],\n };\n }\n\n return {\n errors: [],\n warnings: issues,\n };\n}\n\n/**\n * Validate snippet and render policy for fragments, blocks, and docs block previews.\n */\nexport async function validateSnippetPolicy(\n config: FragmentsConfig,\n configDir: string,\n options: SnippetValidationOptions = {},\n): Promise<SnippetValidationResult> {\n const policy = normalizePolicy(config.snippets, options);\n const issues: FileIssue[] = [];\n\n const discovered = await discoverFragmentFiles(config, configDir);\n const fragmentFiles = discovered.filter((file) => file.relativePath.endsWith(BRAND.fileExtension));\n\n const batchResult = sortAndFilterBatch(fragmentFiles, policy.componentStart, policy.componentLimit);\n if (batchResult.warning) {\n issues.push({ file: 'snippets', message: batchResult.warning });\n }\n\n for (const file of batchResult.selected) {\n try {\n const content = await readFile(file.absolutePath, 'utf-8');\n const sourceFile = sourceFileFromText(file.relativePath, content);\n validateFragmentSource(sourceFile, file.relativePath, policy, issues);\n } catch (error) {\n issues.push({\n file: file.relativePath,\n message: `Failed to validate fragment snippets: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n const isBatchOnly = Boolean(policy.componentStart || policy.componentLimit);\n if (!isBatchOnly) {\n try {\n const blockFiles = await discoverBlockFiles(configDir, config.exclude);\n for (const file of blockFiles) {\n try {\n const content = await readFile(file.absolutePath, 'utf-8');\n const sourceFile = sourceFileFromText(file.relativePath, content);\n validateBlockSource(sourceFile, file.relativePath, policy, issues);\n } catch (error) {\n issues.push({\n file: file.relativePath,\n message: `Failed to validate block snippets: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n } catch (error) {\n issues.push({\n file: 'blocks',\n message: `Failed to discover block files: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n const blockPreviewFile = await findBlockPreviewExamplesFile(configDir);\n if (blockPreviewFile) {\n try {\n const content = await readFile(blockPreviewFile, 'utf-8');\n const sourceFile = sourceFileFromText(blockPreviewFile, content);\n validateBlockPreviewExamples(sourceFile, blockPreviewFile, policy, issues);\n } catch (error) {\n issues.push({\n file: blockPreviewFile,\n message: `Failed to validate block preview examples: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n }\n\n return toValidationResult(policy, issues);\n}\n","import { fragmentDefinitionSchema, BRAND, type FragmentsConfig } from './core/index.js';\nimport {\n discoverFragmentFiles,\n discoverComponentFiles,\n extractComponentName,\n loadFragmentFile,\n} from './core/node.js';\nimport { validateSnippetPolicy, type SnippetValidationOptions } from './service/snippet-validation.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\nexport interface ValidationError {\n file: string;\n message: string;\n details?: string;\n}\n\nexport interface ValidationWarning {\n file: string;\n message: string;\n}\n\nexport interface ValidationRunOptions {\n snippets?: boolean;\n snippetMode?: 'warn' | 'error';\n componentStart?: string;\n componentLimit?: number;\n}\n\n/**\n * Validate fragment file schema\n */\nexport async function validateSchema(\n config: FragmentsConfig,\n configDir: string\n): Promise<ValidationResult> {\n const files = await discoverFragmentFiles(config, configDir);\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n for (const file of files) {\n try {\n const fragment = await loadFragmentFile(file.absolutePath);\n\n if (!fragment) {\n errors.push({\n file: file.relativePath,\n message: 'No default export found',\n details: `Fragment files must have a default export from defineFragment()`,\n });\n continue;\n }\n\n const result = fragmentDefinitionSchema.safeParse(fragment);\n\n if (!result.success) {\n const details = result.error.errors\n .map((e) => `${e.path.join('.')}: ${e.message}`)\n .join('; ');\n\n errors.push({\n file: file.relativePath,\n message: 'Invalid fragment schema',\n details,\n });\n }\n } catch (error) {\n errors.push({\n file: file.relativePath,\n message: 'Failed to load fragment file',\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate coverage - ensure all components have fragments\n */\nexport async function validateCoverage(\n config: FragmentsConfig,\n configDir: string\n): Promise<ValidationResult> {\n const fragmentFiles = await discoverFragmentFiles(config, configDir);\n const componentFiles = await discoverComponentFiles(config, configDir);\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n // Build set of documented component names\n const documentedComponents = new Set<string>();\n\n for (const file of fragmentFiles) {\n try {\n const fragment = await loadFragmentFile(file.absolutePath);\n\n if (fragment?.meta?.name) {\n documentedComponents.add(fragment.meta.name);\n }\n } catch {\n // Skip files that fail to load - schema validation will catch these\n }\n }\n\n // Check each component file\n for (const file of componentFiles) {\n const componentName = extractComponentName(file.relativePath);\n\n // Check if there's a corresponding fragment file\n const fragmentPath = file.relativePath.replace(\n /\\.(tsx?|jsx?)$/,\n BRAND.fileExtension\n );\n const hasFragmentFile = fragmentFiles.some(\n (s) => s.relativePath === fragmentPath\n );\n\n if (!hasFragmentFile && !documentedComponents.has(componentName)) {\n warnings.push({\n file: file.relativePath,\n message: `Component \"${componentName}\" has no fragment documentation`,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Run all validations\n */\nexport async function validateAll(\n config: FragmentsConfig,\n configDir: string,\n options: ValidationRunOptions = {}\n): Promise<ValidationResult> {\n const [schemaResult, coverageResult] = await Promise.all([\n validateSchema(config, configDir),\n validateCoverage(config, configDir),\n ]);\n\n if (options.snippets === false) {\n return {\n valid: schemaResult.valid && coverageResult.valid,\n errors: [...schemaResult.errors, ...coverageResult.errors],\n warnings: [...schemaResult.warnings, ...coverageResult.warnings],\n };\n }\n\n const snippetOptions: SnippetValidationOptions = {\n ...(options.snippetMode && { mode: options.snippetMode }),\n ...(options.componentStart && { componentStart: options.componentStart }),\n ...(typeof options.componentLimit === 'number'\n ? { componentLimit: options.componentLimit }\n : {}),\n };\n const snippetResult = await validateSnippetPolicy(config, configDir, snippetOptions);\n\n return {\n valid: schemaResult.valid && coverageResult.valid && snippetResult.errors.length === 0,\n errors: [...schemaResult.errors, ...coverageResult.errors, ...snippetResult.errors],\n warnings: [...schemaResult.warnings, ...coverageResult.warnings, ...snippetResult.warnings],\n };\n}\n\n/**\n * Validate snippet/render policy only.\n */\nexport async function validateSnippets(\n config: FragmentsConfig,\n configDir: string,\n options: ValidationRunOptions = {}\n): Promise<ValidationResult> {\n const snippetResult = await validateSnippetPolicy(config, configDir, {\n ...(options.snippetMode && { mode: options.snippetMode }),\n ...(options.componentStart && { componentStart: options.componentStart }),\n ...(typeof options.componentLimit === 'number'\n ? { componentLimit: options.componentLimit }\n : {}),\n });\n\n return {\n valid: snippetResult.errors.length === 0,\n errors: snippetResult.errors,\n warnings: snippetResult.warnings,\n };\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport type {\n FragmentsConfig,\n CompiledFragmentsFile,\n CompiledFragment,\n CompiledBlock,\n CompiledTokenData,\n} from \"./core/index.js\";\nimport { BRAND, compileBlock, parseTokenFile } from \"./core/index.js\";\nimport { resolveTokensWithSass } from \"./core/token-resolver.js\";\nimport type { BlockDefinition } from \"./core/index.js\";\nimport {\n discoverFragmentFiles,\n discoverBlockFiles,\n discoverTokenFiles,\n parseFragmentFile,\n loadFragmentFile,\n generateRegistry,\n generateContextMd,\n} from \"./core/node.js\";\nimport {\n extractCustomPropsFromComponentFile,\n resolveComponentSourcePath,\n type AutoDetectedPropDefinition,\n} from \"./core/auto-props.js\";\nimport { buildComponentGraph } from \"./core/graph-extractor.js\";\nimport { serializeGraph } from \"@fragments-sdk/context/graph\";\n\ntype CompiledProp = CompiledFragment[\"props\"][string];\n\nfunction normalizeParsedProps(\n parsedProps: Record<string, Partial<CompiledProp>>\n): Record<string, CompiledProp> {\n return Object.fromEntries(\n Object.entries(parsedProps).map(([name, prop]) => [\n name,\n {\n type: prop.type ?? \"custom\",\n description: prop.description ?? \"\",\n default: prop.default,\n required: prop.required,\n values: prop.values,\n constraints: prop.constraints,\n },\n ])\n );\n}\n\nfunction mergeDocumentedAndAutoProps(\n documentedProps: Record<string, CompiledProp>,\n autoProps: Record<string, AutoDetectedPropDefinition>\n): Record<string, CompiledProp> {\n return Object.fromEntries(\n Object.keys(autoProps).map((name) => {\n const documented = documentedProps[name];\n const auto = autoProps[name];\n\n return [\n name,\n {\n type: auto.type,\n description: documented?.description ?? auto.description ?? \"\",\n default: auto.default !== undefined ? auto.default : documented?.default,\n required: auto.required,\n values: auto.values ?? documented?.values,\n constraints: documented?.constraints,\n },\n ];\n })\n );\n}\n\nexport interface BuildResult {\n success: boolean;\n outputPath: string;\n fragmentCount: number;\n errors: Array<{ file: string; error: string }>;\n warnings: Array<{ file: string; warning: string }>;\n}\n\n/**\n * Build compiled fragments.json file for AI consumption.\n *\n * Uses AST parsing to extract metadata WITHOUT executing fragment files.\n * This means the build works without any project dependencies installed.\n */\nexport async function buildFragments(\n config: FragmentsConfig,\n configDir: string\n): Promise<BuildResult> {\n const files = await discoverFragmentFiles(config, configDir);\n const errors: Array<{ file: string; error: string }> = [];\n const warnings: Array<{ file: string; warning: string }> = [];\n const fragments: CompiledFragmentsFile[\"fragments\"] = {};\n\n for (const file of files) {\n try {\n // Read file content as text\n const content = await readFile(file.absolutePath, \"utf-8\");\n\n // Parse using AST (no execution)\n const parsed = parseFragmentFile(content, file.relativePath);\n\n // Collect warnings\n for (const warning of parsed.warnings) {\n warnings.push({ file: file.relativePath, warning });\n }\n\n // Check for required fields\n if (!parsed.meta.name) {\n errors.push({\n file: file.relativePath,\n error: \"Missing meta.name in fragment definition\",\n });\n continue;\n }\n\n const documentedProps = normalizeParsedProps(parsed.props);\n let mergedProps = documentedProps;\n\n const componentExportName = parsed.componentName ?? parsed.meta.name;\n const componentSourcePath = resolveComponentSourcePath(\n file.absolutePath,\n parsed.componentImport\n );\n\n if (componentExportName && componentSourcePath) {\n const autoPropsResult = extractCustomPropsFromComponentFile(\n componentSourcePath,\n componentExportName\n );\n\n for (const warning of autoPropsResult.warnings) {\n warnings.push({ file: file.relativePath, warning });\n }\n\n const hasAutoProps = Object.keys(autoPropsResult.props).length > 0;\n if (autoPropsResult.resolved && hasAutoProps) {\n const removedDocumentedProps = Object.keys(documentedProps).filter(\n (propName) => !(propName in autoPropsResult.props)\n );\n\n if (removedDocumentedProps.length > 0) {\n warnings.push({\n file: file.relativePath,\n warning: `Removed ${removedDocumentedProps.length} documented props not present in source API: ${removedDocumentedProps.join(\", \")}`,\n });\n }\n\n mergedProps = mergeDocumentedAndAutoProps(\n documentedProps,\n autoPropsResult.props\n );\n } else if (autoPropsResult.resolved && !hasAutoProps && Object.keys(documentedProps).length > 0) {\n warnings.push({\n file: file.relativePath,\n warning: \"Auto-props extraction returned no custom props; falling back to documented props\",\n });\n }\n } else if (!componentExportName) {\n warnings.push({\n file: file.relativePath,\n warning: \"Unable to resolve component export name for auto-props extraction\",\n });\n } else if (!componentSourcePath) {\n warnings.push({\n file: file.relativePath,\n warning: `Unable to resolve component source path from import: ${parsed.componentImport ?? \"unknown\"}`,\n });\n }\n\n // Build compiled fragment from parsed metadata\n const compiled: CompiledFragment = {\n filePath: file.relativePath,\n meta: {\n name: parsed.meta.name,\n description: parsed.meta.description ?? \"\",\n category: parsed.meta.category ?? \"Uncategorized\",\n status: parsed.meta.status,\n tags: parsed.meta.tags,\n since: parsed.meta.since,\n ...(parsed.meta.dependencies && { dependencies: parsed.meta.dependencies }),\n figma: parsed.meta.figma,\n },\n usage: {\n when: parsed.usage.when ?? [],\n whenNot: parsed.usage.whenNot ?? [],\n guidelines: parsed.usage.guidelines,\n accessibility: parsed.usage.accessibility,\n },\n props: mergedProps,\n relations: parsed.relations.map((rel) => ({\n component: rel.component,\n relationship: rel.relationship as\n | \"alternative\"\n | \"sibling\"\n | \"parent\"\n | \"child\"\n | \"composition\",\n note: rel.note,\n })),\n variants: parsed.variants.map((v) => ({\n name: v.name,\n description: v.description,\n ...(v.code && { code: v.code }),\n ...(v.figma && { figma: v.figma }),\n ...(v.args && { args: v.args }),\n })),\n // Include AI metadata if present\n ...(parsed.ai && { ai: parsed.ai }),\n // Include contract metadata if present\n ...(parsed.contract && { contract: parsed.contract }),\n };\n\n fragments[parsed.meta.name] = compiled;\n } catch (error) {\n errors.push({\n file: file.relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Discover and compile block files\n const blocks: Record<string, CompiledBlock> = {};\n try {\n const blockFiles = await discoverBlockFiles(configDir, config.exclude);\n for (const file of blockFiles) {\n try {\n // loadFragmentFile uses esbuild to bundle+evaluate, returns default export\n // CJS/ESM interop may double-wrap the default export\n let raw = await loadFragmentFile(file.absolutePath) as unknown as Record<string, unknown> | null;\n // Unwrap double-default from CJS interop\n if (raw && 'default' in raw && typeof raw.default === 'object') {\n raw = raw.default as Record<string, unknown>;\n }\n const def = raw;\n if (def && typeof def === 'object' && 'name' in def && 'code' in def && 'components' in def) {\n const compiled = compileBlock(def as unknown as BlockDefinition, file.relativePath);\n blocks[compiled.name] = compiled;\n }\n } catch (error) {\n warnings.push({\n file: file.relativePath,\n warning: `Failed to load block: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n } catch {\n // Block discovery failure is non-fatal\n }\n\n // Discover and extract design tokens from SCSS/CSS files\n let tokens: CompiledTokenData | undefined;\n try {\n const tokenPatterns = config.tokens?.include;\n const tokenFiles = await discoverTokenFiles(configDir, tokenPatterns, config.exclude);\n if (tokenFiles.length > 0) {\n // Merge tokens from all discovered files\n const mergedCategories: Record<string, Array<{ name: string; value?: string; description?: string }>> = {};\n let prefix = '--';\n let total = 0;\n\n // Read all file contents first for cross-file SCSS variable resolution\n const fileContents: Array<{ content: string; path: string }> = [];\n for (const file of tokenFiles) {\n const content = await readFile(file.absolutePath, 'utf-8');\n fileContents.push({ content, path: file.relativePath });\n }\n\n // Concatenate all contents so parseTokenFile can resolve SCSS vars across files\n const allContent = fileContents.map((f) => f.content).join('\\n');\n\n for (const { content, path } of fileContents) {\n // Parse with the combined content to enable cross-file SCSS var resolution\n const parsed = parseTokenFile(allContent, path);\n // But only use tokens from THIS file's content to avoid duplicates\n const fileParsed = parseTokenFile(content, path);\n prefix = fileParsed.prefix;\n total += fileParsed.total;\n for (const [cat, catTokens] of Object.entries(fileParsed.categories)) {\n if (!mergedCategories[cat]) {\n mergedCategories[cat] = [];\n }\n for (const t of catTokens) {\n // Deduplicate by name\n if (!mergedCategories[cat].some((e) => e.name === t.name)) {\n // Use resolved value from the combined parse if available\n const combinedToken = Object.values(parsed.categories)\n .flat()\n .find((ct) => ct.name === t.name);\n const resolvedValue = combinedToken?.resolvedValue ?? t.resolvedValue;\n\n mergedCategories[cat].push({\n name: t.name,\n ...(resolvedValue\n ? { value: resolvedValue }\n : t.value ? { value: t.value } : {}),\n description: t.description,\n });\n }\n }\n }\n }\n\n // Sass compilation fallback: resolve tokens the regex parser couldn't handle\n if (total > 0) {\n const allTokens = Object.values(mergedCategories).flat();\n const unresolved = allTokens.filter(\n t => t.value && (t.value.includes('#{') || t.value.includes('$'))\n );\n\n if (unresolved.length > 0 && tokenFiles.length > 0) {\n // Determine the tokens directory from the first discovered file\n const tokensDir = resolve(configDir, tokenFiles[0].relativePath, '..');\n const sassResolved = await resolveTokensWithSass(\n unresolved as Array<{ name: string; value: string }>,\n tokensDir,\n );\n\n // Merge sass-resolved values back into the categories\n if (sassResolved.size > 0) {\n for (const catTokens of Object.values(mergedCategories)) {\n for (const token of catTokens) {\n const resolved = sassResolved.get(token.name);\n if (resolved && token.value && (token.value.includes('#{') || token.value.includes('$'))) {\n token.value = resolved;\n }\n }\n }\n }\n }\n\n tokens = { prefix, total, categories: mergedCategories };\n }\n }\n } catch {\n // Token extraction failure is non-fatal\n }\n\n // Read package name for import statements\n let packageName: string | undefined;\n const pkgJsonPath = resolve(configDir, \"package.json\");\n if (existsSync(pkgJsonPath)) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, \"utf-8\"));\n if (pkg.name) packageName = pkg.name;\n } catch {\n // Non-fatal\n }\n }\n\n // Build component graph for AI structural queries\n // Derive component directory from configDir (typically src/components/)\n const componentDir = resolve(configDir, \"src\", \"components\");\n let graphData: ReturnType<typeof serializeGraph> | undefined;\n try {\n const graphResult = await buildComponentGraph(fragments, blocks, componentDir);\n\n // Auto-enrich fragments with detected metadata\n for (const [name, fragment] of Object.entries(fragments)) {\n const detected = graphResult.autoDetected.get(name);\n if (!detected) continue;\n\n if (!fragment.ai) fragment.ai = {};\n if (!fragment.ai.subComponents && detected.subComponents) {\n fragment.ai.subComponents = detected.subComponents;\n }\n if (!fragment.ai.compositionPattern && detected.compositionPattern) {\n fragment.ai.compositionPattern = detected.compositionPattern;\n }\n if (!fragment.ai.commonPatterns && detected.commonPatterns) {\n fragment.ai.commonPatterns = detected.commonPatterns;\n }\n if (!fragment.ai.requiredChildren && detected.requiredChildren) {\n fragment.ai.requiredChildren = detected.requiredChildren;\n }\n }\n\n // Report drift warnings\n for (const w of graphResult.warnings) {\n warnings.push({ file: \"graph\", warning: w });\n }\n\n graphData = serializeGraph(graphResult.graph);\n } catch (error) {\n warnings.push({\n file: \"graph\",\n warning: `Graph extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n const output: CompiledFragmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n ...(packageName && { packageName }),\n fragments,\n ...(Object.keys(blocks).length > 0 && { blocks }),\n ...(tokens && { tokens }),\n ...(graphData && { graph: graphData }),\n };\n\n const outputPath = resolve(configDir, config.outFile ?? BRAND.outFile);\n await writeFile(outputPath, JSON.stringify(output));\n\n return {\n success: errors.length === 0,\n outputPath,\n fragmentCount: Object.keys(fragments).length,\n errors,\n warnings,\n };\n}\n\n/**\n * Result of building the .fragments directory\n */\nexport interface FragmentsBuildResult {\n success: boolean;\n indexPath: string;\n registryPath: string;\n contextPath: string;\n componentCount: number;\n errors: Array<{ file: string; error: string }>;\n warnings: Array<{ file: string; warning: string }>;\n}\n\n/**\n * Build the .fragments/ directory with index.json, registry.json, and context.md\n *\n * This generates:\n * - .fragments/index.json - Minimal name → path mapping (tiny, for quick lookups)\n * - .fragments/registry.json - Component index with paths and enrichment references\n * - .fragments/context.md - AI-ready consolidated context file\n */\nexport async function buildFragmentsDir(\n config: FragmentsConfig,\n configDir: string\n): Promise<FragmentsBuildResult> {\n const fragmentsDir = join(configDir, BRAND.dataDir);\n const componentsDir = join(fragmentsDir, BRAND.componentsDir);\n\n // Create directories\n await mkdir(fragmentsDir, { recursive: true });\n await mkdir(componentsDir, { recursive: true });\n\n // Generate registry with config options\n const registryResult = await generateRegistry({\n projectRoot: configDir,\n componentPatterns: config.components || [\"src/**/*.tsx\", \"src/**/*.ts\"],\n storyPatterns: config.include || [\"src/**/*.stories.tsx\"],\n fragmentsDir,\n registryOptions: config.registry || {},\n });\n\n const errors = [...registryResult.errors];\n const warnings = [...registryResult.warnings];\n\n // Write index.json (minimal name → path)\n const indexPath = join(fragmentsDir, \"index.json\");\n await writeFile(indexPath, JSON.stringify(registryResult.index, null, 2));\n\n // Write registry.json (full metadata)\n const registryPath = join(fragmentsDir, BRAND.registryFile);\n await writeFile(registryPath, JSON.stringify(registryResult.registry, null, 2));\n\n // Generate context.md - focus on semantic knowledge, skip props (AI can read source)\n const contextResult = generateContextMd(registryResult.registry, {\n format: \"markdown\",\n compact: false,\n include: {\n props: false, // AI can read TypeScript directly\n relations: true,\n code: false,\n },\n });\n\n // Write context.md\n const contextPath = join(fragmentsDir, BRAND.contextFile);\n await writeFile(contextPath, contextResult.content);\n\n return {\n success: errors.length === 0,\n indexPath,\n registryPath,\n contextPath,\n componentCount: registryResult.registry.componentCount,\n errors,\n warnings,\n };\n}\n","/**\n * Token Resolver — resolves unresolved SCSS token values using actual sass compilation.\n *\n * The regex-based resolver in token-parser.ts cannot handle SCSS module namespaces,\n * functions (color.scale, math.div), or map lookups. This module provides a fallback\n * that compiles the actual SCSS sources to extract computed CSS custom property values.\n *\n * Used at build time only — no runtime sass dependency in the MCP server.\n */\n\nimport { resolve, dirname, basename } from 'node:path';\nimport { existsSync, readdirSync } from 'node:fs';\n\n/**\n * Round fractional RGB channel values produced by Sass color math.\n *\n * Sass functions like color.scale() and color.adjust() can produce\n * fractional values like rgb(217.8, 217.8, 217.8). This normalizes\n * them to clean integers: rgb(218, 218, 218).\n *\n * Alpha channels in rgba() are preserved as-is (they're legitimately fractional).\n */\nfunction roundRgbValues(value: string): string {\n return value\n .replace(\n /rgb\\(([^)]+)\\)/g,\n (_full, inner: string) => {\n const parts = inner.split(',').map(p => p.trim());\n const rounded = parts.map(p => {\n const num = parseFloat(p);\n return isNaN(num) ? p : String(Math.round(num));\n });\n return `rgb(${rounded.join(', ')})`;\n },\n )\n .replace(\n /rgba\\(([^)]+)\\)/g,\n (_full, inner: string) => {\n const parts = inner.split(',').map(p => p.trim());\n // Round RGB channels (first 3), preserve alpha as-is\n const rounded = parts.map((p, i) => {\n if (i >= 3) return p; // alpha channel — don't round\n const num = parseFloat(p);\n return isNaN(num) ? p : String(Math.round(num));\n });\n return `rgba(${rounded.join(', ')})`;\n },\n );\n}\n\n/**\n * Resolve unresolved SCSS token values by compiling the project's token SCSS.\n *\n * Generates a temporary SCSS string that imports the project's _variables.scss\n * and includes the fui-css-variables mixin, then compiles it with sass to extract\n * the actual computed values for all CSS custom properties.\n *\n * @param unresolvedTokens - Tokens with values containing #{} or $ that need resolution\n * @param tokensDir - Absolute path to the directory containing _variables.scss\n * @returns Map of token name → resolved CSS value (only for tokens that were unresolved)\n */\nexport async function resolveTokensWithSass(\n unresolvedTokens: Array<{ name: string; value: string }>,\n tokensDir: string,\n): Promise<Map<string, string>> {\n const resolvedMap = new Map<string, string>();\n\n // Filter to only tokens that actually need resolution\n const needsResolution = unresolvedTokens.filter(\n t => t.value.includes('#{') || t.value.includes('$'),\n );\n\n if (needsResolution.length === 0) {\n return resolvedMap;\n }\n\n try {\n // Dynamic import so sass is only loaded when needed (build-time only)\n const sass = await import('sass');\n\n // Find the _variables.scss file and determine the mixin name\n const variablesPath = findVariablesFile(tokensDir);\n if (!variablesPath) {\n return resolvedMap;\n }\n\n // Determine the module name for @use (filename without _ prefix and .scss suffix)\n const fileName = basename(variablesPath);\n const moduleName = fileName.replace(/^_/, '').replace(/\\.scss$/, '');\n\n // Generate a SCSS string that imports the variables and includes the mixin\n const scssSource = `\n@use '${moduleName}' as vars;\n:root { @include vars.fui-css-variables; }\n`;\n\n // Compile the SCSS with the tokens directory as a load path\n const compiled = sass.compileString(scssSource, {\n loadPaths: [tokensDir, dirname(tokensDir)],\n style: 'expanded',\n // Suppress sass deprecation warnings during build\n logger: { warn() {}, debug() {} } as never,\n });\n\n // Parse the compiled CSS for --fui-* custom property declarations\n const cssVarRegex = /(--[\\w-]+)\\s*:\\s*([^;]+)/g;\n let match: RegExpExecArray | null;\n const allResolved = new Map<string, string>();\n\n while ((match = cssVarRegex.exec(compiled.css)) !== null) {\n allResolved.set(match[1], roundRgbValues(match[2].trim()));\n }\n\n // Only return values for the tokens that were originally unresolved\n for (const token of needsResolution) {\n const value = allResolved.get(token.name);\n if (value !== undefined) {\n resolvedMap.set(token.name, value);\n }\n }\n } catch {\n // Sass compilation failure is non-fatal — fall back to regex-resolved values\n }\n\n return resolvedMap;\n}\n\n/**\n * Find the _variables.scss file in the tokens directory.\n */\nfunction findVariablesFile(tokensDir: string): string | null {\n const candidates = ['_variables.scss', 'variables.scss'];\n for (const name of candidates) {\n const path = resolve(tokensDir, name);\n if (existsSync(path)) {\n return path;\n }\n }\n\n // Fallback: look for any SCSS file containing 'css-variables' mixin\n try {\n const files = readdirSync(tokensDir).filter(f => f.endsWith('.scss'));\n for (const file of files) {\n const path = resolve(tokensDir, file);\n // We just need to find it exists; the @use import will handle the rest\n if (file.includes('variables') || file.includes('tokens')) {\n return path;\n }\n }\n } catch {\n // Directory read failure\n }\n\n return null;\n}\n","import { existsSync, statSync } from \"node:fs\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport ts from \"typescript\";\nimport type { PropDefinition } from \"./types.js\";\n\nexport interface AutoDetectedPropDefinition {\n type: PropDefinition[\"type\"];\n description: string;\n required: boolean;\n default?: unknown;\n values?: readonly string[];\n}\n\nexport interface AutoPropsExtractionResult {\n props: Record<string, AutoDetectedPropDefinition>;\n warnings: string[];\n resolved: boolean;\n}\n\ninterface ResolvedComponentSignature {\n propsTypeNode: ts.TypeNode | null;\n componentNode: ts.FunctionLikeDeclarationBase | null;\n}\n\nfunction toPosixPath(filePath: string): string {\n return filePath.replace(/\\\\/g, \"/\");\n}\n\nfunction isFile(filePath: string): boolean {\n if (!existsSync(filePath)) return false;\n try {\n return statSync(filePath).isFile();\n } catch {\n return false;\n }\n}\n\nfunction resolveModulePath(basePath: string): string | null {\n const candidates: string[] = [];\n const extension = extname(basePath);\n\n if (extension) {\n candidates.push(basePath);\n } else {\n candidates.push(\n `${basePath}.tsx`,\n `${basePath}.ts`,\n `${basePath}.jsx`,\n `${basePath}.js`,\n join(basePath, \"index.tsx\"),\n join(basePath, \"index.ts\"),\n join(basePath, \"index.jsx\"),\n join(basePath, \"index.js\")\n );\n }\n\n for (const candidate of candidates) {\n if (isFile(candidate)) {\n return resolve(candidate);\n }\n }\n\n return null;\n}\n\n/**\n * Resolve a component source file from the fragment file path + component import path.\n * Supports relative imports like \".\", \"./Button\", \"../components/Button\".\n */\nexport function resolveComponentSourcePath(\n fragmentFileAbsolutePath: string,\n componentImportPath: string | null\n): string | null {\n if (!componentImportPath) return null;\n if (!componentImportPath.startsWith(\".\")) return null;\n\n const fragmentDir = dirname(fragmentFileAbsolutePath);\n const basePath = resolve(fragmentDir, componentImportPath);\n return resolveModulePath(basePath);\n}\n\nfunction collectTopLevelDeclarations(sourceFile: ts.SourceFile): {\n typeDeclarations: Map<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>;\n functionDeclarations: Map<string, ts.FunctionDeclaration>;\n variableDeclarations: Map<string, ts.VariableDeclaration>;\n} {\n const typeDeclarations = new Map<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>();\n const functionDeclarations = new Map<string, ts.FunctionDeclaration>();\n const variableDeclarations = new Map<string, ts.VariableDeclaration>();\n\n for (const node of sourceFile.statements) {\n if (ts.isInterfaceDeclaration(node)) {\n typeDeclarations.set(node.name.text, node);\n continue;\n }\n\n if (ts.isTypeAliasDeclaration(node)) {\n typeDeclarations.set(node.name.text, node);\n continue;\n }\n\n if (ts.isFunctionDeclaration(node) && node.name) {\n functionDeclarations.set(node.name.text, node);\n continue;\n }\n\n if (ts.isVariableStatement(node)) {\n for (const declaration of node.declarationList.declarations) {\n if (ts.isIdentifier(declaration.name)) {\n variableDeclarations.set(declaration.name.text, declaration);\n }\n }\n }\n }\n\n return { typeDeclarations, functionDeclarations, variableDeclarations };\n}\n\nfunction readDefaultValue(expression: ts.Expression): unknown {\n if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) {\n return expression.text;\n }\n\n if (ts.isNumericLiteral(expression)) {\n return Number(expression.text);\n }\n\n if (expression.kind === ts.SyntaxKind.TrueKeyword) return true;\n if (expression.kind === ts.SyntaxKind.FalseKeyword) return false;\n if (expression.kind === ts.SyntaxKind.NullKeyword) return null;\n\n if (\n ts.isPrefixUnaryExpression(expression) &&\n expression.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(expression.operand)\n ) {\n return -Number(expression.operand.text);\n }\n\n return undefined;\n}\n\nfunction extractDefaultValues(\n componentNode: ts.FunctionLikeDeclarationBase | null\n): Record<string, unknown> {\n const defaults: Record<string, unknown> = {};\n if (!componentNode?.parameters?.length) return defaults;\n\n const firstParam = componentNode.parameters[0];\n if (!ts.isObjectBindingPattern(firstParam.name)) return defaults;\n\n for (const element of firstParam.name.elements) {\n let propName: string | null = null;\n\n if (element.propertyName) {\n if (ts.isIdentifier(element.propertyName) || ts.isStringLiteral(element.propertyName)) {\n propName = element.propertyName.text;\n }\n } else if (ts.isIdentifier(element.name)) {\n propName = element.name.text;\n }\n\n if (!propName || !element.initializer) continue;\n\n const value = readDefaultValue(element.initializer);\n if (value !== undefined) {\n defaults[propName] = value;\n }\n }\n\n return defaults;\n}\n\nfunction isNullishType(type: ts.Type): boolean {\n return (\n (type.flags & ts.TypeFlags.Null) !== 0 ||\n (type.flags & ts.TypeFlags.Undefined) !== 0 ||\n (type.flags & ts.TypeFlags.Void) !== 0\n );\n}\n\nfunction isBooleanLikeType(type: ts.Type): boolean {\n return (\n (type.flags & ts.TypeFlags.BooleanLike) !== 0 ||\n type.flags === ts.TypeFlags.BooleanLiteral\n );\n}\n\nfunction inferPropType(\n type: ts.Type,\n checker: ts.TypeChecker\n): Pick<AutoDetectedPropDefinition, \"type\" | \"values\"> {\n const typeText = checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation);\n\n if (typeText.includes(\"ReactNode\")) {\n return { type: \"node\" };\n }\n if (typeText.includes(\"ReactElement\") || typeText.includes(\"JSX.Element\")) {\n return { type: \"element\" };\n }\n\n if (type.getCallSignatures().length > 0) {\n return { type: \"function\" };\n }\n\n if (checker.isArrayType(type) || checker.isTupleType(type)) {\n return { type: \"array\" };\n }\n\n if (type.isUnion()) {\n const nonNullableTypes = type.types.filter((unionType) => !isNullishType(unionType));\n\n if (nonNullableTypes.length === 1) {\n return inferPropType(nonNullableTypes[0], checker);\n }\n\n const stringLiteralValues = nonNullableTypes\n .filter((unionType) => (unionType.flags & ts.TypeFlags.StringLiteral) !== 0)\n .map((unionType) => (unionType as ts.StringLiteralType).value);\n\n if (stringLiteralValues.length > 0 && stringLiteralValues.length === nonNullableTypes.length) {\n return { type: \"enum\", values: stringLiteralValues };\n }\n\n if (nonNullableTypes.every((unionType) => isBooleanLikeType(unionType))) {\n return { type: \"boolean\" };\n }\n\n return { type: \"union\" };\n }\n\n if ((type.flags & ts.TypeFlags.StringLike) !== 0) {\n return { type: \"string\" };\n }\n if ((type.flags & ts.TypeFlags.NumberLike) !== 0) {\n return { type: \"number\" };\n }\n if ((type.flags & ts.TypeFlags.BooleanLike) !== 0) {\n return { type: \"boolean\" };\n }\n\n if ((type.flags & ts.TypeFlags.Object) !== 0) {\n return { type: \"object\" };\n }\n\n return { type: \"custom\" };\n}\n\nfunction resolveComponentSignature(\n exportName: string,\n declarations: ReturnType<typeof collectTopLevelDeclarations>,\n sourceFile: ts.SourceFile\n): ResolvedComponentSignature {\n const visitedNames = new Set<string>();\n\n const typeNodeFromFunction = (\n node: ts.FunctionLikeDeclarationBase\n ): ResolvedComponentSignature => ({\n propsTypeNode: node.parameters[0]?.type ?? null,\n componentNode: node,\n });\n\n const resolveFromExpression = (expression: ts.Expression): ResolvedComponentSignature => {\n if (ts.isParenthesizedExpression(expression)) {\n return resolveFromExpression(expression.expression);\n }\n if (ts.isAsExpression(expression) || ts.isTypeAssertionExpression(expression)) {\n return resolveFromExpression(expression.expression);\n }\n if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {\n return typeNodeFromFunction(expression);\n }\n if (ts.isIdentifier(expression)) {\n return resolveFromIdentifier(expression.text);\n }\n\n if (ts.isCallExpression(expression)) {\n if (\n ts.isPropertyAccessExpression(expression.expression) &&\n expression.expression.name.text === \"forwardRef\"\n ) {\n const forwardRefPropsType = expression.typeArguments?.[1] ?? null;\n const innerArg = expression.arguments[0];\n const inner = innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))\n ? typeNodeFromFunction(innerArg)\n : innerArg && ts.isIdentifier(innerArg)\n ? resolveFromIdentifier(innerArg.text)\n : { propsTypeNode: null, componentNode: null };\n\n return {\n propsTypeNode: forwardRefPropsType ?? inner.propsTypeNode,\n componentNode: inner.componentNode,\n };\n }\n\n if (\n ts.isPropertyAccessExpression(expression.expression) &&\n expression.expression.name.text === \"memo\" &&\n expression.arguments[0]\n ) {\n return resolveFromExpression(expression.arguments[0]);\n }\n\n if (\n ts.isPropertyAccessExpression(expression.expression) &&\n expression.expression.expression.getText(sourceFile) === \"Object\" &&\n expression.expression.name.text === \"assign\" &&\n expression.arguments[0]\n ) {\n return resolveFromExpression(expression.arguments[0]);\n }\n }\n\n return { propsTypeNode: null, componentNode: null };\n };\n\n const resolveFromVariable = (declaration: ts.VariableDeclaration): ResolvedComponentSignature => {\n if (\n declaration.type &&\n ts.isTypeReferenceNode(declaration.type) &&\n declaration.type.typeArguments?.length\n ) {\n const typeName = declaration.type.typeName.getText(sourceFile);\n if (typeName.includes(\"FC\") || typeName.includes(\"FunctionComponent\")) {\n const componentNode =\n declaration.initializer &&\n (ts.isArrowFunction(declaration.initializer) || ts.isFunctionExpression(declaration.initializer))\n ? declaration.initializer\n : null;\n\n return {\n propsTypeNode: declaration.type.typeArguments[0] ?? null,\n componentNode,\n };\n }\n }\n\n if (declaration.initializer) {\n return resolveFromExpression(declaration.initializer);\n }\n\n return { propsTypeNode: null, componentNode: null };\n };\n\n const resolveFromIdentifier = (name: string): ResolvedComponentSignature => {\n if (!name || visitedNames.has(name)) {\n return { propsTypeNode: null, componentNode: null };\n }\n visitedNames.add(name);\n\n const functionDeclaration = declarations.functionDeclarations.get(name);\n if (functionDeclaration) {\n return typeNodeFromFunction(functionDeclaration);\n }\n\n const variableDeclaration = declarations.variableDeclarations.get(name);\n if (variableDeclaration) {\n return resolveFromVariable(variableDeclaration);\n }\n\n return { propsTypeNode: null, componentNode: null };\n };\n\n return resolveFromIdentifier(exportName);\n}\n\n/**\n * Extract custom component props from a source file.\n * Custom props are identified as props whose declarations originate from the component's source file.\n */\nexport function extractCustomPropsFromComponentFile(\n componentFilePath: string,\n exportName: string\n): AutoPropsExtractionResult {\n const warnings: string[] = [];\n const resolvedPath = resolve(componentFilePath);\n\n if (!existsSync(resolvedPath)) {\n return {\n props: {},\n warnings: [`Component file not found: ${resolvedPath}`],\n resolved: false,\n };\n }\n\n const compilerOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n jsx: ts.JsxEmit.ReactJSX,\n allowSyntheticDefaultImports: true,\n esModuleInterop: true,\n skipLibCheck: true,\n strict: false,\n noEmit: true,\n };\n\n const program = ts.createProgram([resolvedPath], compilerOptions);\n const sourceFile = program.getSourceFile(resolvedPath);\n if (!sourceFile) {\n return {\n props: {},\n warnings: [`Unable to parse component source: ${resolvedPath}`],\n resolved: false,\n };\n }\n\n const checker = program.getTypeChecker();\n const declarations = collectTopLevelDeclarations(sourceFile);\n const signature = resolveComponentSignature(exportName, declarations, sourceFile);\n\n if (!signature.propsTypeNode) {\n return {\n props: {},\n warnings: [`Unable to resolve props type for export: ${exportName}`],\n resolved: false,\n };\n }\n\n const propsType = checker.getTypeFromTypeNode(signature.propsTypeNode);\n const defaultValues = extractDefaultValues(signature.componentNode);\n const sourceFilePath = toPosixPath(sourceFile.fileName);\n\n const extractedProps: Record<string, AutoDetectedPropDefinition> = {};\n for (const symbol of checker.getPropertiesOfType(propsType)) {\n const propName = symbol.getName();\n if (propName.startsWith(\"_\") || propName.startsWith(\"$\")) {\n continue;\n }\n\n const declarationsForSymbol = symbol.getDeclarations() ?? [];\n const localDeclarations = declarationsForSymbol.filter(\n (declaration) => toPosixPath(declaration.getSourceFile().fileName) === sourceFilePath\n );\n\n if (localDeclarations.length === 0) {\n continue;\n }\n\n const referenceNode = localDeclarations[0];\n const inferredType = inferPropType(checker.getTypeOfSymbolAtLocation(symbol, referenceNode), checker);\n const description = ts\n .displayPartsToString(symbol.getDocumentationComment(checker))\n .trim();\n\n extractedProps[propName] = {\n type: inferredType.type,\n description,\n required: (symbol.getFlags() & ts.SymbolFlags.Optional) === 0,\n ...(inferredType.values && { values: inferredType.values }),\n ...(defaultValues[propName] !== undefined && { default: defaultValues[propName] }),\n };\n }\n\n if (Object.keys(extractedProps).length === 0) {\n warnings.push(`Resolved props type for ${exportName}, but no local custom props were found`);\n }\n\n return {\n props: extractedProps,\n warnings,\n resolved: true,\n };\n}\n","/**\n * Graph extraction pipeline — builds the ComponentGraph from source code,\n * fragment metadata, and block definitions.\n *\n * Absorbs and enhances the logic from importAnalyzer.ts:\n * - Import detection (PascalCase component imports)\n * - Hook dependency detection (useX() calls)\n * - Object.assign sub-component detection\n * - JSX usage in variant code\n * - Block co-occurrence\n * - Fragment relation mapping\n * - Auto-detection of requiredChildren and commonPatterns\n */\n\nimport ts from 'typescript';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, join, basename } from 'node:path';\nimport { readdirSync } from 'node:fs';\nimport type {\n ComponentGraph,\n ComponentNode,\n GraphEdge,\n GraphEdgeType,\n GraphHealth,\n} from '@fragments-sdk/context/graph';\nimport { EDGE_TYPE_WEIGHTS, computeHealthFromData } from '@fragments-sdk/context/graph';\nimport type { CompiledFragment, CompiledBlock } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface GraphBuildOptions {\n /** Skip source-code AST analysis (for testing with mock data) */\n skipSourceAnalysis?: boolean;\n}\n\nexport interface GraphBuildResult {\n graph: ComponentGraph;\n /** Auto-detected metadata keyed by component name */\n autoDetected: Map<string, AutoDetectedMetadata>;\n /** Warnings about drift between manual declarations and auto-detected values */\n warnings: string[];\n}\n\nexport interface AutoDetectedMetadata {\n subComponents?: string[];\n compositionPattern?: 'compound' | 'simple' | 'controlled';\n commonPatterns?: string[];\n requiredChildren?: string[];\n}\n\n/**\n * Build the full ComponentGraph from fragments, blocks, and source code.\n */\nexport async function buildComponentGraph(\n fragments: Record<string, CompiledFragment>,\n blocks: Record<string, CompiledBlock>,\n componentDir: string,\n options?: GraphBuildOptions,\n): Promise<GraphBuildResult> {\n const knownComponents = new Set(Object.keys(fragments));\n const allEdges: GraphEdge[] = [];\n const autoDetected = new Map<string, AutoDetectedMetadata>();\n const warnings: string[] = [];\n\n // 1. Extract edges from source code (imports, hooks, sub-components)\n if (!options?.skipSourceAnalysis) {\n const sourceEdges = extractImportAndHookEdges(componentDir, knownComponents);\n allEdges.push(...sourceEdges);\n\n const subComponentResults = extractSubComponents(componentDir, knownComponents);\n for (const [name, subs] of subComponentResults) {\n autoDetected.set(name, {\n ...autoDetected.get(name),\n subComponents: subs,\n compositionPattern: subs.length > 0 ? 'compound' : 'simple',\n });\n }\n }\n\n // 2. Extract JSX usage from variant code\n const jsxEdges = extractJsxUsageEdges(fragments, knownComponents);\n allEdges.push(...jsxEdges);\n\n // 3. Extract block co-occurrence edges\n const blockEdges = extractBlockEdges(blocks);\n allEdges.push(...blockEdges);\n\n // 4. Extract relation edges from fragment metadata\n const relationEdges = extractRelationEdges(fragments);\n allEdges.push(...relationEdges);\n\n // 5. Infer requiredChildren\n const requiredChildrenMap = inferRequiredChildren(fragments, autoDetected);\n for (const [name, children] of requiredChildrenMap) {\n const existing = autoDetected.get(name) ?? {};\n autoDetected.set(name, { ...existing, requiredChildren: children });\n }\n\n // 6. Generate common patterns\n const patternsMap = generateCommonPatterns(fragments, autoDetected);\n for (const [name, patterns] of patternsMap) {\n const existing = autoDetected.get(name) ?? {};\n autoDetected.set(name, { ...existing, commonPatterns: patterns });\n }\n\n // 7. Merge and deduplicate edges\n const mergedEdges = mergeAndDeduplicate(allEdges);\n\n // 8. Build nodes\n const nodes: ComponentNode[] = Object.entries(fragments).map(([name, fragment]) => {\n const detected = autoDetected.get(name);\n return {\n name,\n category: fragment.meta.category,\n status: fragment.meta.status ?? 'stable',\n compositionPattern: fragment.ai?.compositionPattern ?? detected?.compositionPattern,\n subComponents: fragment.ai?.subComponents ?? detected?.subComponents,\n };\n });\n\n // 9. Build block index for health computation\n const blockIndex = new Map<string, string[]>();\n for (const [blockName, block] of Object.entries(blocks)) {\n for (const comp of block.components) {\n const existing = blockIndex.get(comp);\n if (existing) existing.push(blockName);\n else blockIndex.set(comp, [blockName]);\n }\n }\n\n // 10. Compute health\n const health = computeHealthFromData(nodes, mergedEdges, blockIndex);\n\n // 11. Generate drift warnings\n for (const [name, fragment] of Object.entries(fragments)) {\n const detected = autoDetected.get(name);\n if (!detected) continue;\n\n // Sub-components drift\n if (fragment.ai?.subComponents && detected.subComponents) {\n const declared = new Set(fragment.ai.subComponents);\n const found = new Set(detected.subComponents);\n const missing = detected.subComponents.filter(s => !declared.has(s));\n const extra = fragment.ai.subComponents.filter(s => !found.has(s));\n\n if (missing.length > 0) {\n warnings.push(\n `${name}: declares ${declared.size} subComponents but code has ${found.size}. ` +\n `Missing from declaration: ${missing.join(', ')}`\n );\n }\n if (extra.length > 0) {\n warnings.push(\n `${name}: declares subComponents [${extra.join(', ')}] not found in Object.assign`\n );\n }\n }\n }\n\n return {\n graph: { nodes, edges: mergedEdges, health },\n autoDetected,\n warnings,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Extraction functions\n// ---------------------------------------------------------------------------\n\n/**\n * Parse index.tsx files for import declarations and hook calls.\n * Returns import edges and hook-depends edges.\n */\nexport function extractImportAndHookEdges(\n componentDir: string,\n knownComponents: Set<string>,\n): GraphEdge[] {\n const edges: GraphEdge[] = [];\n\n for (const componentName of knownComponents) {\n const indexPath = findComponentIndex(componentDir, componentName);\n if (!indexPath) continue;\n\n let sourceText: string;\n try {\n sourceText = readFileSync(indexPath, 'utf-8');\n } catch {\n continue;\n }\n\n const sourceFile = ts.createSourceFile(\n indexPath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n indexPath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n\n // Walk AST for imports and hook calls\n const visitNode = (node: ts.Node) => {\n // Import declarations\n if (ts.isImportDeclaration(node)) {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) {\n const importPath = moduleSpecifier.text;\n // Only relative imports\n if (importPath.startsWith('.') || importPath.startsWith('/')) {\n const clause = node.importClause;\n if (clause) {\n // Default import\n if (clause.name && isPascalCase(clause.name.text) && knownComponents.has(clause.name.text)) {\n edges.push({\n source: componentName,\n target: clause.name.text,\n type: 'imports',\n weight: EDGE_TYPE_WEIGHTS['imports'],\n provenance: `source:${componentName}/index.tsx`,\n });\n }\n // Named imports\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const element of clause.namedBindings.elements) {\n const name = element.name.text;\n if (isPascalCase(name) && knownComponents.has(name) && name !== componentName) {\n edges.push({\n source: componentName,\n target: name,\n type: 'imports',\n weight: EDGE_TYPE_WEIGHTS['imports'],\n provenance: `source:${componentName}/index.tsx`,\n });\n }\n }\n }\n }\n }\n }\n }\n\n // Hook calls: useX() where X is a known component\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {\n const callName = node.expression.text;\n const hookMatch = callName.match(/^use([A-Z][a-zA-Z]*)$/);\n if (hookMatch) {\n const hookTarget = hookMatch[1];\n if (knownComponents.has(hookTarget) && hookTarget !== componentName) {\n edges.push({\n source: componentName,\n target: hookTarget,\n type: 'hook-depends',\n weight: EDGE_TYPE_WEIGHTS['hook-depends'],\n provenance: `source:${componentName}/index.tsx`,\n });\n }\n }\n }\n\n ts.forEachChild(node, visitNode);\n };\n\n ts.forEachChild(sourceFile, visitNode);\n }\n\n return edges;\n}\n\n/**\n * Detect Object.assign(Root, { Sub1, Sub2 }) patterns in index.tsx files.\n * Returns a map of component name → sub-component names.\n */\nexport function extractSubComponents(\n componentDir: string,\n knownComponents: Set<string>,\n): Map<string, string[]> {\n const result = new Map<string, string[]>();\n\n for (const componentName of knownComponents) {\n const indexPath = findComponentIndex(componentDir, componentName);\n if (!indexPath) continue;\n\n let sourceText: string;\n try {\n sourceText = readFileSync(indexPath, 'utf-8');\n } catch {\n continue;\n }\n\n // Quick regex check first for performance\n if (!sourceText.includes('Object.assign')) continue;\n\n const sourceFile = ts.createSourceFile(\n indexPath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n indexPath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n\n const subComponents: string[] = [];\n\n const visitNode = (node: ts.Node) => {\n // Look for Object.assign(X, { A, B, C })\n if (\n ts.isCallExpression(node) &&\n ts.isPropertyAccessExpression(node.expression) &&\n ts.isIdentifier(node.expression.expression) &&\n node.expression.expression.text === 'Object' &&\n node.expression.name.text === 'assign' &&\n node.arguments.length >= 2\n ) {\n const propsArg = node.arguments[1];\n if (ts.isObjectLiteralExpression(propsArg)) {\n for (const prop of propsArg.properties) {\n if (ts.isShorthandPropertyAssignment(prop)) {\n subComponents.push(prop.name.text);\n } else if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n subComponents.push(prop.name.text);\n }\n }\n }\n }\n ts.forEachChild(node, visitNode);\n };\n\n ts.forEachChild(sourceFile, visitNode);\n\n if (subComponents.length > 0) {\n result.set(componentName, subComponents);\n }\n }\n\n return result;\n}\n\n/**\n * Scan variant code strings for JSX element names → renders edges.\n */\nexport function extractJsxUsageEdges(\n fragments: Record<string, CompiledFragment>,\n knownComponents: Set<string>,\n): GraphEdge[] {\n const edges: GraphEdge[] = [];\n const jsxTagRegex = /<([A-Z][a-zA-Z]*(?:\\.[A-Z][a-zA-Z]*)?)/g;\n\n for (const [name, fragment] of Object.entries(fragments)) {\n const usedComponents = new Set<string>();\n\n for (const variant of fragment.variants) {\n if (!variant.code) continue;\n\n let match: RegExpExecArray | null;\n jsxTagRegex.lastIndex = 0;\n while ((match = jsxTagRegex.exec(variant.code)) !== null) {\n let tagName = match[1];\n // Handle compound: Header.Nav → Header\n if (tagName.includes('.')) {\n tagName = tagName.split('.')[0];\n }\n if (knownComponents.has(tagName) && tagName !== name) {\n usedComponents.add(tagName);\n }\n }\n }\n\n for (const target of usedComponents) {\n edges.push({\n source: name,\n target,\n type: 'renders',\n weight: EDGE_TYPE_WEIGHTS['renders'],\n provenance: `variant:${name}`,\n });\n }\n }\n\n return edges;\n}\n\n/**\n * Create composes edges from block component lists (pairwise).\n */\nexport function extractBlockEdges(\n blocks: Record<string, CompiledBlock>,\n): GraphEdge[] {\n const edges: GraphEdge[] = [];\n\n for (const [blockName, block] of Object.entries(blocks)) {\n const components = block.components;\n // Create pairwise edges (avoid duplicates by only going i < j)\n for (let i = 0; i < components.length; i++) {\n for (let j = i + 1; j < components.length; j++) {\n edges.push({\n source: components[i],\n target: components[j],\n type: 'composes',\n weight: EDGE_TYPE_WEIGHTS['composes'],\n provenance: `block:${blockName}`,\n });\n }\n }\n }\n\n return edges;\n}\n\n/**\n * Map fragment ComponentRelation[] to typed graph edges.\n */\nexport function extractRelationEdges(\n fragments: Record<string, CompiledFragment>,\n): GraphEdge[] {\n const edges: GraphEdge[] = [];\n\n const relationToEdgeType: Record<string, GraphEdgeType> = {\n parent: 'parent-of',\n child: 'parent-of', // reversed: if A declares child B, edge is A parent-of B\n composition: 'composes',\n alternative: 'alternative-to',\n sibling: 'sibling-of',\n };\n\n for (const [name, fragment] of Object.entries(fragments)) {\n if (!fragment.relations) continue;\n\n for (const rel of fragment.relations) {\n const edgeType = relationToEdgeType[rel.relationship];\n if (!edgeType) continue;\n\n // For 'child' relation, source is the current component (parent)\n // For 'parent' relation, source is the related component\n let source: string;\n let target: string;\n\n if (rel.relationship === 'parent') {\n source = rel.component;\n target = name;\n } else {\n source = name;\n target = rel.component;\n }\n\n edges.push({\n source,\n target,\n type: edgeType,\n weight: EDGE_TYPE_WEIGHTS[edgeType],\n note: rel.note,\n provenance: 'relation',\n });\n }\n }\n\n return edges;\n}\n\n/**\n * Infer requiredChildren: sub-components that appear in ALL variant code strings.\n */\nexport function inferRequiredChildren(\n fragments: Record<string, CompiledFragment>,\n autoDetected: Map<string, AutoDetectedMetadata>,\n): Map<string, string[]> {\n const result = new Map<string, string[]>();\n\n for (const [name, fragment] of Object.entries(fragments)) {\n const detected = autoDetected.get(name);\n const subs = detected?.subComponents ?? fragment.ai?.subComponents;\n if (!subs || subs.length === 0) continue;\n\n const variantsWithCode = fragment.variants.filter(v => v.code);\n if (variantsWithCode.length === 0) continue;\n\n const required: string[] = [];\n for (const sub of subs) {\n // Check if this sub-component appears in ALL variants\n const inAll = variantsWithCode.every(v => {\n // Match <ComponentName.SubName or just <SubName\n const patterns = [\n new RegExp(`<${name}\\\\.${sub}[\\\\s/>]`),\n new RegExp(`<${sub}[\\\\s/>]`),\n ];\n return patterns.some(p => p.test(v.code!));\n });\n if (inAll) required.push(sub);\n }\n\n if (required.length > 0) {\n result.set(name, required);\n }\n }\n\n return result;\n}\n\n/**\n * Generate simplified JSX skeleton patterns from variant code.\n */\nexport function generateCommonPatterns(\n fragments: Record<string, CompiledFragment>,\n autoDetected: Map<string, AutoDetectedMetadata>,\n): Map<string, string[]> {\n const result = new Map<string, string[]>();\n\n for (const [name, fragment] of Object.entries(fragments)) {\n const detected = autoDetected.get(name);\n const subs = detected?.subComponents ?? fragment.ai?.subComponents;\n if (!subs || subs.length === 0) continue;\n\n // Build a simplified pattern from the first variant that has code\n const firstVariant = fragment.variants.find(v => v.code);\n if (!firstVariant?.code) continue;\n\n // Extract used sub-components from the code\n const usedSubs: string[] = [];\n for (const sub of subs) {\n const patterns = [\n new RegExp(`<${name}\\\\.${sub}`),\n new RegExp(`<${sub}[\\\\s/>]`),\n ];\n if (patterns.some(p => p.test(firstVariant.code!))) {\n usedSubs.push(sub);\n }\n }\n\n if (usedSubs.length > 0) {\n const pattern = `<${name}>\\n${usedSubs.map(s => ` <${name}.${s}>...</${name}.${s}>`).join('\\n')}\\n</${name}>`;\n result.set(name, [pattern]);\n }\n }\n\n return result;\n}\n\n/**\n * Merge edges: key by (source, target, type), keep highest weight.\n */\nexport function mergeAndDeduplicate(edges: GraphEdge[]): GraphEdge[] {\n const edgeMap = new Map<string, GraphEdge>();\n\n for (const edge of edges) {\n const key = `${edge.source}→${edge.target}:${edge.type}`;\n const existing = edgeMap.get(key);\n if (!existing || edge.weight > existing.weight) {\n edgeMap.set(key, edge);\n }\n }\n\n return [...edgeMap.values()];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isPascalCase(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name);\n}\n\n/**\n * Find the index.tsx file for a component in the component directory.\n */\nfunction findComponentIndex(componentDir: string, componentName: string): string | null {\n // Try direct path: componentDir/ComponentName/index.tsx\n const candidates = [\n join(componentDir, componentName, 'index.tsx'),\n join(componentDir, componentName, 'index.ts'),\n join(componentDir, componentName, `${componentName}.tsx`),\n join(componentDir, componentName, `${componentName}.ts`),\n ];\n\n // Also search within subdirectories matching the component structure\n // e.g., src/components/ComponentName/index.tsx\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n // Try scanning componentDir for directories matching the component name\n try {\n const entries = readdirSync(componentDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && entry.name === componentName) {\n const subCandidates = [\n join(componentDir, entry.name, 'index.tsx'),\n join(componentDir, entry.name, 'index.ts'),\n ];\n for (const sc of subCandidates) {\n if (existsSync(sc)) return sc;\n }\n }\n }\n } catch {\n // Directory might not exist\n }\n\n return null;\n}\n","import pc from 'picocolors';\nimport {\n BRAND,\n DEFAULTS,\n type FragmentsConfig,\n type FragmentDefinition,\n type Theme,\n} from './core/index.js';\nimport { discoverFragmentFiles, loadFragmentFile } from './core/node.js';\nimport {\n BrowserPool,\n CaptureEngine,\n StorageManager,\n formatMs,\n type CaptureOptions,\n} from './service/index.js';\n\n/**\n * Options for the screenshot command\n */\nexport interface ScreenshotCommandOptions {\n /** Specific component to capture */\n component?: string;\n\n /** Specific variant to capture */\n variant?: string;\n\n /** Theme to capture */\n theme?: Theme;\n\n /** Update existing baselines */\n update?: boolean;\n\n /** CI mode - no interactive prompts */\n ci?: boolean;\n\n /** Viewport width */\n width?: number;\n\n /** Viewport height */\n height?: number;\n}\n\n/**\n * Result of the screenshot command\n */\nexport interface ScreenshotResult {\n success: boolean;\n captured: number;\n skipped: number;\n errors: Array<{ component: string; variant: string; error: string }>;\n totalTimeMs: number;\n}\n\n/**\n * Execute the screenshot command\n */\nexport async function runScreenshotCommand(\n config: FragmentsConfig,\n configDir: string,\n options: ScreenshotCommandOptions = {}\n): Promise<ScreenshotResult> {\n const startTime = Date.now();\n const errors: ScreenshotResult['errors'] = [];\n\n // Initialize storage\n const storage = new StorageManager({\n projectRoot: configDir,\n viewport: options.width && options.height\n ? { width: options.width, height: options.height }\n : config.screenshots?.viewport,\n });\n await storage.initialize();\n\n // Discover fragments\n const fragmentFiles = await discoverFragmentFiles(config, configDir);\n\n if (fragmentFiles.length === 0) {\n console.log(pc.yellow('No fragment files found.'));\n return {\n success: true,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Load all fragments\n const fragments: Array<{ path: string; fragment: FragmentDefinition }> = [];\n\n for (const file of fragmentFiles) {\n try {\n const fragment = await loadFragmentFile(file.absolutePath);\n if (fragment) {\n fragments.push({ path: file.relativePath, fragment });\n }\n } catch (error) {\n errors.push({\n component: file.relativePath,\n variant: '',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Filter by component if specified\n const filteredFragments = options.component\n ? fragments.filter((s) => s.fragment.meta.name === options.component)\n : fragments;\n\n if (options.component && filteredFragments.length === 0) {\n console.log(pc.yellow(`Component \"${options.component}\" not found.`));\n return {\n success: false,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Build list of variants to capture\n const variantsToCapture: Array<{\n component: string;\n variant: string;\n render: () => unknown;\n }> = [];\n\n for (const { fragment } of filteredFragments) {\n const variants = options.variant\n ? fragment.variants.filter((v) => v.name === options.variant)\n : fragment.variants;\n\n for (const variant of variants) {\n variantsToCapture.push({\n component: fragment.meta.name,\n variant: variant.name,\n render: variant.render,\n });\n }\n }\n\n if (variantsToCapture.length === 0) {\n console.log(pc.yellow('No variants to capture.'));\n return {\n success: true,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Determine theme\n const theme: Theme = options.theme ?? DEFAULTS.theme;\n const viewport = {\n width: options.width ?? config.screenshots?.viewport?.width ?? DEFAULTS.viewport.width,\n height: options.height ?? config.screenshots?.viewport?.height ?? DEFAULTS.viewport.height,\n };\n\n console.log(pc.cyan(`\\n${BRAND.name} Screenshot\\n`));\n console.log(pc.dim(`Capturing variants (theme: ${theme}, viewport: ${viewport.width}x${viewport.height}):\\n`));\n\n // Initialize browser pool\n const pool = new BrowserPool({\n viewport,\n });\n\n // Create capture engine - use the viewer URL\n const viewerPort = DEFAULTS.port;\n const baseUrl = `http://localhost:${viewerPort}`;\n const captureEngine = new CaptureEngine(pool, baseUrl);\n\n let captured = 0;\n let skipped = 0;\n\n const captureOptions: CaptureOptions = {\n theme,\n viewport,\n delay: config.screenshots?.delay ?? DEFAULTS.captureDelayMs,\n };\n\n try {\n // Warm up the pool\n console.log(pc.dim('Starting browser...'));\n await pool.warmup();\n console.log(pc.dim('Browser ready.\\n'));\n\n // Capture each variant\n for (const { component, variant } of variantsToCapture) {\n const hasExisting = storage.hasBaseline(component, variant, theme);\n\n // Skip if exists and not updating\n if (hasExisting && !options.update) {\n console.log(` ${pc.dim('○')} ${component}/${variant} ${pc.dim('(skipped)')}`);\n skipped++;\n continue;\n }\n\n try {\n const screenshot = await captureEngine.captureVariant(\n component,\n variant,\n captureOptions\n );\n\n await storage.saveBaseline(screenshot);\n\n const totalTime = screenshot.metadata.renderTimeMs + screenshot.metadata.captureTimeMs;\n console.log(\n ` ${pc.green('✓')} ${component}/${variant} ${pc.dim(formatMs(totalTime))}`\n );\n captured++;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.log(` ${pc.red('✗')} ${component}/${variant} ${pc.dim(errorMsg)}`);\n errors.push({ component, variant, error: errorMsg });\n }\n }\n } finally {\n // Shutdown browser pool\n await pool.shutdown();\n }\n\n const totalTimeMs = Date.now() - startTime;\n\n // Print summary\n console.log();\n if (errors.length === 0) {\n console.log(pc.green(`✓ Captured ${captured} screenshot(s) in ${formatMs(totalTimeMs)}`));\n } else {\n console.log(pc.yellow(`⚠ Captured ${captured} screenshot(s) with ${errors.length} error(s)`));\n }\n\n if (skipped > 0) {\n console.log(pc.dim(` ${skipped} skipped (use --update to recapture)`));\n }\n\n console.log(pc.dim(` Stored in ${storage.screenshotsDirPath}\\n`));\n\n return {\n success: errors.length === 0,\n captured,\n skipped,\n errors,\n totalTimeMs,\n };\n}\n","import pc from 'picocolors';\nimport {\n BRAND,\n DEFAULTS,\n type FragmentsConfig,\n type FragmentDefinition,\n type Theme,\n} from './core/index.js';\nimport { discoverFragmentFiles, loadFragmentFile } from './core/node.js';\nimport {\n BrowserPool,\n CaptureEngine,\n StorageManager,\n DiffEngine,\n formatMs,\n type CaptureOptions,\n type DiffResult,\n} from './service/index.js';\n\n/**\n * Options for the diff command\n */\nexport interface DiffCommandOptions {\n /** Specific component to diff */\n component?: string;\n\n /** Specific variant to diff */\n variant?: string;\n\n /** Theme to compare */\n theme?: Theme;\n\n /** CI mode - exit 1 on differences */\n ci?: boolean;\n\n /** Diff threshold percentage */\n threshold?: number;\n\n /** Open diff images */\n open?: boolean;\n}\n\n/**\n * Single diff result with metadata\n */\nexport interface VariantDiffResult {\n component: string;\n variant: string;\n theme: Theme;\n result: DiffResult;\n diffImagePath?: string;\n}\n\n/**\n * Result of the diff command\n */\nexport interface DiffCommandResult {\n success: boolean;\n total: number;\n passed: number;\n failed: number;\n missing: number;\n results: VariantDiffResult[];\n totalTimeMs: number;\n}\n\n/**\n * Execute the diff command\n */\nexport async function runDiffCommand(\n config: FragmentsConfig,\n configDir: string,\n options: DiffCommandOptions = {}\n): Promise<DiffCommandResult> {\n const startTime = Date.now();\n const results: VariantDiffResult[] = [];\n\n // Initialize storage\n const storage = new StorageManager({\n projectRoot: configDir,\n viewport: config.screenshots?.viewport,\n });\n await storage.initialize();\n\n // Initialize diff engine\n const threshold = options.threshold ?? config.screenshots?.threshold ?? DEFAULTS.diffThreshold;\n const diffEngine = new DiffEngine(threshold);\n\n // Discover fragments\n const fragmentFiles = await discoverFragmentFiles(config, configDir);\n\n if (fragmentFiles.length === 0) {\n console.log(pc.yellow('No fragment files found.'));\n return {\n success: true,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Load all fragments\n const fragments: Array<{ path: string; fragment: FragmentDefinition }> = [];\n\n for (const file of fragmentFiles) {\n try {\n const fragment = await loadFragmentFile(file.absolutePath);\n if (fragment) {\n fragments.push({ path: file.relativePath, fragment });\n }\n } catch {\n // Skip failed loads\n }\n }\n\n // Filter by component if specified\n const filteredFragments = options.component\n ? fragments.filter((s) => s.fragment.meta.name === options.component)\n : fragments;\n\n if (options.component && filteredFragments.length === 0) {\n console.log(pc.yellow(`Component \"${options.component}\" not found.`));\n return {\n success: false,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Build list of variants to diff\n const variantsToDiff: Array<{\n component: string;\n variant: string;\n }> = [];\n\n for (const { fragment } of filteredFragments) {\n const variants = options.variant\n ? fragment.variants.filter((v) => v.name === options.variant)\n : fragment.variants;\n\n for (const variant of variants) {\n variantsToDiff.push({\n component: fragment.meta.name,\n variant: variant.name,\n });\n }\n }\n\n if (variantsToDiff.length === 0) {\n console.log(pc.yellow('No variants to compare.'));\n return {\n success: true,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Determine theme\n const theme: Theme = options.theme ?? DEFAULTS.theme;\n const viewport = config.screenshots?.viewport ?? DEFAULTS.viewport;\n\n console.log(pc.cyan(`\\n${BRAND.name} Diff\\n`));\n console.log(pc.dim(`Comparing against baselines (theme: ${theme}, threshold: ${threshold}%):\\n`));\n\n // Initialize browser pool\n const pool = new BrowserPool({\n viewport,\n });\n\n // Create capture engine\n const viewerPort = DEFAULTS.port;\n const baseUrl = `http://localhost:${viewerPort}`;\n const captureEngine = new CaptureEngine(pool, baseUrl);\n\n let passed = 0;\n let failed = 0;\n let missing = 0;\n\n const captureOptions: CaptureOptions = {\n theme,\n viewport,\n delay: config.screenshots?.delay ?? DEFAULTS.captureDelayMs,\n };\n\n try {\n // Warm up the pool\n await pool.warmup();\n\n // Compare each variant\n for (const { component, variant } of variantsToDiff) {\n // Load baseline\n const baseline = await storage.loadBaseline(component, variant, theme);\n\n if (!baseline) {\n console.log(\n ` ${pc.yellow('?')} ${component}/${variant} ${pc.dim('(no baseline)')}`\n );\n missing++;\n continue;\n }\n\n try {\n // Capture current\n const current = await captureEngine.captureVariant(\n component,\n variant,\n captureOptions\n );\n\n // Quick hash check\n if (diffEngine.areIdentical(current, baseline)) {\n console.log(` ${pc.green('✓')} ${component}/${variant} ${pc.dim('0.0%')}`);\n results.push({\n component,\n variant,\n theme,\n result: {\n matches: true,\n diffPercentage: 0,\n diffPixelCount: 0,\n totalPixels: current.viewport.width * current.viewport.height,\n changedRegions: [],\n diffTimeMs: 0,\n },\n });\n passed++;\n continue;\n }\n\n // Full diff\n const diffResult = diffEngine.compare(current, baseline, { threshold });\n\n if (diffResult.matches) {\n console.log(\n ` ${pc.green('✓')} ${component}/${variant} ${pc.dim(`${diffResult.diffPercentage}%`)}`\n );\n passed++;\n } else {\n // Save diff image\n let diffImagePath: string | undefined;\n if (diffResult.diffImage) {\n diffImagePath = await storage.saveDiff(\n component,\n variant,\n theme,\n diffResult.diffImage\n );\n }\n\n console.log(\n ` ${pc.red('✗')} ${component}/${variant} ${pc.yellow(`${diffResult.diffPercentage}%`)}` +\n (diffImagePath ? pc.dim(` → ${diffImagePath}`) : '')\n );\n failed++;\n\n results.push({\n component,\n variant,\n theme,\n result: diffResult,\n diffImagePath,\n });\n continue;\n }\n\n results.push({\n component,\n variant,\n theme,\n result: diffResult,\n });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.log(` ${pc.red('!')} ${component}/${variant} ${pc.dim(errorMsg)}`);\n failed++;\n }\n }\n } finally {\n // Shutdown browser pool\n await pool.shutdown();\n }\n\n const totalTimeMs = Date.now() - startTime;\n const total = passed + failed + missing;\n\n // Print summary\n console.log();\n if (failed === 0 && missing === 0) {\n console.log(pc.green(`✓ All ${passed} variant(s) match baselines`));\n } else if (failed > 0) {\n console.log(pc.red(`✗ ${failed} variant(s) differ from baselines`));\n }\n\n if (missing > 0) {\n console.log(pc.yellow(` ${missing} variant(s) have no baseline (run \\`${BRAND.cliCommand} screenshot\\`)`));\n }\n\n console.log(pc.dim(` Completed in ${formatMs(totalTimeMs)}\\n`));\n\n // In CI mode, exit with error if any failed\n const success = failed === 0;\n\n return {\n success,\n total,\n passed,\n failed,\n missing,\n results,\n totalTimeMs,\n };\n}\n","/**\n * CLI command: fragments analyze\n *\n * Analyzes the design system and generates an HTML report with:\n * - Component inventory\n * - Documentation coverage\n * - Quality insights\n * - Actionable recommendations\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport pc from \"picocolors\";\nimport type { FragmentsConfig, CompiledFragmentsFile } from \"./core/index.js\";\nimport { BRAND, DEFAULTS } from \"./core/index.js\";\nimport {\n analyzeDesignSystem,\n generateHtmlReport,\n getGrade,\n getScoreColor,\n type DesignSystemAnalytics,\n} from \"./service/index.js\";\n\nexport interface AnalyzeOptions {\n /** Output format */\n format?: \"html\" | \"json\" | \"console\";\n /** Output file path (default: fragments-report.html) */\n output?: string;\n /** Open report in browser after generation */\n open?: boolean;\n /** CI mode - exit with appropriate code */\n ci?: boolean;\n /** Minimum score to pass in CI mode */\n minScore?: number;\n}\n\nexport interface AnalyzeResult {\n success: boolean;\n analytics: DesignSystemAnalytics;\n outputPath?: string;\n}\n\n/**\n * Run the analyze command\n */\nexport async function runAnalyzeCommand(\n config: FragmentsConfig,\n configDir: string,\n options: AnalyzeOptions = {}\n): Promise<AnalyzeResult> {\n const format = options.format ?? \"html\";\n const minScore = options.minScore ?? 0;\n\n console.log(pc.cyan(`\\n${BRAND.name} Analyzer\\n`));\n\n // Load compiled fragments\n const fragmentsPath = join(configDir, config.outFile ?? \"fragments.json\");\n\n if (!existsSync(fragmentsPath)) {\n console.log(pc.red(`✗ No fragments.json found. Run \\`${BRAND.cliCommand} build\\` first.\\n`));\n return {\n success: false,\n analytics: createEmptyAnalytics(),\n };\n }\n\n console.log(pc.dim(\"Analyzing design system...\\n\"));\n\n const content = await readFile(fragmentsPath, \"utf-8\");\n const data: CompiledFragmentsFile = JSON.parse(content);\n\n // Run analysis\n const analytics = analyzeDesignSystem(data);\n\n // Print summary to console\n printConsoleSummary(analytics);\n\n // Generate output based on format\n let outputPath: string | undefined;\n\n if (format === \"html\" || format === \"json\") {\n outputPath = options.output ?? getDefaultOutputPath(format, configDir);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n if (format === \"html\") {\n const html = generateHtmlReport(analytics);\n await writeFile(outputPath, html);\n console.log(pc.green(`✓ Report generated: ${outputPath}\\n`));\n } else {\n await writeFile(outputPath, JSON.stringify(analytics, null, 2));\n console.log(pc.green(`✓ JSON report generated: ${outputPath}\\n`));\n }\n\n // Open in browser if requested\n if (options.open && format === \"html\") {\n await openInBrowser(outputPath);\n }\n }\n\n // CI mode - check score\n const passedCi = analytics.summary.overallScore >= minScore;\n\n if (options.ci) {\n if (passedCi) {\n console.log(\n pc.green(`✓ Score ${analytics.summary.overallScore} meets minimum threshold ${minScore}\\n`)\n );\n } else {\n console.log(\n pc.red(\n `✗ Score ${analytics.summary.overallScore} below minimum threshold ${minScore}\\n`\n )\n );\n }\n }\n\n return {\n success: !options.ci || passedCi,\n analytics,\n outputPath,\n };\n}\n\n/**\n * Print a summary to the console\n */\nfunction printConsoleSummary(analytics: DesignSystemAnalytics): void {\n const { summary, coverage, recommendations } = analytics;\n const grade = getGrade(summary.overallScore);\n\n // Score header\n console.log(\n pc.bold(\n `Overall Score: ${colorizeScore(summary.overallScore)} (${grade})\\n`\n )\n );\n\n // Summary stats\n console.log(pc.dim(\"Summary\"));\n console.log(` Components: ${pc.white(summary.totalComponents.toString())}`);\n console.log(` Variants: ${pc.white(summary.totalVariants.toString())}`);\n console.log(` Props: ${pc.white(summary.totalProps.toString())}`);\n console.log(` Categories: ${pc.white(summary.categories.join(\", \"))}`);\n console.log();\n\n // Coverage\n console.log(pc.dim(\"Coverage\"));\n console.log(` Description: ${formatCoverage(coverage.fields.description)}`);\n console.log(` Usage when: ${formatCoverage(coverage.fields.usageWhen)}`);\n console.log(` Usage whenNot:${formatCoverage(coverage.fields.usageWhenNot)}`);\n console.log(` Guidelines: ${formatCoverage(coverage.fields.guidelines)}`);\n console.log(` Relations: ${formatCoverage(coverage.fields.relations)}`);\n console.log();\n\n // Top recommendations\n if (recommendations.length > 0) {\n console.log(pc.dim(\"Top Recommendations\"));\n for (const rec of recommendations.slice(0, 3)) {\n const priority = rec.priority === \"high\"\n ? pc.red(`[${rec.priority}]`)\n : rec.priority === \"medium\"\n ? pc.yellow(`[${rec.priority}]`)\n : pc.dim(`[${rec.priority}]`);\n console.log(` ${priority} ${rec.title}`);\n }\n console.log();\n }\n}\n\n/**\n * Format coverage percentage with color\n */\nfunction formatCoverage(field: { percentage: number; covered: number; total: number }): string {\n const pct = colorizeScore(field.percentage);\n return `${pct} (${field.covered}/${field.total})`;\n}\n\n/**\n * Colorize a score\n */\nfunction colorizeScore(score: number): string {\n if (score >= 80) return pc.green(`${score}%`);\n if (score >= 60) return pc.yellow(`${score}%`);\n return pc.red(`${score}%`);\n}\n\n/**\n * Get default output path\n */\nfunction getDefaultOutputPath(format: \"html\" | \"json\", configDir: string): string {\n const filename = format === \"html\" ? \"fragments-report.html\" : \"fragments-report.json\";\n return join(configDir, filename);\n}\n\n/**\n * Open file in default browser\n */\nasync function openInBrowser(path: string): Promise<void> {\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n\n const os = platform();\n const cmd = os === \"darwin\"\n ? `open \"${path}\"`\n : os === \"win32\"\n ? `start \"\" \"${path}\"`\n : `xdg-open \"${path}\"`;\n\n exec(cmd);\n}\n\n/**\n * Create empty analytics for error cases\n */\nfunction createEmptyAnalytics(): DesignSystemAnalytics {\n return {\n analyzedAt: new Date(),\n summary: {\n totalComponents: 0,\n totalVariants: 0,\n totalProps: 0,\n categories: [],\n overallScore: 0,\n },\n inventory: {\n byCategory: {},\n byStatus: {},\n byVariantCount: [],\n byPropCount: [],\n },\n coverage: {\n overall: 0,\n fields: {\n description: { covered: 0, total: 0, percentage: 0 },\n usageWhen: { covered: 0, total: 0, percentage: 0 },\n usageWhenNot: { covered: 0, total: 0, percentage: 0 },\n guidelines: { covered: 0, total: 0, percentage: 0 },\n accessibility: { covered: 0, total: 0, percentage: 0 },\n relations: { covered: 0, total: 0, percentage: 0 },\n propDescriptions: { covered: 0, total: 0, percentage: 0 },\n propConstraints: { covered: 0, total: 0, percentage: 0 },\n },\n incomplete: [],\n },\n quality: {\n missingWhenNot: [],\n isolated: [],\n deprecated: [],\n fewVariants: [],\n undocumentedProps: [],\n unconstrainedProps: [],\n },\n distribution: {\n variantsPerComponent: [],\n propsPerComponent: [],\n componentsPerCategory: [],\n statusDistribution: [],\n tagFrequency: [],\n },\n recommendations: [],\n };\n}\n"],"mappings":"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","names":["readFile","resolve","join","existsSync","existsSync","existsSync","dirname","join","resolve","ts","ts","existsSync","join","readdirSync","readFile","resolve","existsSync","join","pc","pc","existsSync","readFile","writeFile","mkdir","join","dirname","pc","pc","join","existsSync","readFile","mkdir","dirname","writeFile"]}