@fragments-sdk/cli 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/bin.js +18 -13
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-PMGI7ATF.js → chunk-5CKYLCJH.js} +58 -2
  4. package/dist/chunk-5CKYLCJH.js.map +1 -0
  5. package/dist/{chunk-MUZ6CM66.js → chunk-5ZYEOHYK.js} +13 -11
  6. package/dist/chunk-5ZYEOHYK.js.map +1 -0
  7. package/dist/{chunk-XHNKNI6J.js → chunk-AW7MWOUH.js} +9 -1
  8. package/dist/chunk-AW7MWOUH.js.map +1 -0
  9. package/dist/{chunk-LY2CFFPY.js → chunk-G3M3MPQ6.js} +14 -3
  10. package/dist/chunk-G3M3MPQ6.js.map +1 -0
  11. package/dist/{chunk-3OTEW66K.js → chunk-J4SI5RIH.js} +4 -4
  12. package/dist/{chunk-BSCG3IP7.js → chunk-NOTYONHY.js} +2 -2
  13. package/dist/{chunk-D6VXWI45.js → chunk-ZFKGX3QK.js} +8 -6
  14. package/dist/chunk-ZFKGX3QK.js.map +1 -0
  15. package/dist/{core-DWKLGY4N.js → core-LNXDLXDP.js} +5 -3
  16. package/dist/{generate-3LBZANQ3.js → generate-OIXXHOWR.js} +4 -4
  17. package/dist/index.d.ts +16 -0
  18. package/dist/index.js +6 -6
  19. package/dist/{init-NKIUCYTG.js → init-EVPXIDW4.js} +4 -4
  20. package/dist/mcp-bin.js +3 -3
  21. package/dist/mcp-bin.js.map +1 -1
  22. package/dist/scan-YVYD64GD.js +12 -0
  23. package/dist/{service-QSZMZJBJ.js → service-K52ORLCJ.js} +4 -4
  24. package/dist/{static-viewer-MIPGZ4Z7.js → static-viewer-JNQIHA4B.js} +4 -4
  25. package/dist/{test-ZCTR4LBB.js → test-USARUEFW.js} +9 -5
  26. package/dist/test-USARUEFW.js.map +1 -0
  27. package/dist/{tokens-5JQ5IOR2.js → tokens-C6YHBOQE.js} +5 -5
  28. package/dist/{viewer-D7QC4GM2.js → viewer-H7TVFT4E.js} +15 -15
  29. package/dist/{viewer-D7QC4GM2.js.map → viewer-H7TVFT4E.js.map} +1 -1
  30. package/package.json +2 -1
  31. package/src/bin.ts +7 -1
  32. package/src/build.ts +2 -0
  33. package/src/core/index.ts +4 -0
  34. package/src/core/parser.ts +102 -1
  35. package/src/core/schema.ts +11 -0
  36. package/src/core/storyAdapter.ts +1 -1
  37. package/src/core/storybook-csf.ts +11 -0
  38. package/src/core/types.ts +25 -1
  39. package/src/mcp/server.ts +1 -1
  40. package/src/migrate/bin.ts +7 -1
  41. package/src/migrate/report.ts +1 -1
  42. package/src/service/enhance/doc-extractor.ts +2 -2
  43. package/src/service/enhance/props-extractor.ts +1 -1
  44. package/src/service/enhance/storybook-parser.ts +1 -1
  45. package/src/service/figma.ts +2 -2
  46. package/src/service/metrics-store.ts +2 -1
  47. package/src/service/patch-generator.ts +2 -1
  48. package/src/service/report.ts +1 -1
  49. package/src/test/reporters/junit.ts +7 -3
  50. package/src/test/runner.ts +4 -4
  51. package/src/test/watch.ts +2 -2
  52. package/src/theme/__tests__/generator.test.ts +412 -0
  53. package/src/theme/__tests__/presets.test.ts +169 -0
  54. package/src/theme/__tests__/schema.test.ts +463 -0
  55. package/src/theme/__tests__/serializer.test.ts +326 -0
  56. package/src/theme/generator.ts +355 -0
  57. package/src/theme/index.ts +61 -0
  58. package/src/theme/presets.ts +189 -0
  59. package/src/theme/schema.ts +193 -0
  60. package/src/theme/serializer.ts +123 -0
  61. package/src/theme/types.ts +210 -0
  62. package/src/viewer/components/CodePanel.tsx +1 -1
  63. package/src/viewer/components/FigmaEmbed.tsx +1 -1
  64. package/src/viewer/jsx-parser.ts +2 -1
  65. package/src/viewer/styles/globals.css +1 -1
  66. package/src/viewer/utils/colorSchemes.ts +3 -3
  67. package/dist/chunk-D6VXWI45.js.map +0 -1
  68. package/dist/chunk-LY2CFFPY.js.map +0 -1
  69. package/dist/chunk-MUZ6CM66.js.map +0 -1
  70. package/dist/chunk-PMGI7ATF.js.map +0 -1
  71. package/dist/chunk-XHNKNI6J.js.map +0 -1
  72. package/dist/scan-3ZAOVO4U.js +0 -12
  73. package/dist/test-ZCTR4LBB.js.map +0 -1
  74. /package/dist/{chunk-3OTEW66K.js.map → chunk-J4SI5RIH.js.map} +0 -0
  75. /package/dist/{chunk-BSCG3IP7.js.map → chunk-NOTYONHY.js.map} +0 -0
  76. /package/dist/{core-DWKLGY4N.js.map → core-LNXDLXDP.js.map} +0 -0
  77. /package/dist/{generate-3LBZANQ3.js.map → generate-OIXXHOWR.js.map} +0 -0
  78. /package/dist/{init-NKIUCYTG.js.map → init-EVPXIDW4.js.map} +0 -0
  79. /package/dist/{scan-3ZAOVO4U.js.map → scan-YVYD64GD.js.map} +0 -0
  80. /package/dist/{service-QSZMZJBJ.js.map → service-K52ORLCJ.js.map} +0 -0
  81. /package/dist/{static-viewer-MIPGZ4Z7.js.map → static-viewer-JNQIHA4B.js.map} +0 -0
  82. /package/dist/{tokens-5JQ5IOR2.js.map → tokens-C6YHBOQE.js.map} +0 -0
@@ -2,7 +2,7 @@ import { createRequire } from 'module'; const require = createRequire(import.met
2
2
  import {
3
3
  BRAND,
4
4
  segmentsConfigSchema
5
- } from "./chunk-XHNKNI6J.js";
5
+ } from "./chunk-AW7MWOUH.js";
6
6
 
7
7
  // src/core/config.ts
8
8
  import { existsSync } from "fs";
@@ -1148,6 +1148,7 @@ function parseSegmentFile(fileContent, filePath) {
1148
1148
  const props = extractProps(arg, warnings);
1149
1149
  const variants = extractVariants(arg, sourceFile, warnings);
1150
1150
  const relations = extractRelations(arg, warnings);
1151
+ const ai = extractAIMetadata(arg, warnings);
1151
1152
  return {
1152
1153
  componentImport,
1153
1154
  componentName,
@@ -1156,6 +1157,7 @@ function parseSegmentFile(fileContent, filePath) {
1156
1157
  props,
1157
1158
  variants,
1158
1159
  relations,
1160
+ ai,
1159
1161
  warnings
1160
1162
  };
1161
1163
  }
@@ -1319,6 +1321,32 @@ function extractVariants(arg, sourceFile, warnings) {
1319
1321
  }
1320
1322
  return variants;
1321
1323
  }
1324
+ function dedent(str) {
1325
+ const lines = str.split("\n");
1326
+ if (lines.length <= 1) {
1327
+ return str;
1328
+ }
1329
+ const firstLineIndent = lines[0].match(/^(\s*)/)?.[1].length ?? 0;
1330
+ const startIndex = firstLineIndent === 0 ? 1 : 0;
1331
+ let minIndent = Infinity;
1332
+ for (let i = startIndex; i < lines.length; i++) {
1333
+ const line = lines[i];
1334
+ if (line.trim() === "") continue;
1335
+ const match = line.match(/^(\s*)/);
1336
+ if (match) {
1337
+ minIndent = Math.min(minIndent, match[1].length);
1338
+ }
1339
+ }
1340
+ if (minIndent === Infinity || minIndent === 0) {
1341
+ return str;
1342
+ }
1343
+ return lines.map((line, index) => {
1344
+ if (index === 0 && firstLineIndent === 0) {
1345
+ return line;
1346
+ }
1347
+ return line.slice(minIndent);
1348
+ }).join("\n");
1349
+ }
1322
1350
  function extractRenderCode(renderProp, sourceFile) {
1323
1351
  if (ts2.isArrowFunction(renderProp)) {
1324
1352
  const body = renderProp.body;
@@ -1328,6 +1356,7 @@ function extractRenderCode(renderProp, sourceFile) {
1328
1356
  if (code.startsWith("(") && code.endsWith(")")) {
1329
1357
  code = code.slice(1, -1).trim();
1330
1358
  }
1359
+ code = dedent(code);
1331
1360
  return code;
1332
1361
  }
1333
1362
  return void 0;
@@ -1354,6 +1383,33 @@ function extractRelations(arg, warnings) {
1354
1383
  }
1355
1384
  return relations;
1356
1385
  }
1386
+ function extractAIMetadata(arg, warnings) {
1387
+ const aiProp = findProperty(arg, "ai");
1388
+ if (!aiProp || !ts2.isObjectLiteralExpression(aiProp)) {
1389
+ return void 0;
1390
+ }
1391
+ const ai = {};
1392
+ const compositionPattern = extractStringProperty(aiProp, "compositionPattern");
1393
+ if (compositionPattern && ["compound", "simple", "controlled"].includes(compositionPattern)) {
1394
+ ai.compositionPattern = compositionPattern;
1395
+ }
1396
+ const subComponents = extractStringArray(aiProp, "subComponents");
1397
+ if (subComponents.length > 0) {
1398
+ ai.subComponents = subComponents;
1399
+ }
1400
+ const requiredChildren = extractStringArray(aiProp, "requiredChildren");
1401
+ if (requiredChildren.length > 0) {
1402
+ ai.requiredChildren = requiredChildren;
1403
+ }
1404
+ const commonPatterns = extractStringArray(aiProp, "commonPatterns");
1405
+ if (commonPatterns.length > 0) {
1406
+ ai.commonPatterns = commonPatterns;
1407
+ }
1408
+ if (Object.keys(ai).length > 0) {
1409
+ return ai;
1410
+ }
1411
+ return void 0;
1412
+ }
1357
1413
  function extractStringProperty(obj, name) {
1358
1414
  const prop = findProperty(obj, name);
1359
1415
  if (prop && ts2.isStringLiteral(prop)) {
@@ -1512,4 +1568,4 @@ export {
1512
1568
  generateRegistry,
1513
1569
  generateContextMd
1514
1570
  };
1515
- //# sourceMappingURL=chunk-PMGI7ATF.js.map
1571
+ //# sourceMappingURL=chunk-5CKYLCJH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config.ts","../src/core/discovery.ts","../src/core/generators/typescript-extractor.ts","../src/core/generators/registry.ts","../src/core/generators/context.ts","../src/core/loader.ts","../src/core/parser.ts","../src/core/previewLoader.ts","../src/core/importAnalyzer.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { createJiti } from 'jiti';\nimport { BRAND } from './constants.js';\nimport type { SegmentsConfig } from './types.js';\nimport { segmentsConfigSchema } from './schema.js';\n\nconst DEFAULT_CONFIG: SegmentsConfig = {\n include: [\n `src/**/*${BRAND.fileExtension}`, // *.segment.tsx files\n 'src/**/*.stories.tsx', // Storybook stories (auto-converted)\n ],\n exclude: ['**/node_modules/**'],\n components: ['src/**/index.tsx', 'src/**/*.tsx'],\n framework: 'react',\n};\n\n/**\n * Find the config file in the current directory or parent directories.\n * Checks for both the current config file name and the legacy name.\n */\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n\n while (currentDir !== dirname(currentDir)) {\n // Check for current config file name first\n const configPath = resolve(currentDir, BRAND.configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n // Also check for legacy config file name\n const legacyConfigPath = resolve(currentDir, BRAND.legacyConfigFile);\n if (existsSync(legacyConfigPath)) {\n return legacyConfigPath;\n }\n currentDir = dirname(currentDir);\n }\n\n return null;\n}\n\n/**\n * Load and validate the config file\n */\nexport async function loadConfig(configPath?: string): Promise<{\n config: SegmentsConfig;\n configDir: string;\n}> {\n const resolvedPath = configPath ?? findConfigFile();\n\n if (!resolvedPath) {\n return {\n config: DEFAULT_CONFIG,\n configDir: process.cwd(),\n };\n }\n\n try {\n // Use jiti to load TypeScript config files\n const jiti = createJiti(import.meta.url, {\n interopDefault: true,\n });\n const rawConfig = await jiti.import(resolvedPath);\n\n const result = segmentsConfigSchema.safeParse(rawConfig);\n\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(`Invalid config in ${resolvedPath}:\\n${errors}`);\n }\n\n return {\n config: { ...DEFAULT_CONFIG, ...result.data },\n configDir: dirname(resolvedPath),\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes('Invalid config')) {\n throw error;\n }\n throw new Error(`Failed to load config from ${resolvedPath}: ${error}`);\n }\n}\n","import { resolve, dirname, basename } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport fg from 'fast-glob';\nimport type { SegmentsConfig } from './types.js';\nimport { BRAND } from './constants.js';\n\nexport interface DiscoveredFile {\n /** Absolute path to the file */\n absolutePath: string;\n /** Path relative to config directory */\n relativePath: string;\n}\n\n/**\n * Discovered component with source file information\n */\nexport interface DiscoveredComponent {\n /** Component name (e.g., \"Button\") */\n name: string;\n /** Absolute path to the component source file */\n sourcePath: string;\n /** Path relative to config directory */\n relativePath: string;\n /** Path to storybook file if found */\n storyPath?: string;\n}\n\n/**\n * Discover recipe files (*.recipe.ts) under the config directory\n */\nexport async function discoverRecipeFiles(\n configDir: string,\n exclude?: string[]\n): Promise<DiscoveredFile[]> {\n const pattern = `**/*${BRAND.recipeFileExtension}`;\n const files = await fg(pattern, {\n cwd: configDir,\n ignore: exclude ?? ['**/node_modules/**', '**/dist/**'],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Discover segment files matching the config patterns\n */\nexport async function discoverSegmentFiles(\n config: SegmentsConfig,\n configDir: string\n): Promise<DiscoveredFile[]> {\n const files = await fg(config.include, {\n cwd: configDir,\n ignore: config.exclude ?? [],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Discover component files for coverage validation\n */\nexport async function discoverComponentFiles(\n config: SegmentsConfig,\n configDir: string\n): Promise<DiscoveredFile[]> {\n if (!config.components || config.components.length === 0) {\n return [];\n }\n\n const files = await fg(config.components, {\n cwd: configDir,\n ignore: [\n ...(config.exclude ?? []),\n // Exclude segment files themselves\n ...config.include,\n // Exclude test files\n '**/*.test.*',\n '**/*.spec.*',\n '**/__tests__/**',\n ],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Extract component name from file path\n */\nexport function extractComponentName(filePath: string): string {\n // Handle index.tsx files - use parent directory name\n const parts = filePath.replace(/\\\\/g, '/').split('/');\n const fileName = parts[parts.length - 1];\n\n if (fileName === 'index.tsx' || fileName === 'index.ts') {\n return parts[parts.length - 2] ?? 'Unknown';\n }\n\n // Remove extension\n return fileName.replace(/\\.(tsx?|jsx?)$/, '');\n}\n\n/**\n * Default patterns for component discovery\n */\nconst DEFAULT_COMPONENT_PATTERNS = [\n 'src/components/**/*.tsx',\n 'src/components/**/index.tsx',\n 'components/**/*.tsx',\n 'lib/components/**/*.tsx',\n 'packages/*/src/components/**/*.tsx',\n];\n\n/**\n * Patterns to exclude from component discovery\n */\nconst DEFAULT_EXCLUDE_PATTERNS = [\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*',\n '**/*.story.*',\n '**/__tests__/**',\n '**/__mocks__/**',\n '**/node_modules/**',\n '**/dist/**',\n];\n\n/**\n * Discover components from source files\n *\n * This function finds React components by:\n * 1. Looking for TypeScript/TSX files in common component directories\n * 2. Filtering out test files, stories, and internal files\n * 3. Extracting component names from file names or directories\n */\nexport async function discoverComponentsFromSource(\n configDir: string,\n patterns?: string[],\n exclude?: string[]\n): Promise<DiscoveredComponent[]> {\n const searchPatterns = patterns && patterns.length > 0\n ? patterns\n : DEFAULT_COMPONENT_PATTERNS;\n\n const excludePatterns = [\n ...DEFAULT_EXCLUDE_PATTERNS,\n ...(exclude ?? []),\n ];\n\n const files = await fg(searchPatterns, {\n cwd: configDir,\n ignore: excludePatterns,\n absolute: false,\n });\n\n // Filter to only component-like files (start with uppercase)\n const componentFiles = files.filter((file) => {\n const name = extractComponentName(file);\n return /^[A-Z]/.test(name);\n });\n\n // Find associated story files\n const storyPatterns = [\n '**/*.stories.tsx',\n '**/*.stories.ts',\n '**/*.story.tsx',\n '**/*.story.ts',\n ];\n\n const storyFiles = await fg(storyPatterns, {\n cwd: configDir,\n ignore: ['**/node_modules/**', '**/dist/**'],\n absolute: false,\n });\n\n const storyMap = new Map<string, string>();\n for (const storyFile of storyFiles) {\n const name = extractComponentName(storyFile.replace(/\\.stories?\\.(tsx?|jsx?)$/, '.tsx'));\n storyMap.set(name, storyFile);\n }\n\n // Build discovered components\n const components: DiscoveredComponent[] = [];\n\n for (const file of componentFiles) {\n const name = extractComponentName(file);\n const absolutePath = resolve(configDir, file);\n\n // Look for story file\n const storyFile = storyMap.get(name);\n\n components.push({\n name,\n sourcePath: absolutePath,\n relativePath: file,\n storyPath: storyFile ? resolve(configDir, storyFile) : undefined,\n });\n }\n\n // Sort by name\n components.sort((a, b) => a.name.localeCompare(b.name));\n\n return components;\n}\n\n/**\n * Discover components from a barrel export file (index.ts)\n *\n * Parses the barrel file to find exported components.\n * This is useful for libraries that expose components through a single entry point.\n */\nexport async function discoverComponentsFromBarrel(\n barrelPath: string,\n configDir: string\n): Promise<DiscoveredComponent[]> {\n const absoluteBarrelPath = resolve(configDir, barrelPath);\n\n if (!existsSync(absoluteBarrelPath)) {\n return [];\n }\n\n const content = await readFile(absoluteBarrelPath, 'utf-8');\n const components: DiscoveredComponent[] = [];\n\n // Match export statements like:\n // export { Button } from './Button'\n // export { Card, CardHeader } from './Card'\n // export * from './Modal'\n const exportRegex = /export\\s+(?:\\*|{([^}]+)})\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n let match;\n while ((match = exportRegex.exec(content)) !== null) {\n const exportedNames = match[1];\n const importPath = match[2];\n\n // Resolve the import path\n const barrelDir = dirname(absoluteBarrelPath);\n let resolvedPath = resolve(barrelDir, importPath);\n\n // Add extension if needed\n if (!resolvedPath.endsWith('.tsx') && !resolvedPath.endsWith('.ts')) {\n if (existsSync(`${resolvedPath}.tsx`)) {\n resolvedPath = `${resolvedPath}.tsx`;\n } else if (existsSync(`${resolvedPath}.ts`)) {\n resolvedPath = `${resolvedPath}.ts`;\n } else if (existsSync(`${resolvedPath}/index.tsx`)) {\n resolvedPath = `${resolvedPath}/index.tsx`;\n } else if (existsSync(`${resolvedPath}/index.ts`)) {\n resolvedPath = `${resolvedPath}/index.ts`;\n }\n }\n\n if (!existsSync(resolvedPath)) {\n continue;\n }\n\n if (exportedNames) {\n // Named exports: { Button, Card }\n const names = exportedNames.split(',').map((n) => n.trim().split(/\\s+as\\s+/)[0].trim());\n for (const name of names) {\n if (/^[A-Z]/.test(name)) {\n const relativePath = resolvedPath.replace(configDir + '/', '');\n components.push({\n name,\n sourcePath: resolvedPath,\n relativePath,\n });\n }\n }\n } else {\n // Star export: export * from './Component'\n const name = extractComponentName(importPath);\n if (/^[A-Z]/.test(name)) {\n const relativePath = resolvedPath.replace(configDir + '/', '');\n components.push({\n name,\n sourcePath: resolvedPath,\n relativePath,\n });\n }\n }\n }\n\n return components;\n}\n\n/**\n * Discover fragment files from installed packages that declare a \"fragments\" field\n * in their package.json. This allows consumer projects to see components from\n * installed packages (e.g. @fragments-sdk/ui) in the dev viewer.\n */\nexport async function discoverInstalledFragments(\n projectRoot: string\n): Promise<DiscoveredFile[]> {\n const pkgJsonPath = resolve(projectRoot, 'package.json');\n if (!existsSync(pkgJsonPath)) return [];\n\n const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };\n const results: DiscoveredFile[] = [];\n\n for (const depName of Object.keys(allDeps)) {\n const depDir = resolve(projectRoot, 'node_modules', depName);\n const depPkgPath = resolve(depDir, 'package.json');\n if (!existsSync(depPkgPath)) continue;\n\n const depPkg = JSON.parse(await readFile(depPkgPath, 'utf-8'));\n if (!depPkg.fragments) continue;\n\n // Package declares fragments — scan for source fragment files\n const files = await fg(\n [`src/**/*${BRAND.fileExtension}`, 'src/**/*.stories.tsx'],\n { cwd: depDir, ignore: ['**/node_modules/**'], absolute: false }\n );\n\n for (const rel of files) {\n results.push({\n relativePath: `${depName}/${rel}`,\n absolutePath: resolve(depDir, rel),\n });\n }\n }\n\n return results;\n}\n\n/**\n * Discover all components using multiple strategies\n */\nexport async function discoverAllComponents(\n configDir: string,\n options: {\n patterns?: string[];\n exclude?: string[];\n barrelFiles?: string[];\n } = {}\n): Promise<DiscoveredComponent[]> {\n const componentsMap = new Map<string, DiscoveredComponent>();\n\n // Discover from source files\n const sourceComponents = await discoverComponentsFromSource(\n configDir,\n options.patterns,\n options.exclude\n );\n\n for (const comp of sourceComponents) {\n componentsMap.set(comp.name, comp);\n }\n\n // Discover from barrel files if specified\n if (options.barrelFiles && options.barrelFiles.length > 0) {\n for (const barrelFile of options.barrelFiles) {\n const barrelComponents = await discoverComponentsFromBarrel(barrelFile, configDir);\n for (const comp of barrelComponents) {\n // Only add if not already found\n if (!componentsMap.has(comp.name)) {\n componentsMap.set(comp.name, comp);\n }\n }\n }\n }\n\n return Array.from(componentsMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n","/**\n * TypeScript Props Extractor\n * Extracts prop types, default values, and JSDoc comments from React component files\n */\n\nimport ts from \"typescript\";\nimport { readFileSync } from \"node:fs\";\nimport type { RegistryPropEntry } from \"../fragment-types.js\";\n\n/**\n * Result of extracting props from a component file\n */\nexport interface ExtractedProps {\n /** Component name */\n componentName: string;\n /** Props interface name (e.g., \"ButtonProps\") */\n propsInterfaceName?: string;\n /** Extracted props */\n props: Record<string, RegistryPropEntry>;\n /** Named exports from the file */\n exports: string[];\n /** Import statements (for dependency tracking) */\n imports: string[];\n}\n\n/**\n * Extract props from a TypeScript/TSX component file\n */\nexport function extractPropsFromFile(filePath: string): ExtractedProps | null {\n const sourceText = readFileSync(filePath, \"utf-8\");\n return extractPropsFromSource(sourceText, filePath);\n}\n\n/**\n * Extract props from TypeScript source code\n */\nexport function extractPropsFromSource(\n sourceText: string,\n fileName = \"component.tsx\"\n): ExtractedProps | null {\n const sourceFile = ts.createSourceFile(\n fileName,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n fileName.endsWith(\".tsx\") ? ts.ScriptKind.TSX : ts.ScriptKind.TS\n );\n\n const result: ExtractedProps = {\n componentName: \"\",\n props: {},\n exports: [],\n imports: [],\n };\n\n // Find all exports and props interfaces\n const propsInterfaces = new Map<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>();\n const componentExports: string[] = [];\n const importedModules: string[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n // Track imports\n if (ts.isImportDeclaration(node)) {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) {\n importedModules.push(moduleSpecifier.text);\n }\n }\n\n // Find interface declarations (e.g., interface ButtonProps { ... })\n if (ts.isInterfaceDeclaration(node)) {\n const name = node.name.text;\n if (name.endsWith(\"Props\")) {\n propsInterfaces.set(name, node);\n }\n }\n\n // Find type alias declarations (e.g., type ButtonProps = { ... })\n if (ts.isTypeAliasDeclaration(node)) {\n const name = node.name.text;\n if (name.endsWith(\"Props\")) {\n propsInterfaces.set(name, node);\n }\n }\n\n // Find exported functions/components\n if (ts.isFunctionDeclaration(node) && node.name) {\n const hasExport = node.modifiers?.some(\n (m) => m.kind === ts.SyntaxKind.ExportKeyword\n );\n if (hasExport) {\n componentExports.push(node.name.text);\n }\n }\n\n // Find exported variable declarations (e.g., export const Button = ...)\n if (ts.isVariableStatement(node)) {\n const hasExport = node.modifiers?.some(\n (m) => m.kind === ts.SyntaxKind.ExportKeyword\n );\n if (hasExport) {\n for (const decl of node.declarationList.declarations) {\n if (ts.isIdentifier(decl.name)) {\n componentExports.push(decl.name.text);\n }\n }\n }\n }\n\n // Find export declarations (e.g., export { Button })\n if (ts.isExportDeclaration(node) && node.exportClause) {\n if (ts.isNamedExports(node.exportClause)) {\n for (const element of node.exportClause.elements) {\n componentExports.push(element.name.text);\n }\n }\n }\n });\n\n result.exports = componentExports;\n result.imports = importedModules;\n\n // Find the main component (first PascalCase export)\n const mainComponent = componentExports.find(\n (name) => /^[A-Z]/.test(name) && !name.endsWith(\"Props\")\n );\n\n if (!mainComponent) {\n return null;\n }\n\n result.componentName = mainComponent;\n\n // Find matching props interface\n const propsInterfaceName = `${mainComponent}Props`;\n const propsInterface = propsInterfaces.get(propsInterfaceName);\n\n if (propsInterface) {\n result.propsInterfaceName = propsInterfaceName;\n result.props = extractPropsFromInterface(propsInterface, sourceFile);\n }\n\n return result;\n}\n\n/**\n * Extract props from an interface or type alias declaration\n */\nfunction extractPropsFromInterface(\n node: ts.InterfaceDeclaration | ts.TypeAliasDeclaration,\n sourceFile: ts.SourceFile\n): Record<string, RegistryPropEntry> {\n const props: Record<string, RegistryPropEntry> = {};\n\n // Handle interface declaration\n if (ts.isInterfaceDeclaration(node)) {\n for (const member of node.members) {\n if (ts.isPropertySignature(member) && member.name) {\n const propName = member.name.getText(sourceFile);\n const prop = extractPropFromMember(member, sourceFile);\n if (prop) {\n props[propName] = prop;\n }\n }\n }\n }\n\n // Handle type alias declaration\n if (ts.isTypeAliasDeclaration(node)) {\n const typeNode = node.type;\n if (ts.isTypeLiteralNode(typeNode)) {\n for (const member of typeNode.members) {\n if (ts.isPropertySignature(member) && member.name) {\n const propName = member.name.getText(sourceFile);\n const prop = extractPropFromMember(member, sourceFile);\n if (prop) {\n props[propName] = prop;\n }\n }\n }\n }\n }\n\n return props;\n}\n\n/**\n * Extract prop info from a property signature\n */\nfunction extractPropFromMember(\n member: ts.PropertySignature,\n sourceFile: ts.SourceFile\n): RegistryPropEntry | null {\n const entry: RegistryPropEntry = {};\n\n // Check if required\n entry.required = !member.questionToken;\n\n // Get type\n if (member.type) {\n const typeInfo = parseTypeNode(member.type, sourceFile);\n entry.type = typeInfo.type;\n entry.typeKind = typeInfo.typeKind;\n if (typeInfo.options) {\n entry.options = typeInfo.options;\n }\n }\n\n // Get JSDoc comment\n const jsDocComment = getJSDocComment(member);\n if (jsDocComment) {\n entry.description = jsDocComment;\n }\n\n // Get default value from JSDoc @default tag\n const defaultValue = getJSDocDefault(member);\n if (defaultValue !== undefined) {\n entry.default = defaultValue;\n }\n\n return entry;\n}\n\n/**\n * Parse a TypeScript type node into a simplified representation\n */\nfunction parseTypeNode(\n typeNode: ts.TypeNode,\n sourceFile: ts.SourceFile\n): { type: string; typeKind: RegistryPropEntry[\"typeKind\"]; options?: string[] } {\n // String\n if (typeNode.kind === ts.SyntaxKind.StringKeyword) {\n return { type: \"string\", typeKind: \"string\" };\n }\n\n // Number\n if (typeNode.kind === ts.SyntaxKind.NumberKeyword) {\n return { type: \"number\", typeKind: \"number\" };\n }\n\n // Boolean\n if (typeNode.kind === ts.SyntaxKind.BooleanKeyword) {\n return { type: \"boolean\", typeKind: \"boolean\" };\n }\n\n // Union type (string literal union for enums)\n if (ts.isUnionTypeNode(typeNode)) {\n const options: string[] = [];\n let allLiterals = true;\n\n for (const subType of typeNode.types) {\n if (ts.isLiteralTypeNode(subType)) {\n if (ts.isStringLiteral(subType.literal)) {\n options.push(subType.literal.text);\n } else if (subType.literal.kind === ts.SyntaxKind.TrueKeyword) {\n options.push(\"true\");\n } else if (subType.literal.kind === ts.SyntaxKind.FalseKeyword) {\n options.push(\"false\");\n } else {\n allLiterals = false;\n }\n } else {\n allLiterals = false;\n }\n }\n\n if (allLiterals && options.length > 0) {\n return {\n type: options.map((o) => `\"${o}\"`).join(\" | \"),\n typeKind: \"enum\",\n options,\n };\n }\n\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"union\",\n };\n }\n\n // Function type\n if (ts.isFunctionTypeNode(typeNode)) {\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"function\",\n };\n }\n\n // Array type\n if (ts.isArrayTypeNode(typeNode)) {\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"array\",\n };\n }\n\n // Type reference (e.g., ReactNode, React.ReactElement)\n if (ts.isTypeReferenceNode(typeNode)) {\n const typeName = typeNode.typeName.getText(sourceFile);\n\n // React types\n if (typeName === \"ReactNode\" || typeName === \"React.ReactNode\") {\n return { type: \"ReactNode\", typeKind: \"node\" };\n }\n if (typeName === \"ReactElement\" || typeName === \"React.ReactElement\") {\n return { type: \"ReactElement\", typeKind: \"element\" };\n }\n if (typeName === \"JSX.Element\") {\n return { type: \"JSX.Element\", typeKind: \"element\" };\n }\n\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"object\",\n };\n }\n\n // Object type literal\n if (ts.isTypeLiteralNode(typeNode)) {\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"object\",\n };\n }\n\n // Default: unknown\n return {\n type: typeNode.getText(sourceFile),\n typeKind: \"unknown\",\n };\n}\n\n/**\n * Get JSDoc comment from a node\n */\nfunction getJSDocComment(node: ts.Node): string | undefined {\n const jsDocTags = ts.getJSDocTags(node);\n const jsDoc = (node as unknown as { jsDoc?: ts.JSDoc[] }).jsDoc;\n\n if (jsDoc && jsDoc.length > 0) {\n const comment = jsDoc[0].comment;\n if (typeof comment === \"string\") {\n return comment;\n }\n if (Array.isArray(comment)) {\n return comment.map((c) => (typeof c === \"string\" ? c : c.text)).join(\"\");\n }\n }\n\n return undefined;\n}\n\n/**\n * Get @default value from JSDoc\n */\nfunction getJSDocDefault(node: ts.Node): unknown | undefined {\n const jsDocTags = ts.getJSDocTags(node);\n\n for (const tag of jsDocTags) {\n if (tag.tagName.text === \"default\") {\n const comment = tag.comment;\n if (typeof comment === \"string\") {\n // Try to parse as JSON\n try {\n return JSON.parse(comment);\n } catch {\n return comment;\n }\n }\n }\n }\n\n return undefined;\n}\n","/**\n * Registry Generator\n * Generates .fragments/registry.json and .fragments/index.json\n *\n * Philosophy: Generate only what AI agents and humans can't easily get from source.\n * - Props: AI can read TypeScript directly (skip by default)\n * - Paths: Essential for file navigation (always include)\n * - Enrichment: Human knowledge that doesn't exist elsewhere (include references)\n */\n\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { relative, dirname, basename, join } from \"node:path\";\nimport fg from \"fast-glob\";\nimport type {\n Fragment,\n FragmentRegistry,\n FragmentIndex,\n RegistryComponentEntry,\n} from \"../fragment-types.js\";\nimport { extractPropsFromFile } from \"./typescript-extractor.js\";\nimport { BRAND } from \"../constants.js\";\nimport type { RegistryOptions } from \"../types.js\";\n\n/**\n * Options for registry generation\n */\nexport interface RegistryGeneratorOptions {\n /** Project root directory */\n projectRoot: string;\n /** Glob patterns for component files */\n componentPatterns?: string[];\n /** Glob patterns for story files */\n storyPatterns?: string[];\n /** Path to .fragments directory */\n fragmentsDir?: string;\n /** Registry options from config */\n registryOptions?: RegistryOptions;\n}\n\n/**\n * Result of registry generation\n */\nexport interface RegistryGeneratorResult {\n /** Generated registry (full metadata) */\n registry: FragmentRegistry;\n /** Generated index (minimal name -> path) */\n index: FragmentIndex;\n /** Errors encountered during generation */\n errors: Array<{ file: string; error: string }>;\n /** Warnings */\n warnings: Array<{ file: string; warning: string }>;\n}\n\n/**\n * Generate a fragment registry and index by scanning the project\n */\nexport async function generateRegistry(\n options: RegistryGeneratorOptions\n): Promise<RegistryGeneratorResult> {\n const {\n projectRoot,\n componentPatterns = [\"src/**/*.tsx\", \"src/**/*.ts\"],\n storyPatterns = [\"src/**/*.stories.tsx\", \"src/**/*.stories.ts\"],\n fragmentsDir = join(projectRoot, BRAND.dataDir),\n registryOptions = {},\n } = options;\n\n const {\n requireStory = false,\n publicOnly = false,\n categoryDepth = 1,\n includeProps = false,\n embedFragments = false,\n } = registryOptions;\n\n const errors: Array<{ file: string; error: string }> = [];\n const warnings: Array<{ file: string; warning: string }> = [];\n\n // Find all story files first (for requireStory filtering)\n const storyFiles = await fg(storyPatterns, {\n cwd: projectRoot,\n ignore: [\"**/node_modules/**\"],\n absolute: true,\n });\n\n // Build a map of story files by component directory and base name\n const storyMap = new Map<string, string>();\n for (const storyPath of storyFiles) {\n const storyDir = dirname(storyPath);\n const storyBase = basename(storyPath).replace(/\\.stories\\.(tsx?|jsx?)$/, \"\");\n storyMap.set(`${storyDir}/${storyBase}`, storyPath);\n }\n\n // Find all component files\n const componentFiles = await fg(componentPatterns, {\n cwd: projectRoot,\n ignore: [\n \"**/node_modules/**\",\n \"**/*.stories.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/*.d.ts\",\n ],\n absolute: true,\n });\n\n // Find all fragment files\n const fragmentPattern = join(\n BRAND.dataDir,\n BRAND.componentsDir,\n `*${BRAND.fileExtension}`\n );\n const fragmentFiles = await fg(fragmentPattern, {\n cwd: projectRoot,\n absolute: true,\n });\n\n // Build fragment lookup map\n const fragmentMap = new Map<string, { path: string; fragment: Fragment }>();\n for (const fragmentPath of fragmentFiles) {\n const fragmentName = basename(fragmentPath).replace(BRAND.fileExtension, \"\");\n try {\n const content = readFileSync(fragmentPath, \"utf-8\");\n const fragment = JSON.parse(content) as Fragment;\n fragmentMap.set(fragmentName, {\n path: relative(projectRoot, fragmentPath),\n fragment,\n });\n } catch (e) {\n errors.push({\n file: fragmentPath,\n error: `Failed to parse fragment: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n // Build component index\n const components: Record<string, RegistryComponentEntry> = {};\n const indexComponents: Record<string, string> = {};\n const categories: Record<string, string[]> = {};\n\n // Process component files\n for (const filePath of componentFiles) {\n try {\n const extracted = extractPropsFromFile(filePath);\n if (!extracted || !extracted.componentName) {\n continue;\n }\n\n const componentName = extracted.componentName;\n const relativePath = relative(projectRoot, filePath);\n\n // Check if component is exported (for publicOnly filter)\n if (publicOnly && !extracted.exports.includes(componentName)) {\n continue;\n }\n\n // Find matching story file\n const componentDir = dirname(filePath);\n const baseNameWithoutExt = basename(filePath).replace(/\\.(tsx?|jsx?)$/, \"\");\n const storyPath = storyMap.get(`${componentDir}/${baseNameWithoutExt}`);\n\n // Apply requireStory filter\n if (requireStory && !storyPath) {\n continue;\n }\n\n // Get fragment data if exists\n const fragmentData = fragmentMap.get(componentName);\n\n // Determine category from directory structure\n const category = fragmentData?.fragment?.meta?.status\n ? undefined // Don't use status as category\n : getCategoryFromPath(relativePath, categoryDepth);\n\n // Check if fragment has meaningful enrichment (not just a skeleton)\n const hasEnrichment = fragmentData\n ? hasRealEnrichment(fragmentData.fragment)\n : false;\n\n // Build minimal component entry\n const entry: RegistryComponentEntry = {\n path: relativePath,\n };\n\n // Add optional fields only if present\n if (storyPath) {\n entry.storyPath = relative(projectRoot, storyPath);\n }\n\n if (fragmentData) {\n entry.fragmentPath = fragmentData.path;\n if (hasEnrichment) {\n entry.hasEnrichment = true;\n }\n if (fragmentData.fragment.description) {\n entry.description = fragmentData.fragment.description;\n }\n if (fragmentData.fragment.meta?.status) {\n entry.status = fragmentData.fragment.meta.status;\n }\n // Only embed full fragment if explicitly requested\n if (embedFragments) {\n entry.fragment = fragmentData.fragment;\n }\n }\n\n if (category) {\n entry.category = category;\n // Add to categories index\n if (!categories[category]) {\n categories[category] = [];\n }\n categories[category].push(componentName);\n }\n\n // Only include props if explicitly requested\n if (includeProps && extracted.props) {\n entry.props = extracted.props;\n }\n\n // Only include exports if multiple exports\n if (extracted.exports.length > 1) {\n entry.exports = extracted.exports;\n }\n\n components[componentName] = entry;\n indexComponents[componentName] = relativePath;\n } catch (e) {\n errors.push({\n file: filePath,\n error: `Failed to extract component: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n const componentCount = Object.keys(components).length;\n\n // Build registry\n const registry: FragmentRegistry = {\n $schema: \"https://fragments.dev/schema/registry-v1.json\",\n version: \"1.0\",\n generatedAt: new Date().toISOString(),\n componentCount,\n components,\n categories,\n };\n\n // Build minimal index\n const index: FragmentIndex = {\n version: \"1.0\",\n generatedAt: registry.generatedAt,\n components: indexComponents,\n categories,\n };\n\n return { registry, index, errors, warnings };\n}\n\n/**\n * Get category from file path based on directory structure\n *\n * Examples:\n * - src/components/buttons/Button.tsx -> \"buttons\"\n * - src/components/forms/inputs/TextInput.tsx -> \"forms\" (depth 1) or \"forms/inputs\" (depth 2)\n * - src/components/Button/Button.tsx -> \"Button\" (component folder)\n */\nfunction getCategoryFromPath(relativePath: string, depth: number = 1): string | undefined {\n const parts = relativePath.split(\"/\");\n const componentsIndex = parts.findIndex((p) => p === \"components\");\n\n if (componentsIndex === -1) {\n return undefined;\n }\n\n // Get the parts after \"components/\"\n const afterComponents = parts.slice(componentsIndex + 1);\n\n // If it's just components/Button.tsx, no category\n if (afterComponents.length <= 1) {\n return undefined;\n }\n\n // If it's components/Button/Button.tsx (component folder pattern), no category\n const folderName = afterComponents[0];\n const fileName = afterComponents[afterComponents.length - 1].replace(/\\.(tsx?|jsx?)$/, \"\");\n if (afterComponents.length === 2 && folderName === fileName) {\n return undefined;\n }\n\n // Get category parts based on depth\n const categoryParts = afterComponents.slice(0, Math.min(depth, afterComponents.length - 1));\n\n // Filter out component folders (where folder name matches file name)\n const lastCategoryPart = categoryParts[categoryParts.length - 1];\n if (lastCategoryPart === fileName) {\n categoryParts.pop();\n }\n\n if (categoryParts.length === 0) {\n return undefined;\n }\n\n return categoryParts.join(\"/\");\n}\n\n/**\n * Check if a fragment has meaningful enrichment beyond a skeleton\n */\nfunction hasRealEnrichment(fragment: Fragment): boolean {\n // Has description beyond just the name\n if (fragment.description && fragment.description.length > 20) {\n return true;\n }\n\n // Has usage guidelines\n if (fragment.usage?.when && fragment.usage.when.length > 0) {\n return true;\n }\n if (fragment.usage?.doNot && fragment.usage.doNot.length > 0) {\n return true;\n }\n if (fragment.usage?.patterns && fragment.usage.patterns.length > 0) {\n return true;\n }\n\n // Has accessibility info\n if (fragment.accessibility?.requirements && fragment.accessibility.requirements.length > 0) {\n return true;\n }\n\n // Has figma links\n if (fragment.figma?.nodeId || fragment.figma?.variants) {\n return true;\n }\n\n // Has related components\n if (fragment.related?.similar && fragment.related.similar.length > 0) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Resolve component name to path using registry\n */\nexport function resolveComponentPath(\n componentName: string,\n registry: FragmentRegistry\n): string | undefined {\n const entry = registry.components[componentName];\n return entry?.path;\n}\n\n/**\n * Get all components by category\n */\nexport function getComponentsByCategory(\n category: string,\n registry: FragmentRegistry\n): string[] {\n return registry.categories?.[category] || [];\n}\n","/**\n * Context.md Generator\n * Generates a consolidated AI-ready context file from the fragment registry\n *\n * Philosophy: Focus on human-authored semantic knowledge that AI can't get from source.\n * - Usage guidelines: When to use, when not to use\n * - Relationships: Similar components, alternatives\n * - Accessibility: Requirements and keyboard patterns\n * - DO NOT: Duplicate prop types (AI can read TypeScript directly)\n */\n\nimport type {\n FragmentRegistry,\n RegistryComponentEntry,\n RegistryPropEntry,\n FragmentDoNotItem,\n FragmentContextOptions,\n} from \"../fragment-types.js\";\n\n/**\n * Result of context generation\n */\nexport interface ContextGeneratorResult {\n /** Generated markdown content */\n content: string;\n /** Estimated token count */\n tokenEstimate: number;\n /** Component count */\n componentCount: number;\n}\n\n/**\n * Generate context.md from a fragment registry\n */\nexport function generateContextMd(\n registry: FragmentRegistry,\n options: FragmentContextOptions = {}\n): ContextGeneratorResult {\n const {\n format = \"markdown\",\n compact = false,\n include = { props: true, relations: true, code: false },\n } = options;\n\n if (format === \"json\") {\n return generateJsonContext(registry, include, compact);\n }\n\n return generateMarkdownContext(registry, include, compact);\n}\n\n/**\n * Generate markdown context\n */\nfunction generateMarkdownContext(\n registry: FragmentRegistry,\n include: { props?: boolean; relations?: boolean; code?: boolean },\n compact: boolean\n): ContextGeneratorResult {\n const lines: string[] = [];\n const componentNames = Object.keys(registry.components).sort();\n const componentCount = componentNames.length;\n\n // Header\n lines.push(\"# Component Library Context\");\n lines.push(`Generated: ${new Date().toISOString().split(\"T\")[0]} | Components: ${componentCount}`);\n lines.push(\"\");\n\n // Quick reference table\n lines.push(\"## Quick Reference\");\n lines.push(\"\");\n lines.push(\"| Component | Path | Category | Status |\");\n lines.push(\"|-----------|------|----------|--------|\");\n\n for (const name of componentNames) {\n const entry = registry.components[name];\n const status = entry.status || \"stable\";\n const category = entry.category || \"-\";\n lines.push(`| ${name} | ${entry.path} | ${category} | ${status} |`);\n }\n\n lines.push(\"\");\n\n // In compact mode, stop here\n if (compact) {\n const content = lines.join(\"\\n\");\n return {\n content,\n tokenEstimate: estimateTokens(content),\n componentCount,\n };\n }\n\n // Full documentation for each component\n lines.push(\"---\");\n lines.push(\"\");\n\n for (const name of componentNames) {\n const entry = registry.components[name];\n const fragment = entry.fragment;\n\n lines.push(`## ${name}`);\n lines.push(`**Path:** \\`${entry.path}\\``);\n\n if (entry.category) {\n lines.push(`**Category:** ${entry.category} | **Status:** ${entry.status || \"stable\"}`);\n }\n lines.push(\"\");\n\n // Description\n if (entry.description || fragment?.description) {\n lines.push(\"### Description\");\n lines.push(entry.description || fragment?.description || \"\");\n lines.push(\"\");\n }\n\n // Usage guidelines\n if (fragment?.usage) {\n if (fragment.usage.when && fragment.usage.when.length > 0) {\n lines.push(\"### When to Use\");\n for (const when of fragment.usage.when) {\n lines.push(`- ${when}`);\n }\n lines.push(\"\");\n }\n\n if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {\n lines.push(\"### Do Not\");\n for (const doNotItem of fragment.usage.doNot) {\n if (typeof doNotItem === \"string\") {\n lines.push(`- ${doNotItem}`);\n } else {\n const item = doNotItem as FragmentDoNotItem;\n if (item.instead) {\n // Resolve component path\n const alternativePath = resolveComponentPath(item.instead, registry);\n if (alternativePath) {\n lines.push(`- ${item.text} → use **${item.instead}** (\\`${alternativePath}\\`)`);\n } else {\n lines.push(`- ${item.text} → use **${item.instead}**`);\n }\n } else {\n lines.push(`- ${item.text}`);\n }\n }\n }\n lines.push(\"\");\n }\n\n if (include.code && fragment.usage.patterns && fragment.usage.patterns.length > 0) {\n lines.push(\"### Patterns\");\n for (const pattern of fragment.usage.patterns) {\n lines.push(`**${pattern.name}**`);\n if (pattern.description) {\n lines.push(pattern.description);\n }\n lines.push(\"```tsx\");\n lines.push(pattern.code);\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n }\n\n // Props\n if (include.props && entry.props && Object.keys(entry.props).length > 0) {\n lines.push(\"### Props\");\n lines.push(\"| Prop | Type | Default | Description |\");\n lines.push(\"|------|------|---------|-------------|\");\n\n for (const [propName, prop] of Object.entries(entry.props)) {\n const type = formatPropType(prop);\n const defaultVal = prop.default !== undefined ? `\\`${JSON.stringify(prop.default)}\\`` : \"-\";\n const desc = prop.description || \"-\";\n const required = prop.required ? \" (required)\" : \"\";\n lines.push(`| ${propName}${required} | ${type} | ${defaultVal} | ${desc} |`);\n }\n lines.push(\"\");\n }\n\n // Accessibility\n if (fragment?.accessibility) {\n lines.push(\"### Accessibility\");\n if (fragment.accessibility.role) {\n lines.push(`**Role:** ${fragment.accessibility.role}`);\n }\n if (fragment.accessibility.requirements && fragment.accessibility.requirements.length > 0) {\n for (const req of fragment.accessibility.requirements) {\n lines.push(`- ${req}`);\n }\n }\n if (fragment.accessibility.keyboard) {\n lines.push(\"\");\n lines.push(\"**Keyboard:**\");\n for (const [key, action] of Object.entries(fragment.accessibility.keyboard)) {\n lines.push(`- \\`${key}\\`: ${action}`);\n }\n }\n lines.push(\"\");\n }\n\n // Related components\n if (include.relations && fragment?.related) {\n lines.push(\"### Related\");\n if (fragment.related.similar && fragment.related.similar.length > 0) {\n const resolved = fragment.related.similar.map((comp) => {\n const path = resolveComponentPath(comp, registry);\n return path ? `${comp} (\\`${path}\\`)` : comp;\n });\n lines.push(`- **Similar:** ${resolved.join(\", \")}`);\n }\n if (fragment.related.composedWith && fragment.related.composedWith.length > 0) {\n const resolved = fragment.related.composedWith.map((comp) => {\n const path = resolveComponentPath(comp, registry);\n return path ? `${comp} (\\`${path}\\`)` : comp;\n });\n lines.push(`- **Composed with:** ${resolved.join(\", \")}`);\n }\n if (fragment.related.usedIn && fragment.related.usedIn.length > 0) {\n const resolved = fragment.related.usedIn.map((comp) => {\n const path = resolveComponentPath(comp, registry);\n return path ? `${comp} (\\`${path}\\`)` : comp;\n });\n lines.push(`- **Used in:** ${resolved.join(\", \")}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"---\");\n lines.push(\"\");\n }\n\n const content = lines.join(\"\\n\");\n return {\n content,\n tokenEstimate: estimateTokens(content),\n componentCount,\n };\n}\n\n/**\n * Generate JSON context\n */\nfunction generateJsonContext(\n registry: FragmentRegistry,\n include: { props?: boolean; relations?: boolean; code?: boolean },\n compact: boolean\n): ContextGeneratorResult {\n const componentNames = Object.keys(registry.components).sort();\n const componentCount = componentNames.length;\n\n interface JsonComponent {\n path: string;\n category?: string;\n status?: string;\n description?: string;\n whenToUse?: string[];\n doNot?: Array<{ text: string; instead?: string; insteadPath?: string }>;\n props?: Record<string, {\n type: string;\n required?: boolean;\n default?: unknown;\n description?: string;\n }>;\n related?: {\n similar?: Array<{ name: string; path?: string }>;\n composedWith?: Array<{ name: string; path?: string }>;\n usedIn?: Array<{ name: string; path?: string }>;\n };\n }\n\n const components: Record<string, JsonComponent> = {};\n\n for (const name of componentNames) {\n const entry = registry.components[name];\n const fragment = entry.fragment;\n\n const component: JsonComponent = {\n path: entry.path,\n };\n\n if (entry.category) component.category = entry.category;\n if (entry.status) component.status = entry.status;\n if (entry.description || fragment?.description) {\n component.description = entry.description || fragment?.description;\n }\n\n if (!compact && fragment?.usage) {\n if (fragment.usage.when && fragment.usage.when.length > 0) {\n component.whenToUse = fragment.usage.when;\n }\n\n if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {\n component.doNot = fragment.usage.doNot.map((item) => {\n if (typeof item === \"string\") {\n return { text: item };\n }\n const doNotItem = item as FragmentDoNotItem;\n const result: { text: string; instead?: string; insteadPath?: string } = {\n text: doNotItem.text,\n };\n if (doNotItem.instead) {\n result.instead = doNotItem.instead;\n result.insteadPath = resolveComponentPath(doNotItem.instead, registry);\n }\n return result;\n });\n }\n }\n\n if (!compact && include.props && entry.props) {\n component.props = {};\n for (const [propName, prop] of Object.entries(entry.props)) {\n component.props[propName] = {\n type: formatPropType(prop),\n };\n if (prop.required) component.props[propName].required = true;\n if (prop.default !== undefined) component.props[propName].default = prop.default;\n if (prop.description) component.props[propName].description = prop.description;\n }\n }\n\n if (!compact && include.relations && fragment?.related) {\n component.related = {};\n if (fragment.related.similar) {\n component.related.similar = fragment.related.similar.map((name) => ({\n name,\n path: resolveComponentPath(name, registry),\n }));\n }\n if (fragment.related.composedWith) {\n component.related.composedWith = fragment.related.composedWith.map((name) => ({\n name,\n path: resolveComponentPath(name, registry),\n }));\n }\n if (fragment.related.usedIn) {\n component.related.usedIn = fragment.related.usedIn.map((name) => ({\n name,\n path: resolveComponentPath(name, registry),\n }));\n }\n }\n\n components[name] = component;\n }\n\n const output = {\n version: \"1.0\",\n generatedAt: registry.generatedAt,\n componentCount,\n categories: registry.categories,\n components,\n };\n\n const content = JSON.stringify(output, null, 2);\n return {\n content,\n tokenEstimate: estimateTokens(content),\n componentCount,\n };\n}\n\n/**\n * Resolve component name to path\n */\nfunction resolveComponentPath(\n componentName: string,\n registry: FragmentRegistry\n): string | undefined {\n return registry.components[componentName]?.path;\n}\n\n/**\n * Format prop type for display\n */\nfunction formatPropType(prop: RegistryPropEntry): string {\n if (prop.options && prop.options.length > 0) {\n return prop.options.map((o) => `\"${o}\"`).join(\" \\\\| \");\n }\n return prop.type || \"unknown\";\n}\n\n/**\n * Estimate token count (rough: ~4 chars per token)\n */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","import { writeFile, unlink } from 'node:fs/promises';\nimport { dirname, basename, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { build, type Plugin } from 'esbuild';\nimport type { SegmentDefinition } from './types.js';\nimport { BRAND } from './constants.js';\n\n// Inline implementation of defineSegment that will be injected into bundled files\n// This allows segment files to work without @fragments/core being installed\nconst DEFINE_SEGMENT_SHIM = `\nexport function defineSegment(def) {\n return def;\n}\nexport function defineFragment(def) {\n return def;\n}\nexport function defineRecipe(def) {\n return def;\n}\n`;\n\n/**\n * Creates an esbuild plugin that replaces @fragments/core imports with an inline shim.\n * This allows segment files to be loaded without @fragments/core being installed in the target project.\n */\nfunction createSegmentsCoreShimPlugin(): Plugin {\n return {\n name: BRAND.vitePluginNamespace,\n setup(build) {\n // Intercept @fragments/core imports\n build.onResolve({ filter: /^@fragments\\/core$/ }, (args) => {\n return {\n path: args.path,\n namespace: BRAND.vitePluginNamespace,\n };\n });\n\n // Return the shim content\n build.onLoad({ filter: /.*/, namespace: BRAND.vitePluginNamespace }, () => {\n return {\n contents: DEFINE_SEGMENT_SHIM,\n loader: 'js',\n };\n });\n },\n };\n}\n\n/**\n * Load a segment file, handling TSX/TS transformation automatically.\n * Uses esbuild to bundle and transform TypeScript/JSX before importing.\n */\nexport async function loadSegmentFile(\n absolutePath: string\n): Promise<SegmentDefinition | null> {\n const ext = absolutePath.split('.').pop()?.toLowerCase();\n const needsTransform = ext === 'tsx' || ext === 'ts' || ext === 'jsx';\n\n if (!needsTransform) {\n // Plain JS file, import directly\n const fileUrl = pathToFileURL(absolutePath).href;\n const module = await import(fileUrl);\n return module.default ?? null;\n }\n\n // Bundle the file with all its local dependencies\n const sourceDir = dirname(absolutePath);\n const baseName = basename(absolutePath, `.${ext}`);\n // Use .cjs extension to ensure CommonJS evaluation\n const tempFile = join(sourceDir, `.${baseName}.segments-temp-${Date.now()}.cjs`);\n\n try {\n // Use esbuild to bundle the segment file\n // We inject a shim for @fragments/core so it doesn't need to be installed\n // Using CommonJS format to avoid ESM/CJS interop issues with node_modules\n await build({\n entryPoints: [absolutePath],\n outfile: tempFile,\n bundle: true,\n format: 'cjs', // Use CommonJS to avoid ESM issues with lodash, etc.\n target: 'es2022',\n jsx: 'automatic',\n platform: 'node',\n plugins: [createSegmentsCoreShimPlugin()],\n // Externalize all node_modules - we only need segment metadata, not component code\n packages: 'external',\n // Also explicitly list patterns for nested imports\n external: [\n // React and its subpaths\n 'react',\n 'react-dom',\n 'react/*',\n 'react-dom/*',\n ],\n // Don't emit sourcemaps for temp files\n sourcemap: false,\n // Suppress warnings\n logLevel: 'silent',\n // Use loader to ignore style imports\n loader: {\n '.scss': 'empty',\n '.css': 'empty',\n '.svg': 'empty',\n '.png': 'empty',\n '.jpg': 'empty',\n '.jpeg': 'empty',\n '.gif': 'empty',\n '.woff': 'empty',\n '.woff2': 'empty',\n '.ttf': 'empty',\n '.eot': 'empty',\n },\n });\n\n const fileUrl = pathToFileURL(tempFile).href;\n const module = await import(fileUrl);\n return module.default ?? null;\n } finally {\n // Clean up temp file\n try {\n await unlink(tempFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load multiple segment files in parallel with error handling.\n */\nexport async function loadSegmentFiles(\n absolutePaths: string[]\n): Promise<Map<string, SegmentDefinition | Error>> {\n const results = new Map<string, SegmentDefinition | Error>();\n\n await Promise.all(\n absolutePaths.map(async (path) => {\n try {\n const segment = await loadSegmentFile(path);\n if (segment) {\n results.set(path, segment);\n } else {\n results.set(path, new Error('No default export found'));\n }\n } catch (error) {\n results.set(\n path,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n })\n );\n\n return results;\n}\n","/**\n * AST-Based Segment Parser\n *\n * Extracts segment metadata from .segment.tsx files WITHOUT executing them.\n * This allows `segments build` to work without any project dependencies.\n *\n * Uses TypeScript's compiler API to parse and analyze the AST.\n */\n\nimport ts from \"typescript\";\nimport type { SegmentMeta, SegmentUsage, PropDefinition, AIMetadata } from \"./types.js\";\n\n/**\n * Parsed segment metadata (extracted statically from AST)\n */\nexport interface ParsedSegmentMetadata {\n /** Component import path (e.g., \"./Button\" or \"@/components/Button\") */\n componentImport: string | null;\n\n /** Component name as used in the file */\n componentName: string | null;\n\n /** Component metadata */\n meta: Partial<SegmentMeta>;\n\n /** Usage guidelines */\n usage: Partial<SegmentUsage>;\n\n /** Props documentation */\n props: Record<string, Partial<PropDefinition>>;\n\n /** Variant definitions */\n variants: Array<{\n name: string;\n description: string;\n code?: string;\n figma?: string;\n args?: Record<string, unknown>;\n }>;\n\n /** Related components */\n relations: Array<{\n component: string;\n relationship: string;\n note: string;\n }>;\n\n /** AI-specific metadata for playground context generation */\n ai?: AIMetadata;\n\n /** Parse warnings */\n warnings: string[];\n}\n\n/**\n * Parse a segment file and extract metadata without executing it.\n */\nexport function parseSegmentFile(\n fileContent: string,\n filePath?: string\n): ParsedSegmentMetadata {\n const warnings: string[] = [];\n\n // Parse the file\n const sourceFile = ts.createSourceFile(\n filePath ?? \"segment.tsx\",\n fileContent,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TSX\n );\n\n // Find imports\n const imports = extractImports(sourceFile);\n\n // Find the defineSegment call\n const defineSegmentCall = findDefineSegmentCall(sourceFile);\n\n if (!defineSegmentCall) {\n warnings.push(\"No defineSegment() call found\");\n return {\n componentImport: null,\n componentName: null,\n meta: {},\n usage: { when: [], whenNot: [] },\n props: {},\n variants: [],\n relations: [],\n warnings,\n };\n }\n\n // Extract the argument (object literal)\n const arg = defineSegmentCall.arguments[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) {\n warnings.push(\"defineSegment() argument is not an object literal\");\n return {\n componentImport: null,\n componentName: null,\n meta: {},\n usage: { when: [], whenNot: [] },\n props: {},\n variants: [],\n relations: [],\n warnings,\n };\n }\n\n // Extract component reference\n const componentProp = findProperty(arg, \"component\");\n let componentName: string | null = null;\n let componentImport: string | null = null;\n\n if (componentProp && ts.isIdentifier(componentProp)) {\n componentName = componentProp.text;\n // Find the import for this component\n componentImport = imports.get(componentName) ?? null;\n }\n\n // Extract meta\n const meta = extractMeta(arg, warnings);\n\n // Extract usage\n const usage = extractUsage(arg, warnings);\n\n // Extract props\n const props = extractProps(arg, warnings);\n\n // Extract variants\n const variants = extractVariants(arg, sourceFile, warnings);\n\n // Extract relations\n const relations = extractRelations(arg, warnings);\n\n // Extract AI metadata\n const ai = extractAIMetadata(arg, warnings);\n\n return {\n componentImport,\n componentName,\n meta,\n usage,\n props,\n variants,\n relations,\n ai,\n warnings,\n };\n}\n\n/**\n * Extract all imports from the source file.\n * Returns a map of imported name -> module path\n */\nfunction extractImports(sourceFile: ts.SourceFile): Map<string, string> {\n const imports = new Map<string, string>();\n\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isImportDeclaration(node)) {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) {\n const modulePath = moduleSpecifier.text;\n\n // Handle named imports\n const importClause = node.importClause;\n if (importClause) {\n // Default import\n if (importClause.name) {\n imports.set(importClause.name.text, modulePath);\n }\n\n // Named imports\n const namedBindings = importClause.namedBindings;\n if (namedBindings && ts.isNamedImports(namedBindings)) {\n for (const element of namedBindings.elements) {\n imports.set(element.name.text, modulePath);\n }\n }\n }\n }\n }\n });\n\n return imports;\n}\n\n/**\n * Find the defineSegment() call in the source file.\n */\nfunction findDefineSegmentCall(\n sourceFile: ts.SourceFile\n): ts.CallExpression | null {\n let result: ts.CallExpression | null = null;\n\n function visit(node: ts.Node): void {\n if (ts.isCallExpression(node)) {\n const expression = node.expression;\n if (ts.isIdentifier(expression) && expression.text === \"defineSegment\") {\n result = node;\n return;\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return result;\n}\n\n/**\n * Find a property in an object literal by name.\n */\nfunction findProperty(\n obj: ts.ObjectLiteralExpression,\n name: string\n): ts.Expression | null {\n for (const prop of obj.properties) {\n if (ts.isPropertyAssignment(prop)) {\n const propName = prop.name;\n if (ts.isIdentifier(propName) && propName.text === name) {\n return prop.initializer;\n }\n }\n }\n return null;\n}\n\n/**\n * Extract meta object from defineSegment call.\n */\nfunction extractMeta(\n arg: ts.ObjectLiteralExpression,\n warnings: string[]\n): Partial<SegmentMeta> {\n const metaProp = findProperty(arg, \"meta\");\n if (!metaProp || !ts.isObjectLiteralExpression(metaProp)) {\n warnings.push(\"No meta object found\");\n return {};\n }\n\n const meta: Partial<SegmentMeta> = {};\n\n // Extract string properties\n const name = extractStringProperty(metaProp, \"name\");\n if (name) meta.name = name;\n\n const description = extractStringProperty(metaProp, \"description\");\n if (description) meta.description = description;\n\n const category = extractStringProperty(metaProp, \"category\");\n if (category) meta.category = category;\n\n const status = extractStringProperty(metaProp, \"status\") as SegmentMeta[\"status\"];\n if (status) meta.status = status;\n\n const since = extractStringProperty(metaProp, \"since\");\n if (since) meta.since = since;\n\n // Extract figma URL\n const figma = extractStringProperty(metaProp, \"figma\");\n if (figma) meta.figma = figma;\n\n // Extract tags array\n const tags = extractStringArray(metaProp, \"tags\");\n if (tags.length > 0) meta.tags = tags;\n\n return meta;\n}\n\n/**\n * Extract usage object from defineSegment call.\n */\nfunction extractUsage(\n arg: ts.ObjectLiteralExpression,\n warnings: string[]\n): Partial<SegmentUsage> {\n const usageProp = findProperty(arg, \"usage\");\n if (!usageProp || !ts.isObjectLiteralExpression(usageProp)) {\n return { when: [], whenNot: [] };\n }\n\n return {\n when: extractStringArray(usageProp, \"when\"),\n whenNot: extractStringArray(usageProp, \"whenNot\"),\n guidelines: extractStringArray(usageProp, \"guidelines\"),\n accessibility: extractStringArray(usageProp, \"accessibility\"),\n };\n}\n\n/**\n * Extract props object from defineSegment call.\n */\nfunction extractProps(\n arg: ts.ObjectLiteralExpression,\n warnings: string[]\n): Record<string, Partial<PropDefinition>> {\n const propsProp = findProperty(arg, \"props\");\n if (!propsProp || !ts.isObjectLiteralExpression(propsProp)) {\n return {};\n }\n\n const props: Record<string, Partial<PropDefinition>> = {};\n\n for (const prop of propsProp.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n const propName = prop.name.text;\n const propValue = prop.initializer;\n\n if (ts.isObjectLiteralExpression(propValue)) {\n props[propName] = extractPropDefinition(propValue);\n }\n }\n }\n\n return props;\n}\n\n/**\n * Extract a single prop definition.\n */\nfunction extractPropDefinition(\n obj: ts.ObjectLiteralExpression\n): Partial<PropDefinition> {\n const def: Partial<PropDefinition> = {};\n\n const type = extractStringProperty(obj, \"type\");\n if (type) def.type = type as PropDefinition[\"type\"];\n\n const description = extractStringProperty(obj, \"description\");\n if (description) def.description = description;\n\n const values = extractStringArray(obj, \"values\");\n if (values.length > 0) def.values = values;\n\n const required = extractBooleanProperty(obj, \"required\");\n if (required !== null) def.required = required;\n\n // Default value - try to extract as literal\n const defaultProp = findProperty(obj, \"default\");\n if (defaultProp) {\n def.default = extractLiteralValue(defaultProp);\n }\n\n const constraints = extractStringArray(obj, \"constraints\");\n if (constraints.length > 0) def.constraints = constraints;\n\n return def;\n}\n\n/**\n * Extract variants array from defineSegment call.\n */\nfunction extractVariants(\n arg: ts.ObjectLiteralExpression,\n sourceFile: ts.SourceFile,\n warnings: string[]\n): Array<{ name: string; description: string; code?: string; figma?: string; args?: Record<string, unknown> }> {\n const variantsProp = findProperty(arg, \"variants\");\n if (!variantsProp || !ts.isArrayLiteralExpression(variantsProp)) {\n return [];\n }\n\n const variants: Array<{ name: string; description: string; code?: string; figma?: string; args?: Record<string, unknown> }> = [];\n\n for (const element of variantsProp.elements) {\n if (ts.isObjectLiteralExpression(element)) {\n const name = extractStringProperty(element, \"name\");\n const description = extractStringProperty(element, \"description\");\n\n if (name) {\n const variant: { name: string; description: string; code?: string; figma?: string; args?: Record<string, unknown> } = {\n name,\n description: description ?? \"\",\n };\n\n // Try to extract code property if present\n const codeProp = findProperty(element, \"code\");\n if (codeProp && ts.isStringLiteral(codeProp)) {\n variant.code = codeProp.text;\n }\n\n // Try to extract render function and convert to code string\n const renderProp = findProperty(element, \"render\");\n if (renderProp && !variant.code) {\n variant.code = extractRenderCode(renderProp, sourceFile);\n }\n\n // Extract figma URL for variant\n const figma = extractStringProperty(element, \"figma\");\n if (figma) {\n variant.figma = figma;\n }\n\n // Extract args object for code generation\n const argsProp = findProperty(element, \"args\");\n if (argsProp && ts.isObjectLiteralExpression(argsProp)) {\n const argsValue = extractLiteralValue(argsProp);\n if (argsValue && typeof argsValue === 'object' && !Array.isArray(argsValue)) {\n variant.args = argsValue as Record<string, unknown>;\n }\n }\n\n variants.push(variant);\n }\n }\n }\n\n return variants;\n}\n\n/**\n * Remove common leading whitespace from all lines (dedent).\n * This handles template literals and JSX that have extra indentation from code formatting.\n *\n * Special handling: If the first line has no indentation (common after .trim()),\n * we calculate minimum indent from subsequent lines only.\n */\nfunction dedent(str: string): string {\n const lines = str.split('\\n');\n\n if (lines.length <= 1) {\n return str;\n }\n\n // Check if first line has no indentation\n const firstLineIndent = lines[0].match(/^(\\s*)/)?.[1].length ?? 0;\n const startIndex = firstLineIndent === 0 ? 1 : 0;\n\n // Find the minimum indentation (ignoring empty lines)\n let minIndent = Infinity;\n for (let i = startIndex; i < lines.length; i++) {\n const line = lines[i];\n if (line.trim() === '') continue;\n const match = line.match(/^(\\s*)/);\n if (match) {\n minIndent = Math.min(minIndent, match[1].length);\n }\n }\n\n // If no indentation found, return as-is\n if (minIndent === Infinity || minIndent === 0) {\n return str;\n }\n\n // Remove the common indentation from all lines (except first if it had no indent)\n return lines\n .map((line, index) => {\n if (index === 0 && firstLineIndent === 0) {\n return line; // Keep first line as-is\n }\n return line.slice(minIndent);\n })\n .join('\\n');\n}\n\n/**\n * Extract the code from a render function.\n */\nfunction extractRenderCode(\n renderProp: ts.Expression,\n sourceFile: ts.SourceFile\n): string | undefined {\n // Handle arrow function: () => <Component />\n if (ts.isArrowFunction(renderProp)) {\n const body = renderProp.body;\n // Get the source text of the body\n const start = body.getStart(sourceFile);\n const end = body.getEnd();\n let code = sourceFile.text.substring(start, end).trim();\n\n // Remove parentheses if present\n if (code.startsWith(\"(\") && code.endsWith(\")\")) {\n code = code.slice(1, -1).trim();\n }\n\n // Dedent the code to remove common leading whitespace\n code = dedent(code);\n\n return code;\n }\n\n return undefined;\n}\n\n/**\n * Extract relations array from defineSegment call.\n */\nfunction extractRelations(\n arg: ts.ObjectLiteralExpression,\n warnings: string[]\n): Array<{ component: string; relationship: string; note: string }> {\n const relationsProp = findProperty(arg, \"relations\");\n if (!relationsProp || !ts.isArrayLiteralExpression(relationsProp)) {\n return [];\n }\n\n const relations: Array<{ component: string; relationship: string; note: string }> = [];\n\n for (const element of relationsProp.elements) {\n if (ts.isObjectLiteralExpression(element)) {\n const component = extractStringProperty(element, \"component\");\n const relationship = extractStringProperty(element, \"relationship\");\n const note = extractStringProperty(element, \"note\");\n\n if (component && relationship) {\n relations.push({\n component,\n relationship,\n note: note ?? \"\",\n });\n }\n }\n }\n\n return relations;\n}\n\n/**\n * Extract AI metadata from defineSegment call.\n */\nfunction extractAIMetadata(\n arg: ts.ObjectLiteralExpression,\n warnings: string[]\n): AIMetadata | undefined {\n const aiProp = findProperty(arg, \"ai\");\n if (!aiProp || !ts.isObjectLiteralExpression(aiProp)) {\n return undefined;\n }\n\n const ai: AIMetadata = {};\n\n // Extract compositionPattern\n const compositionPattern = extractStringProperty(aiProp, \"compositionPattern\");\n if (compositionPattern && ['compound', 'simple', 'controlled'].includes(compositionPattern)) {\n ai.compositionPattern = compositionPattern as AIMetadata['compositionPattern'];\n }\n\n // Extract subComponents array\n const subComponents = extractStringArray(aiProp, \"subComponents\");\n if (subComponents.length > 0) {\n ai.subComponents = subComponents;\n }\n\n // Extract requiredChildren array\n const requiredChildren = extractStringArray(aiProp, \"requiredChildren\");\n if (requiredChildren.length > 0) {\n ai.requiredChildren = requiredChildren;\n }\n\n // Extract commonPatterns array\n const commonPatterns = extractStringArray(aiProp, \"commonPatterns\");\n if (commonPatterns.length > 0) {\n ai.commonPatterns = commonPatterns;\n }\n\n // Only return if we have any fields\n if (Object.keys(ai).length > 0) {\n return ai;\n }\n\n return undefined;\n}\n\n/**\n * Extract a string property from an object literal.\n */\nfunction extractStringProperty(\n obj: ts.ObjectLiteralExpression,\n name: string\n): string | null {\n const prop = findProperty(obj, name);\n if (prop && ts.isStringLiteral(prop)) {\n return prop.text;\n }\n // Handle template literals without expressions\n if (prop && ts.isNoSubstitutionTemplateLiteral(prop)) {\n return prop.text;\n }\n return null;\n}\n\n/**\n * Extract a boolean property from an object literal.\n */\nfunction extractBooleanProperty(\n obj: ts.ObjectLiteralExpression,\n name: string\n): boolean | null {\n const prop = findProperty(obj, name);\n if (prop) {\n if (prop.kind === ts.SyntaxKind.TrueKeyword) return true;\n if (prop.kind === ts.SyntaxKind.FalseKeyword) return false;\n }\n return null;\n}\n\n/**\n * Extract a string array from an object literal.\n */\nfunction extractStringArray(\n obj: ts.ObjectLiteralExpression,\n name: string\n): string[] {\n const prop = findProperty(obj, name);\n if (!prop || !ts.isArrayLiteralExpression(prop)) {\n return [];\n }\n\n const result: string[] = [];\n for (const element of prop.elements) {\n if (ts.isStringLiteral(element)) {\n result.push(element.text);\n } else if (ts.isNoSubstitutionTemplateLiteral(element)) {\n result.push(element.text);\n }\n }\n return result;\n}\n\n/**\n * Extract a literal value from an expression.\n */\nfunction extractLiteralValue(expr: ts.Expression): unknown {\n if (ts.isStringLiteral(expr)) {\n return expr.text;\n }\n if (ts.isNumericLiteral(expr)) {\n return Number(expr.text);\n }\n if (expr.kind === ts.SyntaxKind.TrueKeyword) {\n return true;\n }\n if (expr.kind === ts.SyntaxKind.FalseKeyword) {\n return false;\n }\n if (expr.kind === ts.SyntaxKind.NullKeyword) {\n return null;\n }\n if (ts.isArrayLiteralExpression(expr)) {\n return expr.elements.map(extractLiteralValue);\n }\n if (ts.isObjectLiteralExpression(expr)) {\n const obj: Record<string, unknown> = {};\n for (const prop of expr.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n obj[prop.name.text] = extractLiteralValue(prop.initializer);\n }\n }\n return obj;\n }\n return undefined;\n}\n","/**\n * Loader for Storybook .storybook/preview.{tsx,ts,jsx,js} configuration.\n *\n * This module detects and loads Storybook preview configuration to extract:\n * - decorators: Global decorators applied to all stories\n * - parameters: Global parameters for all stories\n * - globalTypes: Global type definitions (e.g., for toolbar controls)\n * - args: Default args for all stories\n * - argTypes: Default argTypes for all stories\n * - loaders: Global loaders for all stories\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { PreviewConfig } from \"./storyAdapter.js\";\n\n/**\n * Possible file extensions and names for preview config\n */\nconst PREVIEW_FILES = [\n \"preview.tsx\",\n \"preview.ts\",\n \"preview.jsx\",\n \"preview.js\",\n];\n\n/**\n * Find the preview config file in a .storybook directory\n *\n * @param storybookDir - Path to the .storybook directory\n * @returns The full path to the preview file, or null if not found\n */\nexport function findPreviewConfigPath(storybookDir: string): string | null {\n for (const fileName of PREVIEW_FILES) {\n const filePath = join(storybookDir, fileName);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n return null;\n}\n\n/**\n * Find the .storybook directory starting from a project root.\n * Checks common locations.\n *\n * @param projectRoot - The project root directory\n * @returns The path to the .storybook directory, or null if not found\n */\nexport function findStorybookDir(projectRoot: string): string | null {\n const possiblePaths = [\n join(projectRoot, \".storybook\"),\n join(projectRoot, \"storybook\"),\n ];\n\n for (const dir of possiblePaths) {\n if (existsSync(dir)) {\n return dir;\n }\n }\n return null;\n}\n\n/**\n * Load and parse the Storybook preview configuration.\n *\n * This function dynamically imports the preview file and extracts\n * the relevant configuration exports.\n *\n * @param previewPath - Full path to the preview config file\n * @returns The parsed preview configuration\n */\nexport async function loadPreviewConfig(\n previewPath: string\n): Promise<PreviewConfig> {\n try {\n // Dynamic import with file:// URL for ESM compatibility\n const fileUrl = new URL(`file://${resolve(previewPath)}`);\n const module = await import(fileUrl.href);\n\n // Extract configuration from the module\n const config: PreviewConfig = {\n decorators: module.decorators ?? module.default?.decorators ?? [],\n parameters: module.parameters ?? module.default?.parameters ?? {},\n globalTypes: module.globalTypes ?? module.default?.globalTypes ?? {},\n args: module.args ?? module.default?.args ?? {},\n argTypes: module.argTypes ?? module.default?.argTypes ?? {},\n loaders: module.loaders ?? module.default?.loaders ?? [],\n };\n\n return config;\n } catch (error) {\n console.warn(\n `[Segments] Failed to load preview config from ${previewPath}:`,\n error instanceof Error ? error.message : error\n );\n return {};\n }\n}\n\n/**\n * Auto-detect and load preview configuration from a project.\n *\n * @param projectRoot - The project root directory\n * @returns The preview configuration, or empty config if not found\n */\nexport async function autoLoadPreviewConfig(\n projectRoot: string\n): Promise<PreviewConfig> {\n const storybookDir = findStorybookDir(projectRoot);\n if (!storybookDir) {\n return {};\n }\n\n const previewPath = findPreviewConfigPath(storybookDir);\n if (!previewPath) {\n return {};\n }\n\n return loadPreviewConfig(previewPath);\n}\n\n/**\n * Generate a virtual module that imports and re-exports preview config.\n * This is used in the Vite plugin to make preview config available at runtime.\n *\n * @param previewPath - Full path to the preview config file, or null\n * @returns JavaScript code for the virtual module\n */\nexport function generatePreviewModule(previewPath: string | null): string {\n if (!previewPath) {\n // No preview config found - export empty defaults\n return `\nexport const decorators = [];\nexport const parameters = {};\nexport const globalTypes = {};\nexport const args = {};\nexport const argTypes = {};\nexport const loaders = [];\n\nexport default {\n decorators,\n parameters,\n globalTypes,\n args,\n argTypes,\n loaders,\n};\n`;\n }\n\n // Import from the actual preview file and re-export\n return `\nimport * as preview from \"${previewPath}\";\n\nexport const decorators = preview.decorators ?? preview.default?.decorators ?? [];\nexport const parameters = preview.parameters ?? preview.default?.parameters ?? {};\nexport const globalTypes = preview.globalTypes ?? preview.default?.globalTypes ?? {};\nexport const args = preview.args ?? preview.default?.args ?? {};\nexport const argTypes = preview.argTypes ?? preview.default?.argTypes ?? {};\nexport const loaders = preview.loaders ?? preview.default?.loaders ?? [];\n\nexport default {\n decorators,\n parameters,\n globalTypes,\n args,\n argTypes,\n loaders,\n};\n`;\n}\n","/**\n * AST-based import analysis for detecting component relationships\n *\n * Analyzes TypeScript/JavaScript files to find which components import others,\n * providing accurate \"used by\" relationships for the component graph.\n */\n\nimport ts from 'typescript';\nimport { readFileSync } from 'node:fs';\nimport { resolve, dirname, basename } from 'node:path';\n\nexport interface ComponentImport {\n /** Name of the imported component */\n name: string;\n /** Import path (relative or package) */\n path: string;\n /** Whether this is a default import */\n isDefault: boolean;\n /** Whether this is a namespace import */\n isNamespace: boolean;\n}\n\nexport interface ImportAnalysisResult {\n /** Source file path */\n filePath: string;\n /** Component name extracted from file */\n componentName: string;\n /** List of component imports found */\n imports: ComponentImport[];\n}\n\n/**\n * Extract component name from a file path\n */\nfunction extractComponentNameFromPath(filePath: string): string {\n const fileName = basename(filePath);\n\n // Handle index.tsx files - use parent directory name\n if (fileName === 'index.tsx' || fileName === 'index.ts' || fileName === 'index.jsx' || fileName === 'index.js') {\n const parentDir = basename(dirname(filePath));\n return parentDir;\n }\n\n // Remove extension and common suffixes\n return fileName\n .replace(/\\.(tsx?|jsx?)$/, '')\n .replace(/\\.stories$/, '')\n .replace(/\\.segment$/, '')\n .replace(/\\.fragment$/, '');\n}\n\n/**\n * Check if an import path looks like a component import (not a utility/library)\n */\nfunction isComponentImportPath(importPath: string): boolean {\n // Skip node_modules packages\n if (!importPath.startsWith('.') && !importPath.startsWith('/')) {\n return false;\n }\n\n // Skip common utility/hook patterns\n const skipPatterns = [\n /\\/hooks\\//,\n /\\/utils\\//,\n /\\/helpers\\//,\n /\\/lib\\//,\n /\\/types\\//,\n /\\/constants\\//,\n /\\/styles\\//,\n /\\/context\\//,\n /\\.css$/,\n /\\.scss$/,\n /\\.less$/,\n /\\.json$/,\n ];\n\n for (const pattern of skipPatterns) {\n if (pattern.test(importPath)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if an imported name looks like a React component (PascalCase)\n */\nfunction isPascalCase(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name);\n}\n\n/**\n * Analyze a single file for component imports\n */\nexport function analyzeFileImports(filePath: string): ImportAnalysisResult {\n const componentName = extractComponentNameFromPath(filePath);\n const imports: ComponentImport[] = [];\n\n let sourceText: string;\n try {\n sourceText = readFileSync(filePath, 'utf-8');\n } catch {\n return { filePath, componentName, imports };\n }\n\n const sourceFile = ts.createSourceFile(\n filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n filePath.endsWith('.tsx') || filePath.endsWith('.jsx')\n ? ts.ScriptKind.TSX\n : ts.ScriptKind.TS\n );\n\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isImportDeclaration(node)) {\n const moduleSpecifier = node.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier)) return;\n\n const importPath = moduleSpecifier.text;\n\n // Skip non-component imports\n if (!isComponentImportPath(importPath)) return;\n\n const importClause = node.importClause;\n if (!importClause) return;\n\n // Default import: import Button from './Button'\n if (importClause.name) {\n const name = importClause.name.text;\n if (isPascalCase(name)) {\n imports.push({\n name,\n path: importPath,\n isDefault: true,\n isNamespace: false,\n });\n }\n }\n\n // Named imports: import { Button, Icon } from './components'\n const namedBindings = importClause.namedBindings;\n if (namedBindings) {\n if (ts.isNamedImports(namedBindings)) {\n for (const element of namedBindings.elements) {\n const name = element.name.text;\n if (isPascalCase(name)) {\n imports.push({\n name,\n path: importPath,\n isDefault: false,\n isNamespace: false,\n });\n }\n }\n } else if (ts.isNamespaceImport(namedBindings)) {\n // Namespace import: import * as Components from './components'\n // We can't reliably know what components are used without more analysis\n const name = namedBindings.name.text;\n imports.push({\n name,\n path: importPath,\n isDefault: false,\n isNamespace: true,\n });\n }\n }\n }\n });\n\n return { filePath, componentName, imports };\n}\n\n/**\n * Build a map of which components are imported by which files\n */\nexport function buildImportGraph(\n filePaths: string[]\n): Map<string, string[]> {\n // Map from component name -> list of component names that import it\n const importedBy = new Map<string, string[]>();\n\n for (const filePath of filePaths) {\n const result = analyzeFileImports(filePath);\n\n for (const imp of result.imports) {\n // Skip namespace imports for now\n if (imp.isNamespace) continue;\n\n const importedComponent = imp.name;\n const importingComponent = result.componentName;\n\n // Don't add self-references\n if (importedComponent === importingComponent) continue;\n\n const existing = importedBy.get(importedComponent) || [];\n if (!existing.includes(importingComponent)) {\n existing.push(importingComponent);\n importedBy.set(importedComponent, existing);\n }\n }\n }\n\n return importedBy;\n}\n\n/**\n * Get components that import a specific component\n */\nexport function getImportedBy(\n componentName: string,\n importGraph: Map<string, string[]>\n): string[] {\n return importGraph.get(componentName) || [];\n}\n"],"mappings":"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","names":["resolve","dirname","existsSync","resolve","existsSync","dirname","readFileSync","dirname","basename","fg","fg","dirname","basename","readFileSync","content","name","dirname","basename","join","build","dirname","basename","join","ts","existsSync","join","resolve","ts","readFileSync","dirname","basename"]}
@@ -2,7 +2,7 @@ import { createRequire } from 'module'; const require = createRequire(import.met
2
2
  import {
3
3
  BRAND,
4
4
  DEFAULTS
5
- } from "./chunk-XHNKNI6J.js";
5
+ } from "./chunk-AW7MWOUH.js";
6
6
 
7
7
  // src/service/browser-pool.ts
8
8
  import { chromium } from "playwright";
@@ -956,7 +956,7 @@ var FigmaClient = class {
956
956
  * - https://www.figma.com/file/abc123/name?node-id=1%3A2 (URL-encoded)
957
957
  */
958
958
  parseUrl(url) {
959
- const urlPattern = /figma\.com\/(?:file|design)\/([^\/]+)\/[^?]*\?.*node-id=([^&]+)/i;
959
+ const urlPattern = /figma\.com\/(?:file|design)\/([^/]+)\/[^?]*\?.*node-id=([^&]+)/i;
960
960
  const match = url.match(urlPattern);
961
961
  if (!match) {
962
962
  throw new FigmaError(
@@ -1028,7 +1028,7 @@ var FigmaClient = class {
1028
1028
  * Works with URLs that may or may not have a node-id.
1029
1029
  */
1030
1030
  parseFileUrl(url) {
1031
- const urlPattern = /figma\.com\/(?:file|design)\/([^\/]+)/i;
1031
+ const urlPattern = /figma\.com\/(?:file|design)\/([^/]+)/i;
1032
1032
  const match = url.match(urlPattern);
1033
1033
  if (!match) {
1034
1034
  throw new FigmaError(
@@ -1832,7 +1832,7 @@ function getStyles() {
1832
1832
  --bg-card: #141414;
1833
1833
  --bg-hover: #1a1a1a;
1834
1834
  --border: #262626;
1835
- --text: #fafafa;
1835
+ --text: #f2f2f2;
1836
1836
  --text-secondary: #a1a1aa;
1837
1837
  --text-muted: #71717a;
1838
1838
  --accent: #10b981;
@@ -3526,12 +3526,13 @@ function generateUnifiedDiff(file, fixes, options) {
3526
3526
  function generateHunk(cssProperty, currentValue, suggestedFix, styleType) {
3527
3527
  const lines = [];
3528
3528
  switch (styleType) {
3529
- case "inline":
3529
+ case "inline": {
3530
3530
  const camelProp = toCamelCase(cssProperty);
3531
3531
  lines.push(`@@ -1,1 +1,1 @@ inline style`);
3532
3532
  lines.push(`- ${camelProp}: '${currentValue}',`);
3533
3533
  lines.push(`+ ${camelProp}: 'var(${suggestedFix.tokenName})',`);
3534
3534
  break;
3535
+ }
3535
3536
  case "styled-components":
3536
3537
  case "emotion":
3537
3538
  lines.push(`@@ -1,1 +1,1 @@ ${styleType}`);
@@ -3940,11 +3941,12 @@ var MetricsStore = class {
3940
3941
  const date = new Date(snapshot.timestamp);
3941
3942
  let key;
3942
3943
  switch (groupBy) {
3943
- case "week":
3944
+ case "week": {
3944
3945
  const weekStart = new Date(date);
3945
3946
  weekStart.setDate(date.getDate() - date.getDay());
3946
3947
  key = weekStart.toISOString().split("T")[0];
3947
3948
  break;
3949
+ }
3948
3950
  case "month":
3949
3951
  key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
3950
3952
  break;
@@ -5016,7 +5018,7 @@ function extractJSDoc(comments) {
5016
5018
  tags: {}
5017
5019
  };
5018
5020
  const lines = content.split("\n");
5019
- let currentDescription = [];
5021
+ const currentDescription = [];
5020
5022
  let currentTag = null;
5021
5023
  let currentTagContent = [];
5022
5024
  for (const line of lines) {
@@ -5056,7 +5058,7 @@ function processTag(docs, tag, content) {
5056
5058
  if (propMatch) {
5057
5059
  const [, type, nameRaw, description] = propMatch;
5058
5060
  const isOptional = nameRaw.startsWith("[");
5059
- const name = nameRaw.replace(/[\[\]]/g, "");
5061
+ const name = nameRaw.replaceAll("[", "").replaceAll("]", "");
5060
5062
  docs.props?.push({
5061
5063
  name,
5062
5064
  type,
@@ -5552,7 +5554,7 @@ function camelToTitle(str) {
5552
5554
  }
5553
5555
  function inferComponentFromPath(filePath) {
5554
5556
  const fileName = basename3(filePath);
5555
- let name = fileName.replace(/\.stories\.(tsx?|jsx?|mdx?)$/, "");
5557
+ const name = fileName.replace(/\.stories\.(tsx?|jsx?|mdx?)$/, "");
5556
5558
  return name;
5557
5559
  }
5558
5560
  async function findStoryFiles(rootDir, include = ["**/*.stories.{tsx,ts,jsx,js}"], exclude = ["**/node_modules/**", "**/dist/**"]) {
@@ -6059,7 +6061,7 @@ function getJSDocInfo(node, sourceFile) {
6059
6061
  }
6060
6062
  function parseJSDocContent(content, result) {
6061
6063
  const lines = content.split("\n");
6062
- let currentDescription = [];
6064
+ const currentDescription = [];
6063
6065
  let currentTag = null;
6064
6066
  let currentTagContent = [];
6065
6067
  for (const line of lines) {
@@ -6633,4 +6635,4 @@ export {
6633
6635
  getStorybookStoryIds,
6634
6636
  renderAllComponentVariants
6635
6637
  };
6636
- //# sourceMappingURL=chunk-MUZ6CM66.js.map
6638
+ //# sourceMappingURL=chunk-5ZYEOHYK.js.map