@fragments-sdk/mcp 0.6.2 → 0.7.0

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/auto-extract.ts","../src/adapters/discover-components.ts","../src/adapters/scan-tokens.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, relative, sep, dirname, basename } from 'node:path';\nimport type { CompiledFragment, PropDefinition, FragmentMeta } from '@fragments-sdk/context/types';\nimport type { DesignSystemData } from '../types.js';\nimport type { DataAdapter } from './types.js';\nimport { discoverComponentFiles } from './discover-components.js';\nimport { scanTokens } from './scan-tokens.js';\n\n/**\n * Auto-extract adapter: discovers and extracts component data\n * directly from source code without requiring fragments.json.\n *\n * Requires TypeScript to be installed (used by @fragments-sdk/extract\n * for LanguageService-based prop extraction).\n */\nexport class AutoExtractionAdapter implements DataAdapter {\n readonly name = 'auto-extract';\n\n discover(startDir: string): string[] {\n return discoverComponentFiles(startDir).map(f => f.filePath);\n }\n\n async load(projectRoot: string): Promise<DesignSystemData> {\n // Dynamic import — keeps startup fast when FragmentsJsonAdapter is used\n let extractMod: { createComponentExtractor: (tsconfigPath?: string) => {\n extract: (filePath: string, exportName?: string) => unknown | null;\n extractAll: (filePath: string) => unknown[];\n dispose: () => void;\n }};\n try {\n extractMod = await import('@fragments-sdk/extract');\n } catch (e) {\n throw new Error(\n 'Auto-extraction requires @fragments-sdk/extract and TypeScript.\\n\\n' +\n 'If you see this error, the MCP server may not be installed correctly.\\n' +\n 'Alternative: pre-build your design system with `npx fragments build`'\n );\n }\n\n // Find tsconfig.json\n const tsconfigPath = findTsConfig(projectRoot);\n\n // Create extractor\n const extractor = extractMod.createComponentExtractor(tsconfigPath ?? undefined);\n\n try {\n // Discover component files\n const discovered = discoverComponentFiles(projectRoot);\n\n if (discovered.length === 0) {\n throw new Error(\n `No component files found in ${projectRoot}.\\n` +\n 'Searched: src/components/, components/, lib/components/, src/ui/\\n\\n' +\n 'If your components are elsewhere, create a fragments.json with:\\n' +\n ' npx fragments build'\n );\n }\n\n const components: Record<string, CompiledFragment> = {};\n const packageMap = new Map<string, string>();\n const defaultPackageName = readPackageName(projectRoot);\n let extractedCount = 0;\n\n // Track which file each component came from (for compound component detection)\n const fileToComponents = new Map<string, string[]>();\n\n for (const { filePath, componentName } of discovered) {\n try {\n const metas = extractor.extractAll(filePath) as ExtractedMeta[];\n\n for (const meta of metas) {\n const fragment = mapToCompiledFragment(meta, filePath, projectRoot);\n components[meta.name] = fragment;\n if (defaultPackageName) {\n packageMap.set(meta.name, defaultPackageName);\n }\n extractedCount++;\n // Track file → components for relationship inference\n const relPath = relative(projectRoot, filePath);\n if (!fileToComponents.has(relPath)) fileToComponents.set(relPath, []);\n fileToComponents.get(relPath)!.push(meta.name);\n }\n\n // If extractAll returns nothing, try with the inferred name\n if (metas.length === 0) {\n const meta = extractor.extract(filePath, componentName) as ExtractedMeta | null;\n if (meta) {\n const fragment = mapToCompiledFragment(meta, filePath, projectRoot);\n components[meta.name] = fragment;\n if (defaultPackageName) {\n packageMap.set(meta.name, defaultPackageName);\n }\n extractedCount++;\n const relPath = relative(projectRoot, filePath);\n if (!fileToComponents.has(relPath)) fileToComponents.set(relPath, []);\n fileToComponents.get(relPath)!.push(meta.name);\n }\n }\n } catch {\n // Skip files that fail extraction — non-fatal\n continue;\n }\n }\n\n // Infer compound component relationships from co-located exports\n inferRelations(components, fileToComponents);\n\n // Log progress to stderr (stdout is reserved for MCP JSON-RPC)\n console.error(`[fragments-mcp] Extracted ${extractedCount} components from ${discovered.length} files.`);\n\n if (extractedCount === 0) {\n throw new Error(\n `Found ${discovered.length} component files but could not extract any props.\\n` +\n 'This usually means TypeScript cannot parse the files.\\n' +\n 'Check that your tsconfig.json includes the component directories.'\n );\n }\n\n // Scan for CSS design tokens\n const tokens = scanTokens(projectRoot);\n if (tokens) {\n console.error(`[fragments-mcp] Found ${tokens.total} design tokens across ${Object.keys(tokens.categories).length} categories.`);\n }\n\n return {\n components,\n blocks: undefined,\n tokens,\n graph: undefined,\n performanceSummary: undefined,\n packageMap,\n defaultPackageName,\n };\n } finally {\n extractor.dispose();\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface ExtractedPropMeta {\n name: string;\n type: string;\n typeKind: string;\n values?: string[];\n default?: string;\n description?: string;\n required: boolean;\n source: string;\n}\n\ninterface ExtractedMeta {\n name: string;\n filePath: string;\n description: string;\n props: Record<string, ExtractedPropMeta>;\n composition: { pattern: string } | null;\n exports: string[];\n dependencies: string[];\n}\n\n// Inherited props that AI agents commonly need, grouped by relevance.\n// Universal props apply to all components. Form props only apply to input-like components.\nconst UNIVERSAL_INHERITED = new Set(['children', 'className', 'id', 'disabled']);\nconst FORM_INPUT_INHERITED = new Set([\n 'placeholder', 'value', 'defaultValue', 'onChange', 'name', 'required',\n 'autoFocus', 'autoComplete', 'checked', 'defaultChecked', 'type',\n]);\nconst LABEL_INHERITED = new Set(['htmlFor']);\n\n// Component names that behave like form inputs\nconst INPUT_LIKE_NAMES = /input|select|textarea|checkbox|radio|switch|slider|combobox/i;\nconst LABEL_LIKE_NAMES = /label/i;\n\nfunction getRelevantInheritedProps(componentName: string): Set<string> {\n const allowed = new Set(UNIVERSAL_INHERITED);\n if (INPUT_LIKE_NAMES.test(componentName)) {\n for (const p of FORM_INPUT_INHERITED) allowed.add(p);\n }\n if (LABEL_LIKE_NAMES.test(componentName)) {\n for (const p of LABEL_INHERITED) allowed.add(p);\n }\n return allowed;\n}\n\nfunction mapToCompiledFragment(\n meta: ExtractedMeta,\n filePath: string,\n projectRoot: string,\n): CompiledFragment {\n // Map props: local props + context-appropriate inherited props\n const relevantInherited = getRelevantInheritedProps(meta.name);\n const props: Record<string, PropDefinition> = {};\n for (const [name, propMeta] of Object.entries(meta.props)) {\n if (propMeta.source === 'inherited' && !relevantInherited.has(name)) continue;\n props[name] = {\n type: propMeta.type,\n description: propMeta.description ?? '',\n required: propMeta.required,\n ...(propMeta.values && { values: propMeta.values }),\n ...(propMeta.default !== undefined && { default: propMeta.default }),\n };\n }\n\n const relativePath = relative(projectRoot, filePath);\n const category = inferCategory(relativePath);\n const importPath = buildImportPath(relativePath);\n const description = buildDescription(meta, props);\n const propsSummary = buildPropsSummary(props);\n const codeExample = buildCodeExample(meta.name, props);\n\n const fragmentMeta: FragmentMeta = {\n name: meta.name,\n description,\n category,\n };\n\n return {\n filePath: relativePath,\n meta: fragmentMeta,\n usage: {\n when: [`Use ${meta.name} when you need a ${category} ${meta.name.toLowerCase()} element.`],\n whenNot: [],\n guidelines: importPath ? [`import { ${meta.name} } from \"${importPath}\"`] : [],\n },\n props,\n propsSummary,\n variants: codeExample ? [{ name: 'Default', description: `Basic ${meta.name} usage`, code: codeExample }] : [],\n sourcePath: relativePath,\n exportName: meta.name,\n _generated: {\n source: 'extracted',\n verified: false,\n timestamp: new Date().toISOString(),\n },\n ...(meta.composition && {\n ai: {\n compositionPattern: meta.composition.pattern as 'compound' | 'simple' | 'controlled' | 'wrapper',\n },\n }),\n };\n}\n\n/**\n * Generate an import path from a relative file path.\n * Converts `src/components/ui/button.tsx` → `@/components/ui/button`\n */\nfunction buildImportPath(relativePath: string): string | null {\n // Strip extension\n const withoutExt = relativePath.replace(/\\.(tsx|jsx|ts|js)$/, '');\n // Common alias: src/ → @/\n if (withoutExt.startsWith(`src${sep}`)) {\n return '@/' + withoutExt.slice(4).split(sep).join('/');\n }\n // Relative path\n return './' + withoutExt.split(sep).join('/');\n}\n\n/**\n * Generate a useful description from extracted metadata.\n */\nfunction buildDescription(meta: ExtractedMeta, localProps: Record<string, PropDefinition>): string {\n // Use JSDoc description if the extractor found one\n if (meta.description && meta.description !== meta.name && !meta.description.endsWith(' component')) {\n return meta.description;\n }\n // Generate from props\n const propEntries = Object.entries(localProps);\n if (propEntries.length === 0) {\n return `${meta.name} component`;\n }\n const details: string[] = [];\n for (const [name, prop] of propEntries) {\n if (prop.values && prop.values.length > 0) {\n details.push(`${prop.values.length} ${name} options`);\n }\n }\n if (details.length > 0) {\n return `${meta.name} component with ${details.join(' and ')}.`;\n }\n return `${meta.name} component with ${propEntries.length} configurable prop${propEntries.length === 1 ? '' : 's'}.`;\n}\n\n/**\n * Generate human-readable prop summaries for AI agents.\n */\nfunction buildPropsSummary(props: Record<string, PropDefinition>): string[] {\n const summaries: string[] = [];\n for (const [name, prop] of Object.entries(props)) {\n let summary = `${name}`;\n if (prop.values && prop.values.length > 0) {\n summary += `: ${prop.values.map(v => `\"${v}\"`).join(' | ')}`;\n } else {\n summary += `: ${prop.type}`;\n }\n if (prop.default !== undefined) {\n summary += ` (default: ${JSON.stringify(prop.default)})`;\n }\n if (prop.required) {\n summary += ' (required)';\n }\n summaries.push(summary);\n }\n return summaries;\n}\n\n/**\n * Generate a basic JSX code example from props.\n */\nfunction buildCodeExample(name: string, props: Record<string, PropDefinition>): string | null {\n const propsStr: string[] = [];\n\n for (const [pName, prop] of Object.entries(props)) {\n if (pName === 'children' || pName === 'asChild' || pName === 'className') continue;\n if (pName === 'onChange' || pName === 'onSubmit' || pName === 'value' ||\n pName === 'defaultValue' || pName === 'checked' || pName === 'defaultChecked' ||\n pName === 'autoFocus' || pName === 'autoComplete' || pName === 'required' ||\n pName === 'disabled' || pName === 'name') continue; // skip state/handler props in examples\n\n if (prop.default !== undefined) {\n if (prop.values && prop.values.length > 1) {\n const nonDefault = prop.values.find(v => v !== String(prop.default));\n if (nonDefault) {\n propsStr.push(`${pName}=\"${nonDefault}\"`);\n continue;\n }\n }\n }\n // Show placeholder for Input-like components\n if (pName === 'placeholder' && INPUT_LIKE_NAMES.test(name)) {\n propsStr.push(`placeholder=\"Enter ${name.toLowerCase()}...\"`);\n continue;\n }\n // Show htmlFor for Label\n if (pName === 'htmlFor' && LABEL_LIKE_NAMES.test(name)) {\n propsStr.push(`htmlFor=\"field-id\"`);\n continue;\n }\n // Skip id/className/children in examples — they're boilerplate\n if (pName === 'id' || pName === 'className' || pName === 'children') continue;\n if (prop.required) {\n if (prop.values && prop.values.length > 0) {\n propsStr.push(`${pName}=\"${prop.values[0]}\"`);\n } else if (prop.type === 'string') {\n propsStr.push(`${pName}=\"...\"`);\n }\n }\n }\n\n const propsJsx = propsStr.length > 0 ? ' ' + propsStr.join(' ') : '';\n // Self-closing for input-like components\n const nameLower = name.toLowerCase();\n const selfClosing = nameLower.includes('input') || nameLower.includes('separator') ||\n nameLower.includes('slider') || nameLower.includes('switch');\n if (selfClosing) {\n return `<${name}${propsJsx} />`;\n }\n return `<${name}${propsJsx}>${name}</${name}>`;\n}\n\n/**\n * Generate a composition example showing how compound sub-components nest together.\n * Returns a JSX snippet like: <Card><CardHeader><CardTitle>Title</CardTitle></CardHeader>...</Card>\n */\nfunction buildCompositionExample(root: string, subs: string[]): string {\n // Group sub-components by likely nesting based on naming conventions\n const header = subs.filter(s => s.includes('Header'));\n const title = subs.filter(s => s.includes('Title'));\n const description = subs.filter(s => s.includes('Description'));\n const content = subs.filter(s => s.includes('Content') || s.includes('Body'));\n const footer = subs.filter(s => s.includes('Footer'));\n const action = subs.filter(s => s.includes('Action'));\n const other = subs.filter(s =>\n !header.includes(s) && !title.includes(s) && !description.includes(s) &&\n !content.includes(s) && !footer.includes(s) && !action.includes(s)\n );\n\n const lines: string[] = [`<${root}>`];\n\n // Header section (with title and description nested inside)\n if (header.length > 0) {\n lines.push(` <${header[0]}>`);\n for (const t of title) lines.push(` <${t}>Title</${t}>`);\n for (const d of description) lines.push(` <${d}>Description</${d}>`);\n lines.push(` </${header[0]}>`);\n } else {\n for (const t of title) lines.push(` <${t}>Title</${t}>`);\n for (const d of description) lines.push(` <${d}>Description</${d}>`);\n }\n\n // Content section\n for (const c of content) lines.push(` <${c}>Content</${c}>`);\n\n // Other sub-components\n for (const o of other) lines.push(` <${o}>...</${o}>`);\n\n // Footer section (with action inside)\n if (footer.length > 0) {\n lines.push(` <${footer[0]}>`);\n for (const a of action) lines.push(` <${a}>Action</${a}>`);\n lines.push(` </${footer[0]}>`);\n } else {\n for (const a of action) lines.push(` <${a}>Action</${a}>`);\n }\n\n lines.push(`</${root}>`);\n return lines.join('\\n');\n}\n\n/**\n * Infer compound component relationships from co-located exports.\n * If Card, CardHeader, CardContent all come from card.tsx, they're related.\n */\nfunction inferRelations(\n components: Record<string, CompiledFragment>,\n fileToComponents: Map<string, string[]>,\n): void {\n for (const [_file, names] of fileToComponents) {\n if (names.length <= 1) continue;\n\n // Find the \"root\" component (shortest name, or the one others are prefixed with)\n const sorted = [...names].sort((a, b) => a.length - b.length);\n const root = sorted[0];\n const subs = sorted.slice(1).filter(n => n.startsWith(root));\n\n if (subs.length === 0) continue;\n\n // Mark the root as a compound component\n const rootComp = components[root];\n if (rootComp) {\n rootComp.ai = {\n ...rootComp.ai,\n compositionPattern: 'compound',\n subComponents: subs,\n };\n // Add relations pointing subs → root\n rootComp.relations = subs.map(sub => ({\n component: sub,\n relationship: 'parent-of',\n note: `${sub} is a sub-component of ${root}`,\n }));\n // Add composition example as a variant\n const compositionCode = buildCompositionExample(root, subs);\n rootComp.variants = [\n ...(rootComp.variants ?? []),\n { name: 'Composition', description: `${root} with all sub-components`, code: compositionCode },\n ];\n }\n\n // Mark each sub-component with a relation back to root + consolidated import\n const rootImportPath = rootComp?.usage?.guidelines?.[0];\n for (const sub of subs) {\n const subComp = components[sub];\n if (subComp) {\n subComp.relations = [{\n component: root,\n relationship: 'child-of',\n note: `Use inside <${root}>`,\n }];\n // Override import to show consolidated multi-import from parent's file\n if (rootImportPath) {\n const allNames = [root, ...subs].join(', ');\n const fromPath = rootImportPath.match(/from\\s+\"([^\"]+)\"/)?.[1] ?? '';\n if (fromPath) {\n subComp.usage = {\n ...subComp.usage,\n guidelines: [`import { ${allNames} } from \"${fromPath}\"`],\n };\n }\n }\n }\n }\n\n // Also update root's import to show all sub-components\n if (rootComp && rootComp.usage?.guidelines?.[0]) {\n const fromPath = rootComp.usage.guidelines[0].match(/from\\s+\"([^\"]+)\"/)?.[1] ?? '';\n if (fromPath) {\n const allNames = [root, ...subs].join(', ');\n rootComp.usage.guidelines = [`import { ${allNames} } from \"${fromPath}\"`];\n }\n }\n }\n}\n\nfunction inferCategory(relativePath: string): string {\n const parts = relativePath.split(sep);\n const componentsIdx = parts.findIndex(p =>\n p === 'components' || p === 'ui'\n );\n if (componentsIdx >= 0 && componentsIdx + 1 < parts.length - 1) {\n const nextPart = parts[componentsIdx + 1];\n if (/^[A-Z]/.test(nextPart)) return parts[componentsIdx] || 'uncategorized';\n return nextPart;\n }\n return 'uncategorized';\n}\n\nfunction findTsConfig(projectRoot: string): string | null {\n const candidates = ['tsconfig.json', 'tsconfig.app.json'];\n for (const name of candidates) {\n const p = join(projectRoot, name);\n if (existsSync(p)) return p;\n }\n return null;\n}\n\nfunction readPackageName(projectRoot: string): string | undefined {\n try {\n const pkgPath = join(projectRoot, 'package.json');\n if (!existsSync(pkgPath)) return undefined;\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as { name?: string };\n return pkg.name;\n } catch {\n return undefined;\n }\n}\n","import { readdirSync, existsSync } from 'node:fs';\nimport { join, extname, basename } from 'node:path';\n\nexport interface DiscoveredComponentFile {\n /** Absolute file path */\n filePath: string;\n /** Inferred PascalCase component name */\n componentName: string;\n}\n\nconst EXCLUDED_DIRS = new Set([\n 'node_modules', 'dist', 'build', '.next', '.nuxt', 'coverage',\n '__tests__', '__mocks__', '.git', '.cache', '.turbo', 'out',\n]);\n\nconst EXCLUDED_PATTERNS = [\n /\\.test\\./,\n /\\.spec\\./,\n /\\.stories\\./,\n /\\.story\\./,\n /\\.fragment\\./,\n /\\.d\\.ts$/,\n /\\.config\\./,\n /\\.mock\\./,\n /\\.fixture\\./,\n];\n\n/**\n * Discover component files by walking common directories.\n * Returns all .tsx/.jsx files (excluding tests, stories, etc.).\n * The extractor determines which files actually export React components.\n */\nexport function discoverComponentFiles(projectRoot: string): DiscoveredComponentFile[] {\n const results: DiscoveredComponentFile[] = [];\n const seen = new Set<string>();\n\n // Common component locations to scan\n const scanDirs = [\n 'src/components', 'components', 'lib/components',\n 'src/ui', 'lib/ui', 'packages',\n ].map(d => join(projectRoot, d)).filter(d => existsSync(d));\n\n // If no conventional dirs exist, scan src/ itself\n if (scanDirs.length === 0) {\n const srcDir = join(projectRoot, 'src');\n if (existsSync(srcDir)) scanDirs.push(srcDir);\n }\n\n for (const dir of scanDirs) {\n walkDir(dir, results, seen);\n }\n\n return results;\n}\n\nfunction walkDir(\n dir: string,\n results: DiscoveredComponentFile[],\n seen: Set<string>,\n depth = 0,\n): void {\n if (depth > 6) return; // prevent deep recursion\n\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch { return; }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n\n if (entry.isDirectory()) {\n if (EXCLUDED_DIRS.has(entry.name)) continue;\n walkDir(join(dir, entry.name), results, seen, depth + 1);\n continue;\n }\n\n if (!entry.isFile()) continue;\n const ext = extname(entry.name);\n if (ext !== '.tsx' && ext !== '.jsx') continue;\n if (EXCLUDED_PATTERNS.some(p => p.test(entry.name))) continue;\n\n const filePath = join(dir, entry.name);\n if (seen.has(filePath)) continue;\n seen.add(filePath);\n\n // Infer component name — accept all files, let extractor determine if it's a component\n const name = inferComponentName(entry.name, dir);\n if (name) {\n results.push({ filePath, componentName: name });\n }\n }\n}\n\nfunction inferComponentName(fileName: string, dirPath: string): string | null {\n const withoutExt = fileName.replace(/\\.(tsx|jsx)$/, '');\n if (withoutExt === 'index') {\n // Use parent directory name\n return basename(dirPath);\n }\n return withoutExt;\n}\n","import { readdirSync, readFileSync, existsSync } from 'node:fs';\nimport { join, extname } from 'node:path';\nimport type { CompiledTokenData } from '@fragments-sdk/context/types';\n\ninterface TokenEntry {\n name: string;\n value?: string;\n description?: string;\n}\n\n/**\n * Scan a project for CSS custom property declarations and return them\n * as CompiledTokenData. Lightweight alternative to the full compiler\n * token pipeline — handles CSS custom properties in :root blocks.\n */\nexport function scanTokens(projectRoot: string): CompiledTokenData | undefined {\n // Find CSS files in common locations\n const cssFiles = discoverCssFiles(projectRoot);\n if (cssFiles.length === 0) return undefined;\n\n const allTokens: TokenEntry[] = [];\n let prefix = '';\n\n for (const filePath of cssFiles) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const tokens = extractCustomProperties(content);\n allTokens.push(...tokens);\n } catch {\n continue;\n }\n }\n\n if (allTokens.length === 0) return undefined;\n\n // Detect common prefix\n prefix = detectPrefix(allTokens.map(t => t.name));\n\n // Group by category (inferred from token name)\n const categories: Record<string, TokenEntry[]> = {};\n for (const token of allTokens) {\n const category = inferTokenCategory(token.name);\n if (!categories[category]) categories[category] = [];\n // Deduplicate by name (keep first occurrence — light mode)\n if (!categories[category].some(t => t.name === token.name)) {\n categories[category].push(token);\n }\n }\n\n return {\n prefix,\n total: Object.values(categories).reduce((sum, arr) => sum + arr.length, 0),\n categories,\n };\n}\n\n/**\n * Find CSS files in common project locations.\n */\nfunction discoverCssFiles(projectRoot: string): string[] {\n const files: string[] = [];\n const searchDirs = [\n 'src', 'styles', 'css', 'app',\n ].map(d => join(projectRoot, d)).filter(d => existsSync(d));\n\n // Also check root for standalone CSS files\n searchDirs.push(projectRoot);\n\n for (const dir of searchDirs) {\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n const ext = extname(entry.name);\n if (ext === '.css' || ext === '.scss') {\n files.push(join(dir, entry.name));\n }\n }\n } catch {\n continue;\n }\n }\n\n // Also check one level deep in src/\n const srcDir = join(projectRoot, 'src');\n if (existsSync(srcDir)) {\n try {\n for (const subEntry of readdirSync(srcDir, { withFileTypes: true })) {\n if (subEntry.isDirectory() && ['styles', 'css', 'theme', 'tokens'].includes(subEntry.name)) {\n const subDir = join(srcDir, subEntry.name);\n for (const file of readdirSync(subDir, { withFileTypes: true })) {\n if (file.isFile() && (file.name.endsWith('.css') || file.name.endsWith('.scss'))) {\n files.push(join(subDir, file.name));\n }\n }\n }\n }\n } catch {\n // ignore\n }\n }\n\n return [...new Set(files)]; // deduplicate\n}\n\n/**\n * Extract CSS custom property declarations from file content.\n * Handles :root { ... } blocks and extracts --name: value; pairs.\n * Only extracts from :root and top-level selectors (not nested component styles).\n */\nfunction extractCustomProperties(content: string): TokenEntry[] {\n const tokens: TokenEntry[] = [];\n // Only extract from :root, .dark, [data-theme], @theme blocks\n // Track if we're inside a relevant block\n let inRelevantBlock = false;\n let braceDepth = 0;\n const relevantSelectors = [':root', '.dark', '[data-theme', '@theme'];\n\n const lines = content.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Check if entering a relevant block\n if (!inRelevantBlock && braceDepth === 0) {\n if (relevantSelectors.some(sel => trimmed.startsWith(sel) || trimmed.includes(sel))) {\n if (trimmed.includes('{')) {\n inRelevantBlock = true;\n braceDepth = 1;\n }\n }\n }\n\n // Track brace depth\n if (inRelevantBlock) {\n for (const ch of trimmed) {\n if (ch === '{') braceDepth++;\n else if (ch === '}') {\n braceDepth--;\n if (braceDepth <= 0) {\n inRelevantBlock = false;\n braceDepth = 0;\n }\n }\n }\n }\n\n // Only extract tokens from relevant blocks, or at top level in @theme\n if (!inRelevantBlock && braceDepth === 0) continue;\n\n const match = trimmed.match(/^(--[\\w-]+)\\s*:\\s*(.+?)\\s*;/);\n if (match) {\n const [, name, value] = match;\n // Extract inline comment as description\n const commentMatch = value.match(/\\/\\*\\s*(.+?)\\s*\\*\\//);\n const cleanValue = value.replace(/\\/\\*.*?\\*\\//, '').trim();\n tokens.push({\n name,\n value: cleanValue,\n description: commentMatch?.[1],\n });\n }\n }\n\n return tokens;\n}\n\n/**\n * Detect common prefix from token names.\n * e.g., [\"--fui-color-accent\", \"--fui-space-2\"] → \"--fui-\"\n * e.g., [\"--background\", \"--foreground\"] → \"--\"\n */\nfunction detectPrefix(names: string[]): string {\n if (names.length === 0) return '--';\n // Remove the leading -- for comparison\n const stripped = names.map(n => n.slice(2));\n // Find common prefix among stripped names\n let prefix = '';\n const first = stripped[0];\n for (let i = 0; i < first.length; i++) {\n const ch = first[i];\n if (stripped.every(n => n[i] === ch)) {\n prefix += ch;\n } else {\n break;\n }\n }\n // Only use prefix if it ends at a word boundary (-)\n const lastDash = prefix.lastIndexOf('-');\n if (lastDash > 0) {\n return '--' + prefix.slice(0, lastDash + 1);\n }\n return '--';\n}\n\n/**\n * Infer token category from its name using naming conventions.\n */\nfunction inferTokenCategory(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('color') || n.includes('background') || n.includes('foreground') ||\n n.includes('primary') || n.includes('secondary') || n.includes('accent') ||\n n.includes('muted') || n.includes('destructive') || n.includes('popover') ||\n n.includes('card') && !n.includes('card-') || n.includes('chart')) {\n return 'colors';\n }\n if (n.includes('font') || n.includes('text') || n.includes('letter') || n.includes('line-height')) {\n return 'typography';\n }\n if (n.includes('space') || n.includes('gap') || n.includes('padding') || n.includes('margin')) {\n return 'spacing';\n }\n if (n.includes('radius')) {\n return 'radius';\n }\n if (n.includes('shadow')) {\n return 'shadows';\n }\n if (n.includes('border')) {\n return 'borders';\n }\n if (n.includes('ring')) {\n return 'focus';\n }\n if (n.includes('sidebar')) {\n return 'sidebar';\n }\n if (n.includes('input')) {\n return 'forms';\n }\n return 'other';\n}\n"],"mappings":"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","names":["existsSync","readFileSync","join","readdirSync","existsSync","join","extname","join","existsSync","readFileSync"]}