@fragments-sdk/mcp 0.5.13 → 0.5.15

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.
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startMcpServer
4
- } from "./chunk-XMNCAB2A.js";
4
+ } from "./chunk-ZOMUPGBG.js";
5
5
 
6
6
  // src/bin.ts
7
7
  var args = process.argv.slice(2);
@@ -2194,6 +2194,36 @@ Suggestion: ${result.suggestion}` : ""}`
2194
2194
  content: [{ type: "text", text: result.text }]
2195
2195
  };
2196
2196
  }
2197
+ // ================================================================
2198
+ // GENERATE_UI — proxy to playground API
2199
+ // ================================================================
2200
+ case TOOL_NAMES.generate_ui: {
2201
+ const prompt = args?.prompt;
2202
+ if (!prompt) {
2203
+ throw new Error("prompt is required");
2204
+ }
2205
+ const currentTree = args?.currentTree;
2206
+ const playgroundUrl = config.playgroundUrl ?? "https://usefragments.com";
2207
+ const response = await fetch(`${playgroundUrl}/api/playground/generate`, {
2208
+ method: "POST",
2209
+ headers: { "Content-Type": "application/json" },
2210
+ body: JSON.stringify({
2211
+ prompt,
2212
+ ...currentTree && { currentSpec: currentTree }
2213
+ })
2214
+ });
2215
+ if (!response.ok) {
2216
+ const errorBody = await response.text();
2217
+ throw new Error(`Playground API error (${response.status}): ${errorBody}`);
2218
+ }
2219
+ const text = await response.text();
2220
+ return {
2221
+ content: [{
2222
+ type: "text",
2223
+ text
2224
+ }]
2225
+ };
2226
+ }
2197
2227
  default:
2198
2228
  throw new Error(`Unknown tool: ${name}`);
2199
2229
  }
@@ -2225,4 +2255,4 @@ export {
2225
2255
  startMcpServer,
2226
2256
  createSandboxServer
2227
2257
  };
2228
- //# sourceMappingURL=chunk-XMNCAB2A.js.map
2258
+ //# sourceMappingURL=chunk-ZOMUPGBG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/constants.ts","../src/discovery.ts","../src/orama-index.ts","../src/search.ts","../src/scoring.ts","../src/service.ts","../src/utils.ts","../src/graph-handler.ts","../src/server-helpers.ts","../src/version.ts"],"sourcesContent":["/**\n * Standalone MCP server for Fragments design system.\n *\n * This is a lightweight extraction of the MCP server from @fragments-sdk/cli\n * that can run independently without Playwright or build tools. It provides:\n * - 9 tools: discover, inspect, blocks, tokens, implement, render, fix, graph, a11y\n * - Hybrid search: Convex-backed vector search + local keyword scoring + RRF\n * - HTTP-only render/fix/a11y (requires a running dev server)\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { BRAND, DEFAULTS } from './constants.js';\nimport { generateContext, filterPlaceholders } from '@fragments-sdk/context/generate';\nimport type { CompiledFragmentsFile, CompiledFragment, Theme } from '@fragments-sdk/context/types';\nimport { buildMcpTools, buildToolNames } from '@fragments-sdk/context/mcp-tools';\nimport { findFragmentsJson } from './discovery.js';\nimport { hybridSearch, keywordScoreBlocks } from './search.js';\nimport { assignConfidence, buildBlockComponentFrequency, boostByBlockFrequency, findClosestMatch, meetsMinimumThreshold } from './scoring.js';\nimport { buildComponentIndex, buildBlockIndex, buildTokenIndex, extractTokenCategories, searchBlocks } from './orama-index.js';\nimport type { ComponentIndex, BlockIndex, TokenIndex } from './orama-index.js';\nimport { renderComponent, compareComponent, fixComponent, auditComponent } from './service.js';\nimport { projectFields } from './utils.js';\nimport { handleGraphTool } from './graph-handler.js';\nimport type { GraphToolArgs } from './graph-handler.js';\nimport {\n buildImportStatements,\n buildLocalSearchData,\n categoryMatches,\n limitTokensPerCategory,\n normalizeFilter,\n} from './server-helpers.js';\nimport { MCP_SERVER_VERSION } from './version.js';\n\n// ---------------------------------------------------------------------------\n// Tool names & definitions (from shared source of truth)\n// ---------------------------------------------------------------------------\n\nconst TOOL_NAMES = buildToolNames(BRAND.nameLower) as Record<string, string> & {\n discover: string;\n inspect: string;\n blocks: string;\n tokens: string;\n implement: string;\n render: string;\n fix: string;\n graph: string;\n a11y: string;\n generate_ui: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared error messages\n// ---------------------------------------------------------------------------\n\nconst NO_VIEWER_MSG = 'This tool requires a running dev server. Add --viewer-url http://localhost:PORT to this server\\'s config args. Start the viewer with \\'fragments dev\\' in your component library directory.';\n\n// ---------------------------------------------------------------------------\n// Server configuration\n// ---------------------------------------------------------------------------\n\nexport interface McpServerConfig {\n /** Project root directory */\n projectRoot: string;\n /** Viewer base URL (for render/fix tools) */\n viewerUrl?: string;\n /** Default theme for verification */\n theme?: Theme;\n /** Diff threshold percentage */\n threshold?: number;\n /** Premium API key — enables semantic vector search when provided */\n apiKey?: string;\n /** Playground API URL for generate_ui tool */\n playgroundUrl?: string;\n}\n\nconst TOOLS = buildMcpTools(BRAND.nameLower) as Tool[];\n\n// ---------------------------------------------------------------------------\n// Server implementation\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(config: McpServerConfig): Server {\n const server = new Server(\n {\n name: `${BRAND.nameLower}-mcp`,\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Lazy-loaded resources\n let fragmentsData: CompiledFragmentsFile | null = null;\n const fragmentPackageMap = new Map<string, string>();\n let defaultPackageName: string | null = null;\n let resolvedRoot: string | null = null;\n\n // Orama BM25 indexes — built once after loadFragments(), reused across searches\n let componentIndex: ComponentIndex | null = null;\n let blockIndex: BlockIndex | null = null;\n let tokenIndex: TokenIndex | null = null;\n\n /**\n * Resolve the project root directory.\n *\n * Layer 1: Try MCP roots/list (VS Code, Claude Code, and any client\n * that implements the MCP roots capability).\n * Layer 2: Fall back to the configured projectRoot (defaults to cwd).\n */\n async function resolveProjectRoot(): Promise<string> {\n if (resolvedRoot) return resolvedRoot;\n\n // Layer 1: Try MCP roots/list\n try {\n const result = await server.listRoots();\n if (result.roots?.length > 0) {\n const rootUri = result.roots[0].uri;\n // Convert file:///path/to/workspace -> /path/to/workspace\n resolvedRoot = fileURLToPath(rootUri);\n return resolvedRoot;\n }\n } catch {\n // Client doesn't support roots/list (e.g. Cursor) — fall through\n }\n\n // Layer 2: Fall back to configured projectRoot (cwd)\n resolvedRoot = config.projectRoot;\n return resolvedRoot;\n }\n\n async function loadFragments(): Promise<CompiledFragmentsFile> {\n if (fragmentsData) return fragmentsData;\n\n const projectRoot = await resolveProjectRoot();\n const paths = findFragmentsJson(projectRoot);\n\n if (paths.length === 0) {\n throw new Error(\n `No ${BRAND.outFile} found. Searched ${projectRoot} and package.json dependencies.\\n\\n` +\n `Fix: Add a project-level MCP config so the server runs from your workspace root:\\n\\n` +\n ` Cursor: .cursor/mcp.json\\n` +\n ` VS Code: .vscode/mcp.json\\n` +\n ` Claude: claude mcp add ${BRAND.nameLower} -- npx @fragments-sdk/mcp\\n` +\n ` Windsurf: .windsurf/mcp.json\\n\\n` +\n `Or pass --project-root: npx @fragments-sdk/mcp -p /path/to/project\\n\\n` +\n `If you're a library author, run \\`${BRAND.cliCommand} build\\` first.`\n );\n }\n\n const content = await readFile(paths[0], 'utf-8');\n fragmentsData = JSON.parse(content) as CompiledFragmentsFile;\n\n // Normalize legacy \"recipes\" key to \"blocks\"\n if (!fragmentsData.blocks && fragmentsData.recipes) {\n fragmentsData.blocks = fragmentsData.recipes;\n }\n\n if (fragmentsData.packageName) {\n for (const name of Object.keys(fragmentsData.fragments)) {\n fragmentPackageMap.set(name, fragmentsData.packageName);\n }\n }\n\n for (let i = 1; i < paths.length; i++) {\n const extra = JSON.parse(await readFile(paths[i], 'utf-8')) as CompiledFragmentsFile;\n if (extra.packageName) {\n for (const name of Object.keys(extra.fragments)) {\n fragmentPackageMap.set(name, extra.packageName);\n }\n }\n Object.assign(fragmentsData.fragments, extra.fragments);\n const extraBlocks = extra.blocks ?? extra.recipes;\n if (extraBlocks) {\n fragmentsData.blocks = { ...fragmentsData.blocks, ...extraBlocks };\n }\n }\n\n // Build Orama BM25 indexes for fast search\n const allFragments = Object.values(fragmentsData.fragments);\n const allBlocks = Object.values(fragmentsData.blocks ?? fragmentsData.recipes ?? {});\n componentIndex = buildComponentIndex(allFragments);\n if (allBlocks.length > 0) {\n blockIndex = buildBlockIndex(allBlocks);\n }\n if (fragmentsData.tokens && fragmentsData.tokens.total > 0) {\n tokenIndex = buildTokenIndex(fragmentsData.tokens);\n }\n\n return fragmentsData;\n }\n\n async function getPackageName(fragmentName?: string): Promise<string> {\n await loadFragments();\n\n if (fragmentName) {\n const segPkg = fragmentPackageMap.get(fragmentName);\n if (segPkg) return segPkg;\n }\n\n if (defaultPackageName) return defaultPackageName;\n\n if (fragmentsData?.packageName) {\n defaultPackageName = fragmentsData.packageName;\n return defaultPackageName;\n }\n\n const root = resolvedRoot ?? config.projectRoot;\n const packageJsonPath = join(root, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content) as { name?: string };\n if (pkg.name) {\n defaultPackageName = pkg.name;\n return defaultPackageName;\n }\n } catch {\n // Fall through\n }\n }\n\n defaultPackageName = 'your-component-library';\n return defaultPackageName;\n }\n\n // Tools that require a running dev server (viewer URL)\n const VIEWER_TOOL_KEYS = new Set(['render', 'fix', 'a11y']);\n\n // Register tool listing — omit viewer-dependent tools when no viewer URL is configured\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n if (config.viewerUrl) {\n return { tools: TOOLS };\n }\n // Filter out tools that require a viewer URL\n const availableTools = TOOLS.filter(\n (t) => !VIEWER_TOOL_KEYS.has(t.name.replace(`${BRAND.nameLower}_`, ''))\n );\n return { tools: availableTools };\n });\n\n // Register tool execution\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n // ================================================================\n // DISCOVER — list, suggest, context, alternatives\n // ================================================================\n case TOOL_NAMES.discover: {\n const data = await loadFragments();\n const useCase = (args?.useCase as string) ?? undefined;\n const componentForAlts = (args?.component as string) ?? undefined;\n const category = normalizeFilter(args?.category as string | undefined);\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const status = (args?.status as string) ?? undefined;\n const format = (args?.format as 'markdown' | 'json') ?? 'markdown';\n const compact = (args?.compact as boolean) ?? false;\n const includeCode = (args?.includeCode as boolean) ?? false;\n const includeRelations = (args?.includeRelations as boolean) ?? false;\n const limit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 25) : 10;\n const verbosity = (args?.verbosity as string) ?? 'standard';\n\n // --- Context mode (compact or format-only) ---\n if (compact || (args?.format && !useCase && !componentForAlts)) {\n let fragments = Object.values(data.fragments);\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n // Apply filters even in compact/context mode\n if (category) {\n fragments = fragments.filter(f => categoryMatches(f.meta.category, category));\n }\n if (search) {\n fragments = fragments.filter(f =>\n f.meta.name.toLowerCase().includes(search) ||\n f.meta.description?.toLowerCase().includes(search) ||\n f.meta.tags?.some(t => t.toLowerCase().includes(search))\n );\n }\n if (status) {\n fragments = fragments.filter(f => f.meta.status === status);\n }\n\n const { content: ctxContent, tokenEstimate } = generateContext(fragments, {\n format,\n compact,\n include: {\n code: includeCode,\n relations: includeRelations,\n },\n }, allBlocks);\n\n return {\n content: [{ type: 'text' as const, text: ctxContent }],\n _meta: { tokenEstimate },\n };\n }\n\n // --- Suggest mode: useCase provided (uses hybrid search) ---\n if (useCase) {\n const { allFragments, allBlocks, localData } = buildLocalSearchData(\n data,\n {\n componentIndex,\n blockIndex,\n tokenIndex,\n }\n );\n const context = ((args as Record<string, unknown>)?.context as string)?.toLowerCase() ?? '';\n const fullQuery = context ? `${useCase} ${context}` : useCase;\n\n // Use hybrid search — filter to components only for discover suggest\n const searchResults = await hybridSearch(fullQuery, localData, limit, 'component', config.apiKey);\n\n // Block-first ranking: boost components by frequency in matching blocks\n const blockMatches = keywordScoreBlocks(fullQuery, allBlocks, blockIndex ?? undefined).slice(0, 5);\n if (blockMatches.length > 0) {\n const matchedBlocks = blockMatches\n .map(bm => allBlocks.find(b => b.name.toLowerCase() === bm.name.toLowerCase()))\n .filter(Boolean) as typeof allBlocks;\n const blockFreq = buildBlockComponentFrequency(matchedBlocks);\n boostByBlockFrequency(searchResults, blockFreq);\n }\n\n const maxScore = searchResults.length > 0 ? searchResults[0].score : 0;\n\n // Build detailed suggestions from search results\n const scored = searchResults.map((result) => {\n const fragment = allFragments.find(\n (s) => s.meta.name.toLowerCase() === result.name.toLowerCase()\n );\n if (!fragment) return null;\n\n const filteredWhen = filterPlaceholders(fragment.usage?.when).slice(0, 3);\n const filteredWhenNot = filterPlaceholders(fragment.usage?.whenNot).slice(0, 2);\n\n return {\n component: fragment.meta.name,\n category: fragment.meta.category,\n description: fragment.meta.description,\n confidence: assignConfidence(result.score, maxScore),\n reasons: [`Matched via hybrid search (score: ${result.score.toFixed(4)})`],\n usage: { when: filteredWhen, whenNot: filteredWhenNot },\n variantCount: fragment.variants.length,\n status: fragment.meta.status,\n };\n }).filter(Boolean);\n\n // Diversify by category (max 2 per category)\n const suggestions: typeof scored = [];\n const categoryCount: Record<string, number> = {};\n for (const item of scored) {\n if (!item) continue;\n const cat = item.category || 'uncategorized';\n const count = categoryCount[cat] || 0;\n if (count < 2 || suggestions.length < 3) {\n suggestions.push(item);\n categoryCount[cat] = count + 1;\n if (suggestions.length >= limit) break;\n }\n }\n\n const compositionHint = suggestions.length >= 2\n ? `These components work well together. For example, ${suggestions[0]!.component} can be combined with ${suggestions.slice(1, 3).map(s => s!.component).join(' and ')}.`\n : undefined;\n\n const useCaseLower = useCase.toLowerCase();\n const STYLE_KEYWORDS = ['color', 'spacing', 'padding', 'margin', 'font', 'border', 'radius', 'shadow', 'variable', 'token', 'css', 'theme', 'dark mode', 'background', 'hover'];\n const isStyleQuery = STYLE_KEYWORDS.some((kw) => useCaseLower.includes(kw));\n\n const noMatch = suggestions.length === 0;\n // Absolute quality gate: if the best BM25 score is below the minimum\n // threshold, treat results as weak regardless of relative confidence.\n // Guard with maxScore > 1 to skip this check for RRF-scored results\n // (which use a different score range of ~0.01-0.05).\n const belowThreshold = !noMatch && maxScore > 1 && !meetsMinimumThreshold(maxScore);\n const weakMatch = !noMatch && (belowThreshold || suggestions.every((s) => s!.confidence === 'low'));\n\n let recommendation: string;\n let nextStep: string | undefined;\n if (noMatch) {\n recommendation = isStyleQuery\n ? `No matching components found. Your query seems styling-related — try ${TOOL_NAMES.tokens} to find CSS custom properties.`\n : 'No matching components found. Try different keywords or browse all components with fragments_discover.';\n nextStep = isStyleQuery\n ? `Use ${TOOL_NAMES.tokens}(search: \"${useCaseLower.split(/\\s+/)[0]}\") to find design tokens.`\n : undefined;\n } else if (weakMatch) {\n recommendation = `Weak matches only — ${suggestions[0]!.component} might work but confidence is low.${isStyleQuery ? ` If you need a CSS variable, try ${TOOL_NAMES.tokens}.` : ''}`;\n nextStep = `Use ${TOOL_NAMES.inspect}(\"${suggestions[0]!.component}\") to check if it fits, or try broader search terms.`;\n } else {\n recommendation = `Best match: ${suggestions[0]!.component} (${suggestions[0]!.confidence} confidence) - ${suggestions[0]!.description}`;\n nextStep = `Use ${TOOL_NAMES.inspect}(\"${suggestions[0]!.component}\") for full details.`;\n }\n\n // Always hint toward tokens tool when query uses styling keywords,\n // even when component matches exist — the user may want CSS variables\n const tokenHint = isStyleQuery && !noMatch\n ? `Your query includes styling terms. For CSS custom properties, also try ${TOOL_NAMES.tokens}(search: \"${useCaseLower.split(/\\s+/)[0]}\").`\n : undefined;\n\n // Surface matching blocks in the response — helps with abstract queries\n // like \"landing page hero section\" where blocks provide better answers\n const blockNames = blockMatches\n .map(bm => allBlocks.find(b => b.name.toLowerCase() === bm.name.toLowerCase()))\n .filter(Boolean)\n .slice(0, 3)\n .map(b => b!.name);\n const blockHint = blockNames.length > 0\n ? `Related blocks: ${blockNames.join(', ')}. Use ${TOOL_NAMES.blocks}(search: \"${useCase}\") for ready-to-use patterns.`\n : undefined;\n\n // Apply verbosity level\n const suggestResponse = verbosity === 'compact'\n ? {\n useCase,\n suggestions: suggestions.map(s => ({\n component: s!.component,\n description: s!.description,\n confidence: s!.confidence,\n })),\n recommendation,\n }\n : {\n useCase,\n context: context || undefined,\n suggestions,\n noMatch,\n weakMatch,\n recommendation,\n compositionHint,\n ...(tokenHint && { tokenHint }),\n ...(blockHint && { blockHint }),\n nextStep,\n };\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(suggestResponse),\n }],\n };\n }\n\n // --- Alternatives mode ---\n if (componentForAlts) {\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentForAlts.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentForAlts, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentForAlts}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const relations = fragment.relations ?? [];\n\n const referencedBy = Object.values(data.fragments)\n .filter((s) =>\n s.relations?.some((r) => r.component.toLowerCase() === componentForAlts.toLowerCase())\n )\n .map((s) => ({\n component: s.meta.name,\n relationship: s.relations?.find(\n (r) => r.component.toLowerCase() === componentForAlts.toLowerCase()\n )?.relationship,\n note: s.relations?.find(\n (r) => r.component.toLowerCase() === componentForAlts.toLowerCase()\n )?.note,\n }));\n\n const sameCategory = Object.values(data.fragments)\n .filter(\n (s) =>\n s.meta.category === fragment.meta.category &&\n s.meta.name.toLowerCase() !== componentForAlts.toLowerCase()\n )\n .map((s) => ({\n component: s.meta.name,\n description: s.meta.description,\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: fragment.meta.name,\n category: fragment.meta.category,\n directRelations: relations,\n referencedBy,\n sameCategory,\n suggestion: relations.find((r) => r.relationship === 'alternative')\n ? `Consider ${relations.find((r) => r.relationship === 'alternative')?.component}: ${relations.find((r) => r.relationship === 'alternative')?.note}`\n : undefined,\n }),\n }],\n };\n }\n\n // --- Default: list mode ---\n const fragments = Object.values(data.fragments)\n .filter((s) => {\n if (category && !categoryMatches(s.meta.category, category)) return false;\n if (status && (s.meta.status ?? 'stable') !== status) return false;\n if (search) {\n const nameMatch = s.meta.name.toLowerCase().includes(search);\n const descMatch = s.meta.description?.toLowerCase().includes(search);\n const tagMatch = s.meta.tags?.some((t) => t.toLowerCase().includes(search));\n if (!nameMatch && !descMatch && !tagMatch) return false;\n }\n return true;\n })\n .map((s) => {\n if (verbosity === 'compact') {\n return { name: s.meta.name, category: s.meta.category };\n }\n return {\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n status: s.meta.status ?? 'stable',\n variantCount: s.variants.length,\n tags: s.meta.tags ?? [],\n ...((includeCode || verbosity === 'full') && s.variants[0]?.code && {\n example: s.variants[0].code,\n }),\n };\n });\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: fragments.length,\n fragments,\n categories: [...new Set(fragments.map((s) => s.category))],\n hint: fragments.length === 0\n ? 'No components found. Try broader search terms or check available categories.'\n : fragments.length > 5\n ? 'Use fragments_discover with useCase for recommendations, or fragments_inspect for details on a specific component.'\n : undefined,\n }),\n }],\n };\n }\n\n // ================================================================\n // INSPECT\n // ================================================================\n case TOOL_NAMES.inspect: {\n const data = await loadFragments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n const variantName = (args?.variant as string) ?? undefined;\n const maxExamples = args?.maxExamples as number | undefined;\n const maxLines = args?.maxLines as number | undefined;\n const verbosity = (args?.verbosity as string) ?? 'standard';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"? Use ${TOOL_NAMES.inspect}(\"${closest}\") to inspect it.` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const pkgName = await getPackageName(fragment.meta.name);\n\n let variants = fragment.variants;\n if (variantName) {\n const query = variantName.toLowerCase();\n let filtered = variants.filter((v) => v.name.toLowerCase() === query);\n if (filtered.length === 0) {\n filtered = variants.filter((v) => v.name.toLowerCase().startsWith(query));\n }\n if (filtered.length === 0) {\n filtered = variants.filter((v) => v.name.toLowerCase().includes(query));\n }\n if (filtered.length > 0) {\n variants = filtered;\n } else {\n throw new Error(\n `Variant \"${variantName}\" not found for ${componentName}. ` +\n `Available: ${fragment.variants.map((v) => v.name).join(', ')}`\n );\n }\n }\n if (maxExamples && maxExamples > 0) {\n variants = variants.slice(0, maxExamples);\n }\n\n const truncateCode = (code: string): string => {\n if (!maxLines || maxLines <= 0) return code;\n const lines = code.split('\\n');\n if (lines.length <= maxLines) return code;\n return lines.slice(0, maxLines).join('\\n') + '\\n// ... truncated';\n };\n\n const examples = variants.map((variant) => {\n if (variant.code) {\n return {\n variant: variant.name,\n description: variant.description,\n code: truncateCode(variant.code),\n };\n }\n return {\n variant: variant.name,\n description: variant.description,\n code: `<${fragment.meta.name} />`,\n note: 'No code example provided in fragment. Refer to props for customization.',\n };\n });\n\n const propsReference = Object.entries(fragment.props ?? {}).map(([propName, prop]) => ({\n name: propName,\n type: prop.type,\n required: prop.required,\n default: prop.default,\n description: prop.description,\n }));\n\n const propConstraints = Object.entries(fragment.props ?? {})\n .filter(([, prop]) => prop.constraints && prop.constraints.length > 0)\n .map(([pName, prop]) => ({\n prop: pName,\n constraints: prop.constraints,\n }));\n\n const fullResult = {\n meta: fragment.meta,\n props: fragment.props,\n variants: fragment.variants,\n relations: fragment.relations,\n contract: fragment.contract,\n generated: fragment._generated,\n guidelines: {\n when: filterPlaceholders(fragment.usage?.when),\n whenNot: filterPlaceholders(fragment.usage?.whenNot),\n guidelines: fragment.usage?.guidelines ?? [],\n accessibility: fragment.usage?.accessibility ?? [],\n propConstraints,\n alternatives: fragment.relations\n ?.filter((r) => r.relationship === 'alternative')\n .map((r) => ({\n component: r.component,\n note: r.note,\n })) ?? [],\n },\n examples: {\n import: `import { ${fragment.meta.name} } from '${pkgName}';`,\n code: examples,\n propsReference,\n },\n };\n\n // Alias legacy field paths (e.g., \"usage.when\" → \"guidelines.when\")\n const aliasMap: Record<string, string> = { 'usage': 'guidelines' };\n const resolvedFields = fields?.map(f => {\n const parts = f.split('.');\n if (aliasMap[parts[0]]) parts[0] = aliasMap[parts[0]];\n return parts.join('.');\n });\n\n let result: unknown;\n if (verbosity === 'compact' && !resolvedFields?.length) {\n // Compact: meta + prop names + variant names only\n result = {\n meta: fullResult.meta,\n propNames: Object.keys(fragment.props ?? {}),\n variantNames: fragment.variants.map(v => v.name),\n };\n } else {\n result = resolvedFields && resolvedFields.length > 0\n ? projectFields(fullResult as unknown as Record<string, unknown>, resolvedFields)\n : fullResult;\n }\n\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result) }],\n };\n }\n\n // ================================================================\n // BLOCKS\n // ================================================================\n case TOOL_NAMES.blocks: {\n const data = await loadFragments();\n const blockName = args?.name as string | undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const component = (args?.component as string)?.toLowerCase() ?? undefined;\n const category = (args?.category as string)?.toLowerCase() ?? undefined;\n const blocksLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 50) : (search ? 10 : undefined);\n\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n if (allBlocks.length === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n blocks: [],\n hint: `No composition blocks found. Blocks are reusable patterns showing how components wire together (e.g., \"Login Form\", \"Settings Page\"). Create .block.ts files and run \\`${BRAND.cliCommand} build\\`.`,\n }),\n }],\n };\n }\n\n let filtered = allBlocks;\n\n if (blockName) {\n filtered = filtered.filter(\n b => b.name.toLowerCase() === blockName.toLowerCase()\n );\n if (filtered.length === 0) {\n const allBlockNames = allBlocks.map(b => b.name);\n const closest = findClosestMatch(blockName, allBlockNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Block \"${blockName}\" not found.${suggestion} Use ${TOOL_NAMES.blocks} to see available blocks.`);\n }\n }\n\n if (search) {\n if (blockIndex) {\n // Use Orama BM25 search with synonym expansion for relevance-ranked results\n const ranked = searchBlocks(search, blockIndex, 50);\n const rankedNames = new Set(ranked.map(r => r.name.toLowerCase()));\n filtered = filtered.filter(b => rankedNames.has(b.name.toLowerCase()));\n // Re-order filtered to match Orama relevance ranking\n filtered.sort((a, b) => {\n const aIdx = ranked.findIndex(r => r.name.toLowerCase() === a.name.toLowerCase());\n const bIdx = ranked.findIndex(r => r.name.toLowerCase() === b.name.toLowerCase());\n return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);\n });\n } else {\n // Fallback: substring matching (blockIndex should always exist, but defensive)\n filtered = filtered.filter(b => {\n const haystack = [\n b.name,\n b.description,\n ...(b.tags ?? []),\n ...b.components,\n b.category,\n ].join(' ').toLowerCase();\n return haystack.includes(search);\n });\n }\n }\n\n if (component) {\n filtered = filtered.filter(b =>\n b.components.some(c => c.toLowerCase() === component)\n );\n }\n\n if (category) {\n filtered = filtered.filter(b =>\n b.category.toLowerCase() === category\n );\n }\n\n // Check if any blocks use Icon components — add import hint\n const blocksUseIcons = filtered.some(\n (b) => b.components.some((c) => c === 'Icon') ||\n (b.code && /\\bIcon\\b/.test(b.code))\n );\n const iconHint = blocksUseIcons\n ? \"Icon components in block code are from @phosphor-icons/react. Import them as: import { IconName } from '@phosphor-icons/react';\"\n : undefined;\n\n // Apply limit if specified\n if (blocksLimit !== undefined) {\n filtered = filtered.slice(0, blocksLimit);\n }\n\n const verbosity = (args?.verbosity as string) ?? 'standard';\n const blocksWithImports = await Promise.all(filtered.map(async (b) => {\n const imports = await buildImportStatements(\n b.components,\n async (componentName) => getPackageName(componentName)\n );\n const base = {\n name: b.name,\n description: b.description,\n category: b.category,\n components: b.components,\n tags: b.tags,\n import: imports.join('\\n'),\n imports,\n };\n if (verbosity === 'compact') return base;\n if (verbosity === 'full') return { ...base, code: b.code };\n // standard: code preview for long blocks\n const codeLines = b.code.split('\\n');\n const code = codeLines.length > 30\n ? codeLines.slice(0, 20).join('\\n') + '\\n// ... truncated (' + codeLines.length + ' lines total)'\n : b.code;\n return { ...base, code };\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: blocksWithImports.length,\n blocks: blocksWithImports,\n ...(iconHint && { iconHint }),\n ...(blocksWithImports.length === 0 && allBlocks.length > 0 && {\n hint: 'No blocks matching your query. Try broader search terms.',\n }),\n }),\n }],\n };\n }\n\n // ================================================================\n // TOKENS\n // ================================================================\n case TOOL_NAMES.tokens: {\n const data = await loadFragments();\n const category = (args?.category as string)?.toLowerCase() ?? undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const tokensLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 100) : (search ? 25 : undefined);\n\n const tokenData = data.tokens;\n\n if (!tokenData || tokenData.total === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n categories: {},\n hint: `No design tokens found. Add a tokens.include pattern to your ${BRAND.configFile} and run \\`${BRAND.cliCommand} build\\`.`,\n }),\n }],\n };\n }\n\n let filteredCategories: Record<string, Array<{ name: string; description?: string }>> = {};\n let filteredTotal = 0;\n\n // Fix: when search term matches a category name exactly, return all\n // tokens in that category (previously only searched token names/descriptions)\n const searchMatchesCategory = search\n ? Object.keys(tokenData.categories).find(cat => cat.toLowerCase() === search)\n : undefined;\n\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n if (category && cat !== category) continue;\n\n let filtered = tokens;\n if (search) {\n // If the search term IS a category name, include all tokens in that category\n if (searchMatchesCategory && cat.toLowerCase() === search) {\n filtered = tokens; // include all\n } else {\n filtered = tokens.filter(\n (t) => t.name.toLowerCase().includes(search) ||\n (t.description && t.description.toLowerCase().includes(search)) ||\n cat.toLowerCase().includes(search)\n );\n }\n }\n\n if (filtered.length > 0) {\n filteredCategories[cat] = filtered;\n filteredTotal += filtered.length;\n }\n }\n\n // Apply token limit per category (default 25 per category for search queries)\n if (tokensLimit !== undefined) {\n const limited = limitTokensPerCategory(filteredCategories, tokensLimit);\n filteredCategories = limited.categories;\n filteredTotal = limited.total;\n }\n\n let hint: string | undefined;\n if (filteredTotal === 0) {\n const availableCategories = Object.keys(tokenData.categories);\n if (category && search) {\n // Combined category + search returned no results\n const categoryTotal = tokenData.categories[category]?.length ?? 0;\n hint = categoryTotal > 0\n ? `No tokens matching \"${search}\" in category \"${category}\" (${categoryTotal} tokens in this category). Try a broader search or remove the search term.`\n : `Category \"${category}\" not found. Available: ${availableCategories.join(', ')}`;\n } else if (search) {\n hint = `No tokens matching \"${search}\". Available categories: ${availableCategories.join(', ')}`;\n } else if (category) {\n hint = `Category \"${category}\" not found. Available: ${availableCategories.join(', ')}`;\n }\n } else if (!category && !search) {\n hint = `Use var(--token-name) in your CSS/styles. Filter by category or search to narrow results.`;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n prefix: tokenData.prefix,\n total: filteredTotal,\n totalAvailable: tokenData.total,\n categories: filteredCategories,\n ...(hint && { hint }),\n ...((!category && !search) && {\n availableCategories: Object.entries(tokenData.categories).map(\n ([cat, tokens]) => ({ category: cat, count: tokens.length })\n ),\n }),\n }),\n }],\n };\n }\n\n // ================================================================\n // IMPLEMENT — one-shot discover + inspect + blocks + tokens\n // ================================================================\n case TOOL_NAMES.implement: {\n const data = await loadFragments();\n const useCase = args?.useCase as string;\n if (!useCase) {\n throw new Error('useCase is required');\n }\n\n const verbosity = (args?.verbosity as string) ?? 'standard';\n const { allFragments, allBlocks, localData } = buildLocalSearchData(\n data,\n {\n componentIndex,\n blockIndex,\n tokenIndex,\n }\n );\n const tokenData = data.tokens;\n const implLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 15) : 5;\n\n // Search each kind independently — no cross-kind competition for slots\n const [componentResults, blockResults, tokenResults] = await Promise.all([\n hybridSearch(useCase, localData, implLimit * 3, 'component', config.apiKey),\n hybridSearch(useCase, localData, implLimit, 'block', config.apiKey),\n hybridSearch(useCase, localData, implLimit, 'token', config.apiKey),\n ]);\n\n // Filter blocks by relevance floor (30% of top block score)\n const topBlockScore = blockResults.length > 0 ? blockResults[0].score : 0;\n const filteredBlockResults = blockResults.filter(r => r.score >= topBlockScore * 0.3);\n\n // Block-first component ranking: boost by block component frequency\n if (filteredBlockResults.length > 0) {\n const matchedBlocks = filteredBlockResults\n .map(r => allBlocks.find(b => b.name.toLowerCase() === r.name.toLowerCase()))\n .filter(Boolean) as typeof allBlocks;\n const blockFreq = buildBlockComponentFrequency(matchedBlocks);\n boostByBlockFrequency(componentResults, blockFreq);\n }\n\n // Take top matches after boosting (respects limit param)\n const topComponentResults = componentResults.slice(0, implLimit);\n const maxCompScore = topComponentResults.length > 0 ? topComponentResults[0].score : 0;\n\n // Map component results back to fragments\n const topMatches = topComponentResults.map((result) => {\n const fragment = allFragments.find(\n (s) => s.meta.name.toLowerCase() === result.name.toLowerCase()\n );\n return fragment ? { fragment, score: result.score } : null;\n }).filter(Boolean) as Array<{ fragment: CompiledFragment; score: number }>;\n\n // Build component details for top matches\n const components = await Promise.all(\n topMatches.map(async ({ fragment: s, score }) => {\n const pkgName = await getPackageName(s.meta.name);\n if (verbosity === 'compact') {\n return {\n name: s.meta.name,\n description: s.meta.description,\n confidence: assignConfidence(score, maxCompScore),\n import: `import { ${s.meta.name} } from '${pkgName}';`,\n };\n }\n const exampleLimit = verbosity === 'full' ? s.variants.length : 2;\n const propsLimit = verbosity === 'full' ? Object.keys(s.props ?? {}).length : 5;\n const examples = s.variants.slice(0, exampleLimit).map((v) => ({\n variant: v.name,\n code: v.code ?? `<${s.meta.name} />`,\n }));\n const propsSummary = Object.entries(s.props ?? {}).slice(0, propsLimit).map(\n ([pName, p]) => `${pName}${p.required ? ' (required)' : ''}: ${p.type}${p.values ? ` = ${p.values.join('|')}` : ''}`\n );\n return {\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n confidence: assignConfidence(score, maxCompScore),\n import: `import { ${s.meta.name} } from '${pkgName}';`,\n props: propsSummary,\n examples,\n guidelines: filterPlaceholders(s.usage?.when).slice(0, 3),\n accessibility: s.usage?.accessibility?.slice(0, 2) ?? [],\n };\n })\n );\n\n // Map block results back to full block data (up to 5)\n const matchingBlocks = (await Promise.all(filteredBlockResults.slice(0, 5).map(async (result) => {\n const block = allBlocks.find(\n (b) => b.name.toLowerCase() === result.name.toLowerCase()\n );\n if (!block) return null;\n const imports = await buildImportStatements(\n block.components,\n async (componentName) => getPackageName(componentName)\n );\n const codeLines = block.code.split('\\n');\n const code = codeLines.length > 30\n ? codeLines.slice(0, 20).join('\\n') + '\\n// ... truncated (' + codeLines.length + ' lines total)'\n : block.code;\n return {\n name: block.name,\n description: block.description,\n components: block.components,\n code,\n import: imports.join('\\n'),\n imports,\n };\n }))).filter(Boolean) as Array<{\n name: string;\n description: string;\n components: string[];\n code: string;\n import: string;\n imports: string[];\n }>;\n\n // Map token results to grouped format.\n // Fix: when BM25 search returns empty (use-case terms don't match token\n // names like \"--fui-space-2\"), extract semantic categories from the query\n // and return representative tokens from those categories.\n let relevantTokens: Record<string, string[]> | undefined;\n if (tokenResults.length > 0 && tokenData) {\n relevantTokens = {};\n for (const result of tokenResults) {\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n if (tokens.some((t) => t.name === result.name)) {\n if (!relevantTokens[cat]) relevantTokens[cat] = [];\n relevantTokens[cat].push(result.name);\n break;\n }\n }\n }\n if (Object.keys(relevantTokens).length === 0) relevantTokens = undefined;\n }\n\n // Fallback: extract relevant token categories from the use-case query\n if (!relevantTokens && tokenData) {\n const categories = extractTokenCategories(useCase);\n relevantTokens = {};\n for (const cat of categories) {\n const tokens = tokenData.categories[cat];\n if (tokens && tokens.length > 0) {\n // Include up to 5 representative tokens per category\n relevantTokens[cat] = tokens.slice(0, 5).map(t => t.name);\n }\n }\n if (Object.keys(relevantTokens).length === 0) relevantTokens = undefined;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n useCase,\n components,\n blocks: verbosity !== 'compact' && matchingBlocks.length > 0 ? matchingBlocks : undefined,\n tokens: verbosity !== 'compact' ? relevantTokens : undefined,\n noMatch: components.length === 0,\n summary: components.length > 0\n ? `Found ${components.length} component(s) for \"${useCase}\". ${matchingBlocks.length > 0 ? `Plus ${matchingBlocks.length} ready-to-use block(s).` : ''}`\n : `No components match \"${useCase}\". Try ${TOOL_NAMES.discover} with different terms${tokenData ? ` or ${TOOL_NAMES.tokens} for CSS variables` : ''}.`,\n }),\n }],\n };\n }\n\n // ================================================================\n // RENDER — HTTP-only (no Playwright)\n // ================================================================\n case TOOL_NAMES.render: {\n const componentName = args?.component as string;\n const variantName = args?.variant as string | undefined;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const viewport = args?.viewport as { width?: number; height?: number } | undefined;\n const figmaUrl = args?.figmaUrl as string | undefined;\n const threshold = (args?.threshold as number) ?? (figmaUrl ? 1.0 : config.threshold ?? DEFAULTS.diffThreshold);\n\n if (!componentName) {\n return {\n content: [{ type: 'text' as const, text: 'Error: component name is required' }],\n isError: true,\n };\n }\n\n // Validate component exists (provides \"did you mean?\" on typos)\n {\n const data = await loadFragments();\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n // --- Figma compare mode ---\n if (figmaUrl) {\n try {\n const result = await compareComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n props,\n figmaUrl,\n threshold,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Compare error: ${result.error}${result.suggestion ? `\\nSuggestion: ${result.suggestion}` : ''}`,\n }],\n isError: true,\n };\n }\n\n const content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> = [];\n\n const summaryText = result.match\n ? `MATCH: ${componentName} matches Figma design (${result.diffPercentage}% diff, threshold: ${result.threshold}%)`\n : `MISMATCH: ${componentName} differs from Figma design by ${result.diffPercentage}% (threshold: ${result.threshold}%)`;\n\n content.push({ type: 'text' as const, text: summaryText });\n\n if (result.diff && !result.match) {\n content.push({\n type: 'image' as const,\n data: result.diff.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n });\n content.push({\n type: 'text' as const,\n text: `Diff image above shows visual differences (red highlights). Changed regions: ${result.changedRegions?.length ?? 0}`,\n });\n }\n\n content.push({\n type: 'text' as const,\n text: JSON.stringify({\n match: result.match,\n diffPercentage: result.diffPercentage,\n threshold: result.threshold,\n figmaUrl: result.figmaUrl,\n changedRegions: result.changedRegions,\n }),\n });\n\n return { content };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to compare component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running and FIGMA_ACCESS_TOKEN is set.`,\n }],\n isError: true,\n };\n }\n }\n\n // --- Default: pure render mode ---\n try {\n const result = await renderComponent(viewerUrl, {\n component: componentName,\n props,\n variant: variantName,\n viewport: viewport ?? { width: 800, height: 600 },\n });\n\n if (result.error) {\n return {\n content: [{ type: 'text' as const, text: `Render error: ${result.error}` }],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'image' as const,\n data: result.screenshot!.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n },\n {\n type: 'text' as const,\n text: `Successfully rendered ${componentName}${variantName ? ` (variant: \"${variantName}\")` : ''}${Object.keys(props).length > 0 ? ` with props: ${JSON.stringify(props)}` : ''}`,\n },\n ],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to render component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // FIX — HTTP-only (no Playwright)\n // ================================================================\n case TOOL_NAMES.fix: {\n const data = await loadFragments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const fixType = (args?.fixType as 'token' | 'all') ?? 'all';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n try {\n const result = await fixComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n fixType,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Fix generation error: ${result.error}`,\n }],\n isError: true,\n };\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n fixType,\n patches: result.patches,\n summary: result.summary,\n patchCount: result.patches.length,\n nextStep: result.patches.length > 0\n ? 'Apply patches using your editor or `patch` command, then run fragments_render to confirm fixes.'\n : undefined,\n }),\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to generate fixes: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // A11Y — accessibility audit\n // ================================================================\n case TOOL_NAMES.a11y: {\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const standard = (args?.standard as 'AA' | 'AAA') ?? 'AA';\n const includeFixPatches = (args?.includeFixPatches as boolean) ?? false;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n // Validate component exists (provides \"did you mean?\" on typos)\n {\n const data = await loadFragments();\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n try {\n const result = await auditComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n standard,\n includeFixPatches,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `A11y audit error: ${result.error}`,\n }],\n isError: true,\n };\n }\n\n let nextStep: string;\n if (result.emptyAudit) {\n nextStep = `No testable elements found for ${variantName ? `variant \"${variantName}\"` : componentName}. The variant may not exist or renders no accessible content. Check available variants with ${TOOL_NAMES.inspect}(\"${componentName}\").`;\n } else if (result.passed) {\n nextStep = 'All accessibility checks passed. Consider running with standard: \"AAA\" for enhanced compliance.';\n } else {\n nextStep = `Fix the violations above, then re-run ${TOOL_NAMES.a11y} to verify. Use ${TOOL_NAMES.fix} for automated fixes.`;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n standard,\n totalViolations: result.results.reduce((sum, r) => sum + r.summary.total, 0),\n variantsPassingAA: `${result.aaPercent}%`,\n variantsPassingAAA: `${result.aaaPercent}%`,\n passed: result.passed,\n ...(result.emptyAudit && { emptyAudit: true }),\n results: result.results,\n nextStep,\n }),\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to audit component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // GRAPH — component relationship queries\n // ================================================================\n case TOOL_NAMES.graph: {\n const data = await loadFragments();\n const graphArgs: GraphToolArgs = {\n mode: (args?.mode as string) ?? 'health',\n component: args?.component as string | undefined,\n target: args?.target as string | undefined,\n edgeTypes: args?.edgeTypes as string[] | undefined,\n maxDepth: args?.maxDepth as number | undefined,\n };\n\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const result = handleGraphTool(\n graphArgs,\n data.graph,\n data.blocks ?? data.recipes,\n allNames,\n );\n\n if (result.isError) {\n return {\n content: [{ type: 'text' as const, text: result.text }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: 'text' as const, text: result.text }],\n };\n }\n\n // ================================================================\n // GENERATE_UI — proxy to playground API\n // ================================================================\n case TOOL_NAMES.generate_ui: {\n const prompt = args?.prompt as string;\n if (!prompt) {\n throw new Error('prompt is required');\n }\n\n const currentTree = args?.currentTree as Record<string, unknown> | undefined;\n const playgroundUrl = config.playgroundUrl ?? 'https://usefragments.com';\n\n const response = await fetch(`${playgroundUrl}/api/playground/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n prompt,\n ...(currentTree && { currentSpec: currentTree }),\n }),\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new Error(`Playground API error (${response.status}): ${errorBody}`);\n }\n\n // The API returns a streaming text response with the element tree JSON\n const text = await response.text();\n\n return {\n content: [{\n type: 'text' as const,\n text,\n }],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n }),\n }],\n isError: true,\n };\n }\n });\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<void> {\n const server = createMcpServer(config);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n/**\n * Smithery sandbox server for capability scanning.\n * Returns a server instance with default config so Smithery can enumerate tools.\n */\nexport function createSandboxServer() {\n return createMcpServer({ projectRoot: process.cwd() });\n}\n","/**\n * Brand constants for easy rebranding if domain availability requires it.\n * All naming throughout the codebase should reference these constants.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\nexport const BRAND = {\n /** Display name (e.g., \"Fragments\") */\n name: \"Fragments\",\n\n /** Lowercase name for file paths and CLI (e.g., \"fragments\") */\n nameLower: \"fragments\",\n\n /** File extension for fragment definition files (e.g., \".fragment.tsx\") */\n fileExtension: \".fragment.tsx\",\n\n /** Legacy file extension for segments (still supported for migration) */\n legacyFileExtension: \".segment.tsx\",\n\n /** JSON file extension for compiled output */\n jsonExtension: \".fragment.json\",\n\n /** Default output file name (e.g., \"fragments.json\") */\n outFile: \"fragments.json\",\n\n /** Config file name (e.g., \"fragments.config.ts\") */\n configFile: \"fragments.config.ts\",\n\n /** Legacy config file name (still supported for migration) */\n legacyConfigFile: \"segments.config.ts\",\n\n /** CLI command name (e.g., \"fragments\") */\n cliCommand: \"fragments\",\n\n /** Package scope (e.g., \"@fragments\") */\n packageScope: \"@fragments\",\n\n /** Directory for storing fragments, registry, and cache */\n dataDir: \".fragments\",\n\n /** Components subdirectory within .fragments/ */\n componentsDir: \"components\",\n\n /** Registry file name */\n registryFile: \"registry.json\",\n\n /** Context file name (AI-ready markdown) */\n contextFile: \"context.md\",\n\n /** Screenshots subdirectory */\n screenshotsDir: \"screenshots\",\n\n /** Cache subdirectory (gitignored) */\n cacheDir: \"cache\",\n\n /** Diff output subdirectory (gitignored) */\n diffDir: \"diff\",\n\n /** Manifest filename */\n manifestFile: \"manifest.json\",\n\n /** Prefix for localStorage keys (e.g., \"fragments-\") */\n storagePrefix: \"fragments-\",\n\n /** Static viewer HTML file name */\n viewerHtmlFile: \"fragments-viewer.html\",\n\n /** MCP tool name prefix (e.g., \"fragments_\") */\n mcpToolPrefix: \"fragments_\",\n\n /** File extension for block definition files */\n blockFileExtension: \".block.ts\",\n\n /** @deprecated Use blockFileExtension instead */\n recipeFileExtension: \".recipe.ts\",\n\n /** Vite plugin namespace */\n vitePluginNamespace: \"fragments-core-shim\",\n} as const;\n\nexport type Brand = typeof BRAND;\n\n/**\n * Default configuration values for the service.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\nexport const DEFAULTS = {\n /** Default viewport dimensions */\n viewport: {\n width: 1280,\n height: 800,\n },\n\n /** Default diff threshold (percentage) */\n diffThreshold: 5,\n\n /** Browser pool size */\n poolSize: 3,\n\n /** Idle timeout before browser shutdown (ms) - 5 minutes */\n idleTimeoutMs: 5 * 60 * 1000,\n\n /** Delay after render before capture (ms) */\n captureDelayMs: 100,\n\n /** Font loading timeout (ms) */\n fontTimeoutMs: 3000,\n\n /** Default theme */\n theme: \"light\" as const,\n\n /** Dev server port */\n port: 6006,\n} as const;\n\nexport type Defaults = typeof DEFAULTS;\n","/**\n * Fragment discovery — finds fragments.json files in the project.\n *\n * Extracted from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\n\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { BRAND } from './constants.js';\n\n/**\n * Resolve workspace directory globs (e.g. \"apps/*\") into actual paths.\n */\nfunction resolveWorkspaceGlob(baseDir: string, pattern: string): string[] {\n const parts = pattern.split('/');\n let dirs = [baseDir];\n\n for (const part of parts) {\n if (part === '**') continue;\n const next: string[] = [];\n for (const d of dirs) {\n if (part === '*') {\n try {\n for (const entry of readdirSync(d, { withFileTypes: true })) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {\n next.push(join(d, entry.name));\n }\n }\n } catch { /* unreadable dir */ }\n } else {\n const candidate = join(d, part);\n if (existsSync(candidate)) next.push(candidate);\n }\n }\n dirs = next;\n }\n\n return dirs;\n}\n\n/**\n * Detect workspace directories from package.json \"workspaces\" or pnpm-workspace.yaml.\n */\nfunction getWorkspaceDirs(rootDir: string): string[] {\n const dirs: string[] = [];\n\n // npm/yarn: package.json \"workspaces\" field\n const rootPkgPath = join(rootDir, 'package.json');\n if (existsSync(rootPkgPath)) {\n try {\n const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));\n const workspaces = Array.isArray(rootPkg.workspaces)\n ? rootPkg.workspaces\n : rootPkg.workspaces?.packages;\n if (Array.isArray(workspaces)) {\n for (const pattern of workspaces) {\n dirs.push(...resolveWorkspaceGlob(rootDir, pattern));\n }\n return dirs;\n }\n } catch { /* unreadable */ }\n }\n\n // pnpm: pnpm-workspace.yaml\n const pnpmWsPath = join(rootDir, 'pnpm-workspace.yaml');\n if (existsSync(pnpmWsPath)) {\n try {\n const content = readFileSync(pnpmWsPath, 'utf-8');\n const lines = content.split('\\n');\n let inPackages = false;\n for (const line of lines) {\n if (/^packages\\s*:/.test(line)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n const match = line.match(/^\\s+-\\s+['\"]?([^'\"#\\n]+)['\"]?/);\n if (match) {\n dirs.push(...resolveWorkspaceGlob(rootDir, match[1].trim()));\n } else if (/^\\S/.test(line) && line.trim()) {\n break;\n }\n }\n }\n } catch { /* unreadable */ }\n }\n\n return dirs;\n}\n\n/**\n * Resolve a dependency's package.json path. Tries the standard subpath first,\n * then falls back to resolving the package's main entry and walking up to\n * find package.json — necessary when the package's `exports` map doesn't\n * expose `./package.json`.\n */\nfunction resolveDepPackageJson(\n localRequire: NodeRequire,\n depName: string\n): string | null {\n // Fast path: package exposes ./package.json in exports\n try {\n return localRequire.resolve(`${depName}/package.json`);\n } catch {\n // Blocked by exports map\n }\n\n // Fallback: resolve the package's main entry and walk up to package.json\n try {\n const mainPath = localRequire.resolve(depName);\n let dir = dirname(mainPath);\n while (true) {\n const candidate = join(dir, 'package.json');\n if (existsSync(candidate)) {\n const pkg = JSON.parse(readFileSync(candidate, 'utf-8'));\n if (pkg.name === depName) return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // Package not resolvable at all\n }\n\n return null;\n}\n\n/**\n * Scan a directory's package.json deps for packages with a \"fragments\" field.\n */\nfunction findFragmentsInDeps(dir: string, found: string[]): void {\n const pkgJsonPath = join(dir, 'package.json');\n if (!existsSync(pkgJsonPath)) return;\n\n try {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies,\n };\n const localRequire = createRequire(join(dir, 'noop.js'));\n for (const depName of Object.keys(allDeps)) {\n try {\n const depPkgPath = resolveDepPackageJson(localRequire, depName);\n if (!depPkgPath) continue;\n const depPkg = JSON.parse(readFileSync(depPkgPath, 'utf-8'));\n if (depPkg.fragments) {\n const fragmentsPath = join(dirname(depPkgPath), depPkg.fragments);\n if (existsSync(fragmentsPath) && !found.includes(fragmentsPath)) {\n found.push(fragmentsPath);\n }\n }\n } catch {\n // Package not resolvable or unreadable, skip\n }\n }\n } catch {\n // No package.json or unreadable\n }\n}\n\n/**\n * Find fragments.json files:\n * 1. Walk up from startDir (for library authors with a local build)\n * 2. Read package.json deps and resolve packages with a \"fragments\" field\n * 3. Check workspace packages' deps (monorepo support)\n *\n * Uses Node.js module resolution (createRequire) to handle all package\n * managers: pnpm symlinks, yarn PnP, monorepo hoisting, etc.\n */\nexport function findFragmentsJson(startDir: string): string[] {\n const found: string[] = [];\n const resolvedStart = resolve(startDir);\n\n // 1. Walk upward from startDir (library author flow)\n let dir = resolvedStart;\n while (true) {\n const candidate = join(dir, BRAND.outFile);\n if (existsSync(candidate)) {\n found.push(candidate);\n break;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // 2. Check root package.json deps\n findFragmentsInDeps(resolvedStart, found);\n\n // 3. Check workspace packages' deps (monorepo support)\n if (found.length === 0 || existsSync(join(resolvedStart, 'pnpm-workspace.yaml'))) {\n const workspaceDirs = getWorkspaceDirs(resolvedStart);\n for (const wsDir of workspaceDirs) {\n findFragmentsInDeps(wsDir, found);\n }\n }\n\n return found;\n}\n","/**\n * Orama-powered BM25 search indexes for components, blocks, and tokens.\n *\n * Replaces the bag-of-words keyword scorer with Orama's built-in BM25 engine,\n * which provides IDF weighting (automatically downweights common terms like\n * \"page\", \"section\", \"content\"), stemming, and field-level boosting.\n */\n\nimport { create, insertMultiple, search } from '@orama/orama';\nimport type { AnyOrama } from '@orama/orama';\nimport type { CompiledFragment, CompiledBlock, CompiledTokenData } from '@fragments-sdk/context/types';\nimport type { ScoredResult, EntryKind } from './search.js';\n\n// ---------------------------------------------------------------------------\n// Synonym map (shared with search.ts — imported via re-export)\n// ---------------------------------------------------------------------------\n\nexport const SYNONYM_MAP: Record<string, string[]> = {\n 'form': ['input', 'field', 'submit', 'validation'],\n 'input': ['form', 'field', 'text', 'entry'],\n 'button': ['action', 'click', 'submit', 'trigger'],\n 'action': ['button', 'click', 'trigger'],\n 'submit': ['button', 'form', 'action', 'send'],\n 'alert': ['notification', 'message', 'warning', 'error', 'feedback'],\n 'notification': ['alert', 'message', 'toast'],\n 'feedback': ['form', 'comment', 'review', 'rating'],\n 'card': ['container', 'panel', 'box', 'content'],\n 'toggle': ['switch', 'checkbox', 'boolean', 'on/off'],\n 'switch': ['toggle', 'checkbox', 'boolean'],\n 'badge': ['tag', 'label', 'status', 'indicator'],\n 'status': ['badge', 'indicator', 'state'],\n 'login': ['auth', 'signin', 'authentication', 'form'],\n 'auth': ['login', 'signin', 'authentication'],\n 'chat': ['message', 'conversation', 'ai'],\n 'table': ['data', 'grid', 'list', 'rows'],\n 'textarea': ['text', 'input', 'multiline', 'area', 'comment'],\n 'area': ['textarea', 'multiline', 'text'],\n 'landing': ['page', 'hero', 'marketing', 'section', 'layout'],\n 'hero': ['landing', 'marketing', 'banner', 'headline', 'section'],\n 'marketing': ['landing', 'hero', 'pricing', 'testimonial', 'cta'],\n 'cta': ['marketing', 'banner', 'action', 'button'],\n 'testimonial': ['marketing', 'review', 'quote', 'feedback'],\n 'layout': ['stack', 'grid', 'box', 'container', 'page'],\n 'page': ['layout', 'landing', 'section', 'container'],\n 'section': ['hero', 'feature', 'testimonial', 'cta', 'faq'],\n 'pricing': ['card', 'plan', 'tier', 'marketing'],\n 'plan': ['pricing', 'card', 'tier', 'subscription'],\n 'dashboard': ['metrics', 'stats', 'chart', 'card', 'grid'],\n 'metrics': ['dashboard', 'stats', 'progress', 'number'],\n 'stats': ['metrics', 'dashboard', 'progress', 'badge'],\n 'chart': ['dashboard', 'metrics', 'data', 'graph'],\n};\n\n// ---------------------------------------------------------------------------\n// Query expansion via synonyms\n// ---------------------------------------------------------------------------\n\n/**\n * Expand a query string with synonym terms.\n * Returns the expanded query as a single string suitable for Orama `term`.\n */\nexport function expandQuery(query: string): string {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const expanded = new Set(terms);\n for (const term of terms) {\n const synonyms = SYNONYM_MAP[term];\n if (synonyms) {\n for (const syn of synonyms) expanded.add(syn);\n }\n }\n return Array.from(expanded).join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// Shared two-pass search pattern\n// ---------------------------------------------------------------------------\n\ninterface TwoPassConfig {\n index: AnyOrama;\n query: string;\n properties: string[];\n boost: Record<string, number>;\n limit: number;\n kind: EntryKind;\n}\n\n/**\n * Two-pass BM25 search: original terms weighted 2x, synonym-expanded terms 1x.\n * Prevents synonym noise from outranking truly relevant results.\n */\nexport function twoPassSearch(config: TwoPassConfig): ScoredResult[] {\n const { index, query, properties, boost, limit, kind } = config;\n\n const baseConfig = {\n mode: 'fulltext' as const,\n properties,\n boost,\n limit,\n };\n\n const originalTermsQuery = query.toLowerCase().split(/\\s+/).filter(Boolean).join(' ');\n const expandedQuery = expandQuery(query);\n\n // First pass: original terms only (moderate threshold to filter weak matches)\n const originalResults = search(index, { term: originalTermsQuery, ...baseConfig, threshold: 0.8 });\n // Second pass: synonym-expanded (permissive — scoring handles relevance via 1x weight)\n const expandedResults = search(index, { term: expandedQuery, ...baseConfig, threshold: 1 });\n\n type Hit = { score: number; document: { name: string } };\n const origHits = (originalResults as unknown as { hits: Hit[] }).hits;\n const expHits = (expandedResults as unknown as { hits: Hit[] }).hits;\n\n // Combine scores: original terms get 2x weight\n const scoreMap = new Map<string, number>();\n for (const hit of origHits) {\n scoreMap.set(hit.document.name, (hit.score || 0) * 2);\n }\n for (const hit of expHits) {\n const name = hit.document.name;\n const existing = scoreMap.get(name) ?? 0;\n scoreMap.set(name, existing + (hit.score || 0));\n }\n\n const scored: ScoredResult[] = [];\n for (const [name, score] of scoreMap) {\n if (score > 0) {\n scored.push({ name, kind, rank: scored.length, score });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n scored.forEach((s, i) => { s.rank = i; });\n\n return scored;\n}\n\n// ---------------------------------------------------------------------------\n// Component index\n// ---------------------------------------------------------------------------\n\nconst componentSchema = {\n name: 'string' as const,\n description: 'string' as const,\n category: 'string' as const,\n tags: 'string' as const,\n whenUsed: 'string' as const,\n variants: 'string' as const,\n status: 'string' as const,\n};\n\nexport type ComponentIndex = AnyOrama;\n\nexport function buildComponentIndex(fragments: CompiledFragment[]): ComponentIndex {\n const db = create({ schema: componentSchema, language: 'english' });\n\n const docs = fragments.map((f) => ({\n name: f.meta.name,\n description: f.meta.description ?? '',\n category: f.meta.category ?? '',\n tags: (f.meta.tags ?? []).join(' '),\n whenUsed: (f.usage?.when ?? []).join(' '),\n variants: f.variants.map(v => `${v.name} ${v.description || ''}`).join(' '),\n status: f.meta.status ?? 'stable',\n }));\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchComponents(\n query: string,\n index: ComponentIndex,\n fragments: CompiledFragment[],\n limit = 50,\n): ScoredResult[] {\n const boostConfig = {\n mode: 'fulltext' as const,\n properties: ['name', 'whenUsed', 'description', 'category', 'tags', 'variants'],\n boost: {\n name: 3,\n whenUsed: 2.5,\n description: 2,\n category: 1.5,\n tags: 1.5,\n variants: 1,\n },\n limit,\n };\n\n // Two-pass search: original terms weighted 2x, synonym terms 1x\n // This prevents synonym noise (\"box\", \"container\") from outranking truly relevant results\n const originalTermsList = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const originalTermsQuery = originalTermsList.join(' ');\n const expandedQuery = expandQuery(query);\n\n // First pass: original terms, moderate threshold; second pass: synonyms, permissive\n const originalResults = search(index, { term: originalTermsQuery, ...boostConfig, threshold: 0.8 });\n const expandedResults = search(index, { term: expandedQuery, ...boostConfig, threshold: 1 });\n\n type Hit = { score: number; document: { name: string } };\n const origHits = (originalResults as unknown as { hits: Hit[] }).hits;\n const expHits = (expandedResults as unknown as { hits: Hit[] }).hits;\n\n // Combine scores: original terms get 2x weight\n const scoreMap = new Map<string, number>();\n for (const hit of origHits) {\n scoreMap.set(hit.document.name, (hit.score || 0) * 2);\n }\n for (const hit of expHits) {\n const name = hit.document.name;\n const existing = scoreMap.get(name) ?? 0;\n scoreMap.set(name, existing + (hit.score || 0));\n }\n\n // Build a name→fragment lookup for status bonuses\n const fragmentMap = new Map<string, CompiledFragment>();\n for (const f of fragments) {\n fragmentMap.set(f.meta.name.toLowerCase(), f);\n }\n\n // Exact name match bonus: if a component name matches an original query term exactly,\n // boost it above similar-named components (e.g., \"Button\" > \"ButtonGroup\" for \"button action\")\n const originalTermsSet = new Set(originalTermsList);\n\n // Build scored results with status + name match adjustments\n const scored: ScoredResult[] = [];\n for (const [name, rawScore] of scoreMap) {\n let score = rawScore;\n const nameLower = name.toLowerCase();\n const fragment = fragmentMap.get(nameLower);\n\n // Exact name match bonus — strong signal that this specific component was requested\n // Must be large enough to overcome BM25 score differences from compound names\n // (e.g., \"ButtonGroup\" matching more fields than \"Button\")\n if (originalTermsSet.has(nameLower)) {\n score += 25;\n }\n\n // Apply status bonus/penalty (matches old scorer)\n if (fragment) {\n if (fragment.meta.status === 'stable') score += 5;\n else if (fragment.meta.status === 'beta') score += 2;\n if (fragment.meta.status === 'deprecated') score -= 25;\n }\n\n if (score > 0) {\n scored.push({ name, kind: 'component' as EntryKind, rank: scored.length, score });\n }\n }\n\n // Sort by score descending and assign ranks\n scored.sort((a, b) => b.score - a.score);\n scored.forEach((s, i) => { s.rank = i; });\n\n return scored;\n}\n\n// ---------------------------------------------------------------------------\n// Block index\n// ---------------------------------------------------------------------------\n\nconst blockSchema = {\n name: 'string' as const,\n description: 'string' as const,\n category: 'string' as const,\n tags: 'string' as const,\n components: 'string' as const,\n};\n\nexport type BlockIndex = AnyOrama;\n\nexport function buildBlockIndex(blocks: CompiledBlock[]): BlockIndex {\n const db = create({ schema: blockSchema, language: 'english' });\n\n const docs = blocks.map((b) => ({\n name: b.name,\n description: b.description ?? '',\n category: b.category ?? '',\n tags: (b.tags ?? []).join(' '),\n components: b.components.join(' '),\n }));\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchBlocks(\n query: string,\n index: BlockIndex,\n limit = 50,\n): ScoredResult[] {\n return twoPassSearch({\n index,\n query,\n properties: ['name', 'description', 'components', 'tags', 'category'],\n boost: {\n name: 3,\n description: 2,\n components: 1.5,\n tags: 1.5,\n category: 1.5,\n },\n limit,\n kind: 'block' as EntryKind,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Token index\n// ---------------------------------------------------------------------------\n\nconst tokenSchema = {\n name: 'string' as const,\n category: 'string' as const,\n description: 'string' as const,\n};\n\nexport type TokenIndex = AnyOrama;\n\nexport function buildTokenIndex(tokenData: CompiledTokenData): TokenIndex {\n const db = create({ schema: tokenSchema, language: 'english' });\n\n const docs: Array<{ name: string; category: string; description: string }> = [];\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n for (const token of tokens) {\n docs.push({\n name: token.name,\n category: cat,\n description: token.description ?? '',\n });\n }\n }\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchTokens(\n query: string,\n index: TokenIndex,\n limit = 50,\n): ScoredResult[] {\n return twoPassSearch({\n index,\n query,\n properties: ['name', 'category', 'description'],\n boost: {\n name: 2.5,\n category: 2,\n description: 1.5,\n },\n limit,\n kind: 'token' as EntryKind,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Semantic category extraction for implement tool token matching\n// ---------------------------------------------------------------------------\n\n/** Maps use-case keywords to relevant token categories */\nconst USE_CASE_TOKEN_CATEGORIES: Record<string, string[]> = {\n 'table': ['spacing', 'borders', 'surfaces', 'text'],\n 'data': ['spacing', 'borders', 'surfaces'],\n 'grid': ['spacing', 'layout'],\n 'form': ['spacing', 'borders', 'radius', 'focus'],\n 'input': ['spacing', 'borders', 'radius', 'focus'],\n 'card': ['surfaces', 'shadows', 'radius', 'borders', 'spacing'],\n 'button': ['colors', 'radius', 'spacing', 'focus'],\n 'layout': ['spacing', 'layout', 'surfaces'],\n 'dashboard': ['spacing', 'surfaces', 'borders', 'shadows'],\n 'chat': ['spacing', 'surfaces', 'radius', 'shadows'],\n 'modal': ['shadows', 'surfaces', 'radius', 'spacing'],\n 'dialog': ['shadows', 'surfaces', 'radius', 'spacing'],\n 'navigation': ['spacing', 'surfaces', 'borders'],\n 'sidebar': ['spacing', 'surfaces', 'borders'],\n 'hero': ['spacing', 'typography', 'colors'],\n 'landing': ['spacing', 'typography', 'colors'],\n 'pricing': ['spacing', 'surfaces', 'borders', 'radius'],\n 'auth': ['spacing', 'borders', 'radius', 'focus'],\n 'login': ['spacing', 'borders', 'radius', 'focus'],\n 'dark': ['colors', 'surfaces'],\n 'theme': ['colors', 'surfaces', 'text'],\n};\n\n/**\n * Extract relevant token categories from a use-case query.\n * Returns category names that should be included in implement results.\n */\nexport function extractTokenCategories(query: string): string[] {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const categories = new Set<string>();\n\n for (const term of terms) {\n const cats = USE_CASE_TOKEN_CATEGORIES[term];\n if (cats) {\n for (const cat of cats) categories.add(cat);\n }\n }\n\n // If nothing matched, return common defaults\n if (categories.size === 0) {\n return ['spacing', 'colors', 'surfaces'];\n }\n\n return Array.from(categories);\n}\n","/**\n * Search module for MCP server component discovery.\n *\n * Default (free): BM25 scoring via Orama with synonym expansion and multi-field\n * boosted matching against fragments.json. No external API calls.\n *\n * Premium (--api-key): adds Convex-hosted vector search (Voyage-Code-3 embeddings)\n * fused with keyword results via Reciprocal Rank Fusion (RRF).\n */\n\nimport type { CompiledFragment, CompiledBlock, CompiledTokenData } from '@fragments-sdk/context/types';\nimport type { SerializedComponentGraph } from '@fragments-sdk/context/graph';\nimport {\n buildComponentIndex,\n buildBlockIndex,\n buildTokenIndex,\n searchComponents as oramaSearchComponents,\n searchBlocks as oramaSearchBlocks,\n searchTokens as oramaSearchTokens,\n type ComponentIndex,\n type BlockIndex,\n type TokenIndex,\n} from './orama-index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Entry kind discriminator — matches the Convex schema */\nexport type EntryKind = 'component' | 'block' | 'token';\n\nexport interface ScoredResult {\n /** Entry name */\n name: string;\n /** What kind of entry (component, block, token) */\n kind: EntryKind;\n /** Rank position (0-indexed) */\n rank: number;\n /** Raw score from the search system */\n score: number;\n}\n\ninterface ConvexSearchResponse {\n results: Array<{\n kind: string;\n name: string;\n score: number;\n description: string;\n category: string;\n }>;\n}\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nconst CONVEX_SEARCH_URL = 'https://combative-jay-834.convex.site/search';\nconst CONVEX_TIMEOUT_MS = 3000;\n\n// ---------------------------------------------------------------------------\n// Vector search via Convex (PREMIUM)\n// ---------------------------------------------------------------------------\n\n/**\n * PREMIUM — Convex-hosted semantic vector search.\n *\n * This function is only called when a valid API key is provided via --api-key.\n * The Convex endpoint is auth-gated (SEARCH_API_KEY env var in Convex dashboard).\n *\n * Re-enablement checklist (for when you're ready to sell premium):\n * 1. Convex endpoint auth is already in place (SEARCH_API_KEY env var)\n * 2. --api-key CLI flag and Authorization header plumbing already wired below\n * 3. To enable for a paying customer: issue them a key matching SEARCH_API_KEY,\n * they add --api-key <key> to their MCP config\n * 4. Optionally add per-key rate limiting in convex/search.ts later\n *\n * @param apiKey - Bearer token passed as Authorization header to Convex\n * @param kind - Optional filter to only search components, blocks, or tokens\n * Returns an empty array if Convex is unreachable (offline, timeout, error, 401).\n */\nexport async function searchConvex(\n query: string,\n apiKey: string,\n limit = 10,\n kind?: EntryKind\n): Promise<ScoredResult[]> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), CONVEX_TIMEOUT_MS);\n\n const response = await fetch(CONVEX_SEARCH_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ query, limit, ...(kind && { kind }) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return [];\n }\n\n const data = (await response.json()) as ConvexSearchResponse;\n\n return data.results.map((r, i) => ({\n name: r.name,\n kind: (r.kind as EntryKind) ?? 'component',\n rank: i,\n score: r.score,\n }));\n } catch {\n // Network error, timeout, or Convex unreachable — silent fallback\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — components\n// ---------------------------------------------------------------------------\n\n/**\n * Score components against a query using BM25 via Orama.\n *\n * If an Orama index is provided (via LocalSearchData.componentIndex),\n * it will be used directly. Otherwise, a temporary index is built on the fly.\n */\nexport function keywordScoreComponents(\n query: string,\n fragments: CompiledFragment[],\n componentIndex?: ComponentIndex,\n): ScoredResult[] {\n const index = componentIndex ?? buildComponentIndex(fragments);\n return oramaSearchComponents(query, index, fragments);\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — blocks\n// ---------------------------------------------------------------------------\n\n/**\n * Score blocks against a query using BM25 via Orama.\n */\nexport function keywordScoreBlocks(\n query: string,\n blocks: CompiledBlock[],\n blockIndex?: BlockIndex,\n): ScoredResult[] {\n const index = blockIndex ?? buildBlockIndex(blocks);\n return oramaSearchBlocks(query, index);\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — tokens\n// ---------------------------------------------------------------------------\n\n/**\n * Score tokens against a query using BM25 via Orama.\n */\nexport function keywordScoreTokens(\n query: string,\n tokenData: CompiledTokenData,\n tokenIndex?: TokenIndex,\n): ScoredResult[] {\n const index = tokenIndex ?? buildTokenIndex(tokenData);\n return oramaSearchTokens(query, index);\n}\n\n// ---------------------------------------------------------------------------\n// Reciprocal Rank Fusion\n// ---------------------------------------------------------------------------\n\n/**\n * Reciprocal Rank Fusion (RRF) — merges multiple ranked result lists\n * into a single ranking using the formula: score = sum(1 / (k + rank))\n */\nfunction reciprocalRankFusion(\n resultSets: Array<{ label: string; results: ScoredResult[] }>,\n k = 60\n): ScoredResult[] {\n // Use kind:name as key to avoid collisions across kinds\n const scoreMap = new Map<string, { score: number; kind: EntryKind; name: string }>();\n\n for (const { results } of resultSets) {\n for (let rank = 0; rank < results.length; rank++) {\n const result = results[rank];\n const key = `${result.kind}:${result.name}`;\n const rrfScore = 1 / (k + rank + 1);\n\n const existing = scoreMap.get(key);\n if (existing) {\n existing.score += rrfScore;\n } else {\n scoreMap.set(key, { score: rrfScore, kind: result.kind, name: result.name });\n }\n }\n }\n\n const fused: ScoredResult[] = [];\n for (const [, { score, kind, name }] of scoreMap) {\n fused.push({ name, kind, rank: 0, score });\n }\n\n fused.sort((a, b) => b.score - a.score);\n fused.forEach((r, i) => { r.rank = i; });\n\n return fused;\n}\n\n// ---------------------------------------------------------------------------\n// Hybrid search (public API)\n// ---------------------------------------------------------------------------\n\n/** Data sources for local keyword scoring */\nexport interface LocalSearchData {\n fragments: CompiledFragment[];\n blocks?: CompiledBlock[];\n tokenData?: CompiledTokenData;\n /** Serialized component graph for neighbor boosting */\n graph?: SerializedComponentGraph;\n /** Pre-built Orama indexes (set at server startup for performance) */\n componentIndex?: ComponentIndex;\n blockIndex?: BlockIndex;\n tokenIndex?: TokenIndex;\n}\n\n/** Options for hybridSearch */\nexport interface HybridSearchOptions {\n /** Max results to return */\n limit?: number;\n /** Filter to a specific entry kind */\n kind?: EntryKind;\n /** Premium API key — when provided, enables Convex vector search + RRF fusion */\n apiKey?: string;\n}\n\n/**\n * Search across components, blocks, and tokens.\n *\n * Default: BM25 scoring via Orama with synonym expansion and field boosting.\n * Premium (apiKey provided): adds Convex vector search fused via RRF.\n *\n * @param kind - Optional filter to restrict results to a specific kind\n */\nexport async function hybridSearch(\n query: string,\n data: LocalSearchData,\n limit = 10,\n kind?: EntryKind,\n apiKey?: string,\n): Promise<ScoredResult[]> {\n // Build local BM25 results based on requested kind(s)\n const keywordResults: ScoredResult[] = [];\n\n if (!kind || kind === 'component') {\n keywordResults.push(...keywordScoreComponents(query, data.fragments, data.componentIndex));\n }\n if ((!kind || kind === 'block') && data.blocks) {\n keywordResults.push(...keywordScoreBlocks(query, data.blocks, data.blockIndex));\n }\n if ((!kind || kind === 'token') && data.tokenData) {\n keywordResults.push(...keywordScoreTokens(query, data.tokenData, data.tokenIndex));\n }\n\n // Re-sort combined keyword results\n keywordResults.sort((a, b) => b.score - a.score);\n keywordResults.forEach((r, i) => { r.rank = i; });\n\n // --- Premium: vector search (only when API key is provided) ---\n if (!apiKey) {\n return keywordResults.slice(0, limit);\n }\n\n const vectorResults = await searchConvex(query, apiKey, limit, kind);\n\n // If vector search returned nothing, just use keyword results\n if (vectorResults.length === 0) {\n return keywordResults.slice(0, limit);\n }\n\n // Build graph neighbor boost list if graph data is available\n const graphBoostResults: ScoredResult[] = [];\n if (data.graph) {\n try {\n const { ComponentGraphEngine, deserializeGraph } = await import('@fragments-sdk/context/graph');\n const graph = deserializeGraph(data.graph);\n const engine = new ComponentGraphEngine(graph);\n\n // Collect top component results from keyword+vector\n const topComponents = [...keywordResults, ...vectorResults]\n .filter(r => r.kind === 'component')\n .slice(0, 5);\n\n // Find graph neighbors of top results\n const neighborSet = new Set<string>();\n for (const result of topComponents) {\n const neighbors = engine.neighbors(result.name, 1);\n for (const n of neighbors.neighbors) {\n if (!neighborSet.has(n.component)) {\n neighborSet.add(n.component);\n graphBoostResults.push({\n name: n.component,\n kind: 'component',\n rank: graphBoostResults.length,\n score: 1, // Will be normalized through RRF\n });\n }\n }\n }\n } catch {\n // Graph boost is best-effort — fail silently\n }\n }\n\n // Fuse with RRF\n const resultSets: Array<{ label: string; results: ScoredResult[] }> = [\n { label: 'vector', results: vectorResults },\n { label: 'keyword', results: keywordResults },\n ];\n\n if (graphBoostResults.length > 0) {\n resultSets.push({ label: 'graph', results: graphBoostResults });\n }\n\n const fused = reciprocalRankFusion(resultSets);\n\n return fused.slice(0, limit);\n}\n","/**\n * Scoring utilities for MCP tool result ranking.\n *\n * Extracted as pure functions for easy testing and reuse across\n * discover, implement, and other search-driven tools.\n */\n\nimport type { CompiledBlock } from '@fragments-sdk/context/types';\nimport type { ScoredResult } from './search.js';\n\n// ---------------------------------------------------------------------------\n// Confidence assignment — ratio-to-max (scale-independent)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimum absolute score floor. If the best result scores below this,\n * results are considered a no-match rather than low-confidence garbage.\n *\n * BM25 scores for a 60-component corpus typically range 10-100+ for real\n * matches (including name-match bonuses of +25 and status bonuses of +5).\n * A maxScore below 5 means no meaningful term overlap was found — only\n * status bonuses and/or minimal synonym noise.\n *\n * Note: this threshold is calibrated for BM25 keyword scores. When hybrid\n * search uses RRF fusion (premium API key), scores are in a different range\n * (~0.01-0.05) and the threshold should be bypassed via a maxScore > 1 guard.\n */\nexport const MINIMUM_SCORE_THRESHOLD = 5;\n\n/**\n * Assign a confidence level based on how a score compares to the best result.\n *\n * Uses ratio-to-max instead of absolute thresholds so the same function works\n * for both keyword scores (8-50+) and RRF scores (0.01-0.02).\n *\n * - high: score >= 70% of maxScore (\"this is almost certainly what you need\")\n * - medium: score >= 40% of maxScore (\"this could be useful\")\n * - low: score < 40% of maxScore (\"tangentially related\")\n */\nexport function assignConfidence(\n score: number,\n maxScore: number,\n): 'high' | 'medium' | 'low' {\n if (maxScore <= 0) return 'low';\n const ratio = score / maxScore;\n if (ratio >= 0.7) return 'high';\n if (ratio >= 0.4) return 'medium';\n return 'low';\n}\n\n/**\n * Check if the best score in a result set meets the minimum quality threshold.\n * Returns true if results are meaningful, false if they're noise.\n */\nexport function meetsMinimumThreshold(maxScore: number): boolean {\n return maxScore >= MINIMUM_SCORE_THRESHOLD;\n}\n\n// ---------------------------------------------------------------------------\n// Levenshtein distance — for fuzzy \"did you mean?\" suggestions\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the Levenshtein edit distance between two strings.\n * Used for suggesting closest component name matches on typos.\n */\nexport function levenshtein(a: string, b: string): number {\n const la = a.length;\n const lb = b.length;\n const dp: number[] = Array.from({ length: lb + 1 }, (_, i) => i);\n\n for (let i = 1; i <= la; i++) {\n let prev = i - 1;\n dp[0] = i;\n for (let j = 1; j <= lb; j++) {\n const temp = dp[j];\n dp[j] = a[i - 1] === b[j - 1]\n ? prev\n : 1 + Math.min(prev, dp[j], dp[j - 1]);\n prev = temp;\n }\n }\n\n return dp[lb];\n}\n\n/**\n * Find the closest matching name from a list, using Levenshtein distance.\n * Returns the closest match if it's within `maxDistance`, or null otherwise.\n */\nexport function findClosestMatch(\n input: string,\n candidates: string[],\n maxDistance = 3,\n): string | null {\n const inputLower = input.toLowerCase();\n let bestMatch: string | null = null;\n let bestDist = maxDistance + 1;\n\n for (const candidate of candidates) {\n const candidateLower = candidate.toLowerCase();\n const dist = levenshtein(inputLower, candidateLower);\n if (dist < bestDist) {\n bestDist = dist;\n bestMatch = candidate;\n } else if (dist === bestDist && bestMatch) {\n // Tie-break: prefer the candidate whose length is closer to input length\n const currentLenDiff = Math.abs(bestMatch.length - input.length);\n const newLenDiff = Math.abs(candidate.length - input.length);\n if (newLenDiff < currentLenDiff) {\n bestMatch = candidate;\n }\n }\n }\n\n return bestDist <= maxDistance ? bestMatch : null;\n}\n\n// ---------------------------------------------------------------------------\n// Block-first component ranking\n// ---------------------------------------------------------------------------\n\n/** Points added per block occurrence (e.g., Card in 3 blocks → +15) */\nexport const BLOCK_BOOST_PER_OCCURRENCE = 5;\n\n/**\n * Count how many blocks each component appears in.\n *\n * Returns a Map<lowercase component name, count>.\n * This is the core signal for block-first ranking: if Card appears in 5/5\n * marketing blocks, it's clearly more important than Sidebar which appears in 0.\n */\nexport function buildBlockComponentFrequency(\n blocks: CompiledBlock[],\n): Map<string, number> {\n const freq = new Map<string, number>();\n for (const block of blocks) {\n for (const comp of block.components) {\n const key = comp.toLowerCase();\n freq.set(key, (freq.get(key) ?? 0) + 1);\n }\n }\n return freq;\n}\n\n/**\n * Boost component search results by how frequently they appear in matching blocks.\n *\n * Mutates scores in-place and re-sorts. Components that appear in more blocks\n * get a proportionally higher boost (freq * BLOCK_BOOST_PER_OCCURRENCE).\n *\n * Returns the mutated+sorted array for convenience.\n */\nexport function boostByBlockFrequency(\n results: ScoredResult[],\n freq: Map<string, number>,\n): ScoredResult[] {\n for (const result of results) {\n const count = freq.get(result.name.toLowerCase()) ?? 0;\n if (count > 0) {\n result.score += count * BLOCK_BOOST_PER_OCCURRENCE;\n }\n }\n results.sort((a, b) => b.score - a.score);\n results.forEach((r, i) => { r.rank = i; });\n return results;\n}\n","/**\n * HTTP-based render/fix service — no Playwright dependency.\n *\n * When a viewer URL is configured (e.g., the Fragments dev server is running),\n * these functions proxy render/fix requests to the viewer's HTTP API.\n * When no viewer is available, they return helpful error messages.\n */\n\nexport interface RenderRequest {\n component: string;\n props?: Record<string, unknown>;\n variant?: string;\n viewport?: { width?: number; height?: number };\n}\n\nexport interface RenderResult {\n screenshot?: string;\n error?: string;\n}\n\nexport interface CompareRequest {\n component: string;\n variant?: string;\n props?: Record<string, unknown>;\n figmaUrl: string;\n threshold?: number;\n}\n\nexport interface CompareResult {\n match?: boolean;\n diffPercentage?: number;\n threshold?: number;\n rendered?: string;\n figma?: string;\n diff?: string;\n figmaUrl?: string;\n changedRegions?: Array<{ x: number; y: number; width: number; height: number }>;\n error?: string;\n suggestion?: string;\n}\n\nexport interface FixRequest {\n component: string;\n variant?: string;\n fixType?: 'token' | 'all';\n}\n\nexport interface FixResult {\n patches: Array<{ file: string; diff: string }>;\n summary: string;\n error?: string;\n}\n\nexport interface A11yRequest {\n component: string;\n variant?: string;\n standard?: 'AA' | 'AAA';\n includeFixPatches?: boolean;\n}\n\nexport interface A11yVariantResult {\n variant: string;\n violations: number;\n passes: number;\n incomplete: number;\n summary: {\n total: number;\n critical: number;\n serious: number;\n moderate: number;\n minor: number;\n };\n violationDetails?: Array<{\n id: string;\n impact: string;\n description: string;\n helpUrl: string;\n nodes: number;\n }>;\n}\n\nexport interface A11yResult {\n component: string;\n results: A11yVariantResult[];\n score: number;\n aaPercent: number;\n aaaPercent: number;\n passed: boolean;\n /** True when axe found no testable elements (e.g., nonexistent variant) */\n emptyAudit?: boolean;\n standard: string;\n error?: string;\n}\n\n/**\n * Render a component via the viewer's HTTP API.\n */\nexport async function renderComponent(\n viewerUrl: string,\n request: RenderRequest\n): Promise<RenderResult> {\n const renderUrl = `${viewerUrl}/fragments/render`;\n\n const response = await fetch(renderUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: request.component,\n props: request.props ?? {},\n variant: request.variant,\n viewport: request.viewport ?? { width: 800, height: 600 },\n }),\n });\n\n return (await response.json()) as RenderResult;\n}\n\n/**\n * Compare a component render against a Figma design via the viewer's HTTP API.\n */\nexport async function compareComponent(\n viewerUrl: string,\n request: CompareRequest\n): Promise<CompareResult> {\n const compareUrl = `${viewerUrl}/fragments/compare`;\n\n const response = await fetch(compareUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n return (await response.json()) as CompareResult;\n}\n\n/**\n * Generate fix patches via the viewer's HTTP API.\n */\nexport async function fixComponent(\n viewerUrl: string,\n request: FixRequest\n): Promise<FixResult> {\n const fixUrl = `${viewerUrl}/fragments/fix`;\n\n const response = await fetch(fixUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n return (await response.json()) as FixResult;\n}\n\n/**\n * Run an accessibility audit on a component via the viewer's HTTP API.\n */\nexport async function auditComponent(\n viewerUrl: string,\n request: A11yRequest\n): Promise<A11yResult> {\n const a11yUrl = `${viewerUrl}/fragments/a11y`;\n\n const response = await fetch(a11yUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: request.component,\n variant: request.variant,\n standard: request.standard,\n includeFixPatches: request.includeFixPatches,\n }),\n });\n\n const raw = (await response.json()) as {\n results: A11yVariantResult[];\n error?: string;\n };\n\n if (raw.error) {\n return {\n component: request.component,\n results: [],\n score: 0,\n aaPercent: 0,\n aaaPercent: 0,\n passed: false,\n standard: request.standard ?? 'AA',\n error: raw.error,\n };\n }\n\n const results = raw.results ?? [];\n const standard = request.standard ?? 'AA';\n\n // Calculate totals\n let totalCritical = 0;\n let totalSerious = 0;\n let totalModerate = 0;\n let totalMinor = 0;\n\n for (const r of results) {\n totalCritical += r.summary.critical;\n totalSerious += r.summary.serious;\n totalModerate += r.summary.moderate;\n totalMinor += r.summary.minor;\n }\n\n // Score: start at 100, subtract per violation\n const deductions =\n totalCritical * 10 +\n totalSerious * 5 +\n totalModerate * 2 +\n totalMinor * 1;\n const score = Math.max(0, 100 - deductions);\n\n // Per-variant compliance: calculate the percentage of variants that pass,\n // not a binary gate. A component with 5 clean variants and 1 with a violation\n // should show ~83% AA compliance, not 0%.\n const variantCount = results.length;\n const aaPassCount = results.filter(r => {\n const critical = r.summary.critical;\n const serious = r.summary.serious;\n return critical === 0 && serious === 0;\n }).length;\n const aaaPassCount = results.filter(r => {\n const total = r.summary.critical + r.summary.serious + r.summary.moderate + r.summary.minor;\n return total === 0;\n }).length;\n // Detect empty audits: if every variant has 0 passes AND 0 violations,\n // axe found no testable elements (e.g., nonexistent variant rendered empty).\n // Report this as an inconclusive result rather than a false pass.\n const totalPasses = results.reduce((sum, r) => sum + r.passes, 0);\n const totalViolations = totalCritical + totalSerious + totalModerate + totalMinor;\n const emptyAudit = results.length > 0 && totalPasses === 0 && totalViolations === 0;\n\n const aaPercent = variantCount > 0 ? Math.round((aaPassCount / variantCount) * 100) : 100;\n const aaaPercent = variantCount > 0 ? Math.round((aaaPassCount / variantCount) * 100) : 100;\n\n // Overall pass/fail uses aggregate totals (matches original behavior for the `passed` field)\n // An empty audit (nothing tested) is NOT a pass\n const aaPass = !emptyAudit && totalCritical === 0 && totalSerious === 0;\n const aaaPass = !emptyAudit && totalViolations === 0;\n\n const passed = standard === 'AAA' ? aaaPass : aaPass;\n\n return {\n component: request.component,\n results,\n score: emptyAudit ? 0 : score,\n aaPercent: emptyAudit ? 0 : aaPercent,\n aaaPercent: emptyAudit ? 0 : aaaPercent,\n ...(emptyAudit && { emptyAudit }),\n passed,\n standard,\n };\n}\n","/**\n * Utility functions for the MCP server.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\n\n/**\n * Extract specific fields from an object using dot notation paths.\n * E.g., projectFields(obj, ['meta.name', 'usage.when']) returns { meta: { name: ... }, usage: { when: ... } }\n *\n * @param obj - The source object to extract fields from\n * @param fields - Array of field paths (supports dot notation for nested fields)\n * @returns A new object containing only the requested fields\n */\nexport function projectFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[]\n): Partial<T> {\n if (!fields || fields.length === 0) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n const parts = field.split('.');\n let source: unknown = obj;\n let target = result;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isLast = i === parts.length - 1;\n\n if (source === null || source === undefined || typeof source !== 'object') {\n break;\n }\n\n const sourceObj = source as Record<string, unknown>;\n const value = sourceObj[part];\n\n if (isLast) {\n // Set the final value\n target[part] = value;\n } else {\n // Create nested object if needed\n if (!(part in target)) {\n target[part] = {};\n }\n target = target[part] as Record<string, unknown>;\n source = value;\n }\n }\n }\n\n return result as Partial<T>;\n}\n","/**\n * MCP tool handler for the fragments_graph tool.\n *\n * Dispatches graph queries to the ComponentGraphEngine and formats\n * results as structured markdown/JSON for AI consumption.\n */\n\nimport {\n ComponentGraphEngine,\n deserializeGraph,\n} from '@fragments-sdk/context/graph';\nimport type {\n SerializedComponentGraph,\n GraphEdgeType,\n ComponentGraph,\n} from '@fragments-sdk/context/graph';\nimport type { CompiledBlock } from '@fragments-sdk/context/types';\nimport { findClosestMatch } from './scoring.js';\n\nexport interface GraphToolArgs {\n mode: string;\n component?: string;\n target?: string;\n edgeTypes?: string[];\n maxDepth?: number;\n}\n\nexport function handleGraphTool(\n args: GraphToolArgs,\n serializedGraph: SerializedComponentGraph | undefined,\n blocks?: Record<string, CompiledBlock>,\n componentNames?: string[],\n): { text: string; isError?: boolean } {\n if (!serializedGraph) {\n return {\n text: JSON.stringify({\n error: 'No graph data available. Run `fragments build` to generate the component graph.',\n hint: 'The graph is built automatically during `fragments build` and embedded in fragments.json.',\n }),\n isError: true,\n };\n }\n\n const graph = deserializeGraph(serializedGraph);\n const blockData = blocks\n ? Object.fromEntries(\n Object.entries(blocks).map(([k, v]) => [k, { components: v.components }])\n )\n : undefined;\n const engine = new ComponentGraphEngine(graph, blockData);\n const edgeTypes = args.edgeTypes as GraphEdgeType[] | undefined;\n\n switch (args.mode) {\n case 'health': {\n const health = engine.getHealth();\n const blockCount = blocks ? Object.keys(blocks).length : 0;\n return {\n text: JSON.stringify({\n mode: 'health',\n ...health,\n ...(health.compositionCoverage === 0 && blockCount === 0 && {\n compositionNote: 'No composition blocks defined yet — compositionCoverage will increase as blocks are added',\n }),\n summary: `${health.nodeCount} components, ${health.edgeCount} edges, ${health.connectedComponents.length} island(s), ${health.orphans.length} orphan(s), ${health.compositionCoverage}% in blocks`,\n }),\n };\n }\n\n case 'dependencies': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for dependencies mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const deps = engine.dependencies(args.component, edgeTypes);\n return {\n text: JSON.stringify({\n mode: 'dependencies',\n component: args.component,\n count: deps.length,\n dependencies: deps.map(e => ({\n component: e.target,\n type: e.type,\n weight: e.weight,\n note: e.note,\n provenance: e.provenance,\n })),\n }),\n };\n }\n\n case 'dependents': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for dependents mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const deps = engine.dependents(args.component, edgeTypes);\n return {\n text: JSON.stringify({\n mode: 'dependents',\n component: args.component,\n count: deps.length,\n dependents: deps.map(e => ({\n component: e.source,\n type: e.type,\n weight: e.weight,\n note: e.note,\n provenance: e.provenance,\n })),\n }),\n };\n }\n\n case 'impact': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for impact mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const result = engine.impact(args.component, args.maxDepth ?? 3);\n return {\n text: JSON.stringify({\n mode: 'impact',\n ...result,\n summary: `Changing ${args.component} affects ${result.totalAffected} component(s) and ${result.affectedBlocks.length} block(s)`,\n }),\n };\n }\n\n case 'path': {\n if (!args.component || !args.target) {\n return { text: JSON.stringify({ error: 'component and target are required for path mode' }), isError: true };\n }\n const result = engine.path(args.component, args.target);\n return {\n text: JSON.stringify({\n mode: 'path',\n from: args.component,\n to: args.target,\n ...result,\n edges: result.edges.map(e => ({\n source: e.source,\n target: e.target,\n type: e.type,\n })),\n }),\n };\n }\n\n case 'composition': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for composition mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const tree = engine.composition(args.component);\n return {\n text: JSON.stringify({\n mode: 'composition',\n ...tree,\n }),\n };\n }\n\n case 'alternatives': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for alternatives mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const alts = engine.alternatives(args.component);\n return {\n text: JSON.stringify({\n mode: 'alternatives',\n component: args.component,\n count: alts.length,\n alternatives: alts,\n }),\n };\n }\n\n case 'islands': {\n const islands = engine.islands();\n return {\n text: JSON.stringify({\n mode: 'islands',\n count: islands.length,\n islands: islands.map((island, i) => ({\n id: i + 1,\n size: island.length,\n components: island,\n })),\n }),\n };\n }\n\n default:\n return {\n text: JSON.stringify({\n error: `Unknown mode: \"${args.mode}\". Valid modes: dependencies, dependents, impact, path, composition, alternatives, islands, health`,\n }),\n isError: true,\n };\n }\n}\n","import type {\n CompiledBlock,\n CompiledFragment,\n CompiledFragmentsFile,\n CompiledTokenData,\n} from '@fragments-sdk/context/types';\n\nimport type { LocalSearchData } from './search.js';\nimport type { BlockIndex, ComponentIndex, TokenIndex } from './orama-index.js';\n\ninterface SearchIndexes {\n componentIndex: ComponentIndex | null;\n blockIndex: BlockIndex | null;\n tokenIndex: TokenIndex | null;\n}\n\ninterface BuildSearchDataResult {\n allFragments: CompiledFragment[];\n allBlocks: CompiledBlock[];\n localData: LocalSearchData;\n}\n\nexport function normalizeFilter(value: string | undefined): string | undefined {\n const normalized = value?.trim().toLowerCase();\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\nexport function categoryMatches(\n category: string | undefined,\n categoryFilter: string | undefined\n): boolean {\n if (!categoryFilter) return true;\n return normalizeFilter(category) === categoryFilter;\n}\n\nexport function buildLocalSearchData(\n data: Pick<CompiledFragmentsFile, 'fragments' | 'blocks' | 'recipes' | 'tokens' | 'graph'>,\n indexes: SearchIndexes\n): BuildSearchDataResult {\n const allFragments = Object.values(data.fragments);\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n const localData: LocalSearchData = {\n fragments: allFragments,\n blocks: allBlocks,\n tokenData: data.tokens as CompiledTokenData | undefined,\n graph: data.graph,\n componentIndex: indexes.componentIndex ?? undefined,\n blockIndex: indexes.blockIndex ?? undefined,\n tokenIndex: indexes.tokenIndex ?? undefined,\n };\n\n return { allFragments, allBlocks, localData };\n}\n\nexport async function buildImportStatements(\n components: string[],\n resolvePackageName: (component: string) => Promise<string>\n): Promise<string[]> {\n const grouped = new Map<string, string[]>();\n\n for (const component of components) {\n if (!component) continue;\n\n const packageName = await resolvePackageName(component);\n const existing = grouped.get(packageName);\n\n if (!existing) {\n grouped.set(packageName, [component]);\n continue;\n }\n\n if (!existing.includes(component)) {\n existing.push(component);\n }\n }\n\n return Array.from(grouped.entries()).map(\n ([packageName, componentNames]) =>\n `import { ${componentNames.join(', ')} } from '${packageName}';`\n );\n}\n\nexport function limitTokensPerCategory<T>(\n categories: Record<string, T[]>,\n limit: number | undefined\n): { categories: Record<string, T[]>; total: number } {\n if (limit === undefined) {\n return {\n categories,\n total: Object.values(categories).reduce((sum, tokens) => sum + tokens.length, 0),\n };\n }\n\n const limited: Record<string, T[]> = {};\n let total = 0;\n\n for (const [category, tokens] of Object.entries(categories)) {\n const sliced = tokens.slice(0, limit);\n if (sliced.length === 0) continue;\n limited[category] = sliced;\n total += sliced.length;\n }\n\n return { categories: limited, total };\n}\n","import { readFileSync } from 'node:fs';\n\ninterface PackageJson {\n version?: string;\n}\n\nfunction readPackageVersion(): string {\n try {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf-8');\n const pkg = JSON.parse(raw) as PackageJson;\n return pkg.version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nexport const MCP_SERVER_VERSION = readPackageVersion();\n"],"mappings":"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","names":["existsSync","readFileSync","join","ComponentGraphEngine","deserializeGraph","readFileSync","join","existsSync","readFileSync","search","fragments"]}
package/dist/server.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  createMcpServer,
3
3
  createSandboxServer,
4
4
  startMcpServer
5
- } from "./chunk-XMNCAB2A.js";
5
+ } from "./chunk-ZOMUPGBG.js";
6
6
  export {
7
7
  createMcpServer,
8
8
  createSandboxServer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/mcp",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
4
4
  "license": "FSL-1.1-MIT",
5
5
  "description": "Standalone MCP server for Fragments design system — zero-config component discovery with semantic search",
6
6
  "mcpName": "io.github.ConanMcN/fragments-mcp",
@@ -45,7 +45,7 @@
45
45
  "@scarf/scarf": "^1.4.0",
46
46
  "@modelcontextprotocol/sdk": "^1.0.0",
47
47
  "@orama/orama": "^3.1.18",
48
- "@fragments-sdk/context": "0.4.1"
48
+ "@fragments-sdk/context": "0.4.3"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^22.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server.ts","../src/constants.ts","../src/discovery.ts","../src/orama-index.ts","../src/search.ts","../src/scoring.ts","../src/service.ts","../src/utils.ts","../src/graph-handler.ts","../src/server-helpers.ts","../src/version.ts"],"sourcesContent":["/**\n * Standalone MCP server for Fragments design system.\n *\n * This is a lightweight extraction of the MCP server from @fragments-sdk/cli\n * that can run independently without Playwright or build tools. It provides:\n * - 9 tools: discover, inspect, blocks, tokens, implement, render, fix, graph, a11y\n * - Hybrid search: Convex-backed vector search + local keyword scoring + RRF\n * - HTTP-only render/fix/a11y (requires a running dev server)\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { BRAND, DEFAULTS } from './constants.js';\nimport { generateContext, filterPlaceholders } from '@fragments-sdk/context/generate';\nimport type { CompiledFragmentsFile, CompiledFragment, Theme } from '@fragments-sdk/context/types';\nimport { buildMcpTools, buildToolNames } from '@fragments-sdk/context/mcp-tools';\nimport { findFragmentsJson } from './discovery.js';\nimport { hybridSearch, keywordScoreBlocks } from './search.js';\nimport { assignConfidence, buildBlockComponentFrequency, boostByBlockFrequency, findClosestMatch, meetsMinimumThreshold } from './scoring.js';\nimport { buildComponentIndex, buildBlockIndex, buildTokenIndex, extractTokenCategories, searchBlocks } from './orama-index.js';\nimport type { ComponentIndex, BlockIndex, TokenIndex } from './orama-index.js';\nimport { renderComponent, compareComponent, fixComponent, auditComponent } from './service.js';\nimport { projectFields } from './utils.js';\nimport { handleGraphTool } from './graph-handler.js';\nimport type { GraphToolArgs } from './graph-handler.js';\nimport {\n buildImportStatements,\n buildLocalSearchData,\n categoryMatches,\n limitTokensPerCategory,\n normalizeFilter,\n} from './server-helpers.js';\nimport { MCP_SERVER_VERSION } from './version.js';\n\n// ---------------------------------------------------------------------------\n// Tool names & definitions (from shared source of truth)\n// ---------------------------------------------------------------------------\n\nconst TOOL_NAMES = buildToolNames(BRAND.nameLower) as Record<string, string> & {\n discover: string;\n inspect: string;\n blocks: string;\n tokens: string;\n implement: string;\n render: string;\n fix: string;\n graph: string;\n a11y: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared error messages\n// ---------------------------------------------------------------------------\n\nconst NO_VIEWER_MSG = 'This tool requires a running dev server. Add --viewer-url http://localhost:PORT to this server\\'s config args. Start the viewer with \\'fragments dev\\' in your component library directory.';\n\n// ---------------------------------------------------------------------------\n// Server configuration\n// ---------------------------------------------------------------------------\n\nexport interface McpServerConfig {\n /** Project root directory */\n projectRoot: string;\n /** Viewer base URL (for render/fix tools) */\n viewerUrl?: string;\n /** Default theme for verification */\n theme?: Theme;\n /** Diff threshold percentage */\n threshold?: number;\n /** Premium API key — enables semantic vector search when provided */\n apiKey?: string;\n}\n\nconst TOOLS = buildMcpTools(BRAND.nameLower) as Tool[];\n\n// ---------------------------------------------------------------------------\n// Server implementation\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(config: McpServerConfig): Server {\n const server = new Server(\n {\n name: `${BRAND.nameLower}-mcp`,\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Lazy-loaded resources\n let fragmentsData: CompiledFragmentsFile | null = null;\n const fragmentPackageMap = new Map<string, string>();\n let defaultPackageName: string | null = null;\n let resolvedRoot: string | null = null;\n\n // Orama BM25 indexes — built once after loadFragments(), reused across searches\n let componentIndex: ComponentIndex | null = null;\n let blockIndex: BlockIndex | null = null;\n let tokenIndex: TokenIndex | null = null;\n\n /**\n * Resolve the project root directory.\n *\n * Layer 1: Try MCP roots/list (VS Code, Claude Code, and any client\n * that implements the MCP roots capability).\n * Layer 2: Fall back to the configured projectRoot (defaults to cwd).\n */\n async function resolveProjectRoot(): Promise<string> {\n if (resolvedRoot) return resolvedRoot;\n\n // Layer 1: Try MCP roots/list\n try {\n const result = await server.listRoots();\n if (result.roots?.length > 0) {\n const rootUri = result.roots[0].uri;\n // Convert file:///path/to/workspace -> /path/to/workspace\n resolvedRoot = fileURLToPath(rootUri);\n return resolvedRoot;\n }\n } catch {\n // Client doesn't support roots/list (e.g. Cursor) — fall through\n }\n\n // Layer 2: Fall back to configured projectRoot (cwd)\n resolvedRoot = config.projectRoot;\n return resolvedRoot;\n }\n\n async function loadFragments(): Promise<CompiledFragmentsFile> {\n if (fragmentsData) return fragmentsData;\n\n const projectRoot = await resolveProjectRoot();\n const paths = findFragmentsJson(projectRoot);\n\n if (paths.length === 0) {\n throw new Error(\n `No ${BRAND.outFile} found. Searched ${projectRoot} and package.json dependencies.\\n\\n` +\n `Fix: Add a project-level MCP config so the server runs from your workspace root:\\n\\n` +\n ` Cursor: .cursor/mcp.json\\n` +\n ` VS Code: .vscode/mcp.json\\n` +\n ` Claude: claude mcp add ${BRAND.nameLower} -- npx @fragments-sdk/mcp\\n` +\n ` Windsurf: .windsurf/mcp.json\\n\\n` +\n `Or pass --project-root: npx @fragments-sdk/mcp -p /path/to/project\\n\\n` +\n `If you're a library author, run \\`${BRAND.cliCommand} build\\` first.`\n );\n }\n\n const content = await readFile(paths[0], 'utf-8');\n fragmentsData = JSON.parse(content) as CompiledFragmentsFile;\n\n // Normalize legacy \"recipes\" key to \"blocks\"\n if (!fragmentsData.blocks && fragmentsData.recipes) {\n fragmentsData.blocks = fragmentsData.recipes;\n }\n\n if (fragmentsData.packageName) {\n for (const name of Object.keys(fragmentsData.fragments)) {\n fragmentPackageMap.set(name, fragmentsData.packageName);\n }\n }\n\n for (let i = 1; i < paths.length; i++) {\n const extra = JSON.parse(await readFile(paths[i], 'utf-8')) as CompiledFragmentsFile;\n if (extra.packageName) {\n for (const name of Object.keys(extra.fragments)) {\n fragmentPackageMap.set(name, extra.packageName);\n }\n }\n Object.assign(fragmentsData.fragments, extra.fragments);\n const extraBlocks = extra.blocks ?? extra.recipes;\n if (extraBlocks) {\n fragmentsData.blocks = { ...fragmentsData.blocks, ...extraBlocks };\n }\n }\n\n // Build Orama BM25 indexes for fast search\n const allFragments = Object.values(fragmentsData.fragments);\n const allBlocks = Object.values(fragmentsData.blocks ?? fragmentsData.recipes ?? {});\n componentIndex = buildComponentIndex(allFragments);\n if (allBlocks.length > 0) {\n blockIndex = buildBlockIndex(allBlocks);\n }\n if (fragmentsData.tokens && fragmentsData.tokens.total > 0) {\n tokenIndex = buildTokenIndex(fragmentsData.tokens);\n }\n\n return fragmentsData;\n }\n\n async function getPackageName(fragmentName?: string): Promise<string> {\n await loadFragments();\n\n if (fragmentName) {\n const segPkg = fragmentPackageMap.get(fragmentName);\n if (segPkg) return segPkg;\n }\n\n if (defaultPackageName) return defaultPackageName;\n\n if (fragmentsData?.packageName) {\n defaultPackageName = fragmentsData.packageName;\n return defaultPackageName;\n }\n\n const root = resolvedRoot ?? config.projectRoot;\n const packageJsonPath = join(root, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content) as { name?: string };\n if (pkg.name) {\n defaultPackageName = pkg.name;\n return defaultPackageName;\n }\n } catch {\n // Fall through\n }\n }\n\n defaultPackageName = 'your-component-library';\n return defaultPackageName;\n }\n\n // Tools that require a running dev server (viewer URL)\n const VIEWER_TOOL_KEYS = new Set(['render', 'fix', 'a11y']);\n\n // Register tool listing — omit viewer-dependent tools when no viewer URL is configured\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n if (config.viewerUrl) {\n return { tools: TOOLS };\n }\n // Filter out tools that require a viewer URL\n const availableTools = TOOLS.filter(\n (t) => !VIEWER_TOOL_KEYS.has(t.name.replace(`${BRAND.nameLower}_`, ''))\n );\n return { tools: availableTools };\n });\n\n // Register tool execution\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n // ================================================================\n // DISCOVER — list, suggest, context, alternatives\n // ================================================================\n case TOOL_NAMES.discover: {\n const data = await loadFragments();\n const useCase = (args?.useCase as string) ?? undefined;\n const componentForAlts = (args?.component as string) ?? undefined;\n const category = normalizeFilter(args?.category as string | undefined);\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const status = (args?.status as string) ?? undefined;\n const format = (args?.format as 'markdown' | 'json') ?? 'markdown';\n const compact = (args?.compact as boolean) ?? false;\n const includeCode = (args?.includeCode as boolean) ?? false;\n const includeRelations = (args?.includeRelations as boolean) ?? false;\n const limit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 25) : 10;\n const verbosity = (args?.verbosity as string) ?? 'standard';\n\n // --- Context mode (compact or format-only) ---\n if (compact || (args?.format && !useCase && !componentForAlts)) {\n let fragments = Object.values(data.fragments);\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n // Apply filters even in compact/context mode\n if (category) {\n fragments = fragments.filter(f => categoryMatches(f.meta.category, category));\n }\n if (search) {\n fragments = fragments.filter(f =>\n f.meta.name.toLowerCase().includes(search) ||\n f.meta.description?.toLowerCase().includes(search) ||\n f.meta.tags?.some(t => t.toLowerCase().includes(search))\n );\n }\n if (status) {\n fragments = fragments.filter(f => f.meta.status === status);\n }\n\n const { content: ctxContent, tokenEstimate } = generateContext(fragments, {\n format,\n compact,\n include: {\n code: includeCode,\n relations: includeRelations,\n },\n }, allBlocks);\n\n return {\n content: [{ type: 'text' as const, text: ctxContent }],\n _meta: { tokenEstimate },\n };\n }\n\n // --- Suggest mode: useCase provided (uses hybrid search) ---\n if (useCase) {\n const { allFragments, allBlocks, localData } = buildLocalSearchData(\n data,\n {\n componentIndex,\n blockIndex,\n tokenIndex,\n }\n );\n const context = ((args as Record<string, unknown>)?.context as string)?.toLowerCase() ?? '';\n const fullQuery = context ? `${useCase} ${context}` : useCase;\n\n // Use hybrid search — filter to components only for discover suggest\n const searchResults = await hybridSearch(fullQuery, localData, limit, 'component', config.apiKey);\n\n // Block-first ranking: boost components by frequency in matching blocks\n const blockMatches = keywordScoreBlocks(fullQuery, allBlocks, blockIndex ?? undefined).slice(0, 5);\n if (blockMatches.length > 0) {\n const matchedBlocks = blockMatches\n .map(bm => allBlocks.find(b => b.name.toLowerCase() === bm.name.toLowerCase()))\n .filter(Boolean) as typeof allBlocks;\n const blockFreq = buildBlockComponentFrequency(matchedBlocks);\n boostByBlockFrequency(searchResults, blockFreq);\n }\n\n const maxScore = searchResults.length > 0 ? searchResults[0].score : 0;\n\n // Build detailed suggestions from search results\n const scored = searchResults.map((result) => {\n const fragment = allFragments.find(\n (s) => s.meta.name.toLowerCase() === result.name.toLowerCase()\n );\n if (!fragment) return null;\n\n const filteredWhen = filterPlaceholders(fragment.usage?.when).slice(0, 3);\n const filteredWhenNot = filterPlaceholders(fragment.usage?.whenNot).slice(0, 2);\n\n return {\n component: fragment.meta.name,\n category: fragment.meta.category,\n description: fragment.meta.description,\n confidence: assignConfidence(result.score, maxScore),\n reasons: [`Matched via hybrid search (score: ${result.score.toFixed(4)})`],\n usage: { when: filteredWhen, whenNot: filteredWhenNot },\n variantCount: fragment.variants.length,\n status: fragment.meta.status,\n };\n }).filter(Boolean);\n\n // Diversify by category (max 2 per category)\n const suggestions: typeof scored = [];\n const categoryCount: Record<string, number> = {};\n for (const item of scored) {\n if (!item) continue;\n const cat = item.category || 'uncategorized';\n const count = categoryCount[cat] || 0;\n if (count < 2 || suggestions.length < 3) {\n suggestions.push(item);\n categoryCount[cat] = count + 1;\n if (suggestions.length >= limit) break;\n }\n }\n\n const compositionHint = suggestions.length >= 2\n ? `These components work well together. For example, ${suggestions[0]!.component} can be combined with ${suggestions.slice(1, 3).map(s => s!.component).join(' and ')}.`\n : undefined;\n\n const useCaseLower = useCase.toLowerCase();\n const STYLE_KEYWORDS = ['color', 'spacing', 'padding', 'margin', 'font', 'border', 'radius', 'shadow', 'variable', 'token', 'css', 'theme', 'dark mode', 'background', 'hover'];\n const isStyleQuery = STYLE_KEYWORDS.some((kw) => useCaseLower.includes(kw));\n\n const noMatch = suggestions.length === 0;\n // Absolute quality gate: if the best BM25 score is below the minimum\n // threshold, treat results as weak regardless of relative confidence.\n // Guard with maxScore > 1 to skip this check for RRF-scored results\n // (which use a different score range of ~0.01-0.05).\n const belowThreshold = !noMatch && maxScore > 1 && !meetsMinimumThreshold(maxScore);\n const weakMatch = !noMatch && (belowThreshold || suggestions.every((s) => s!.confidence === 'low'));\n\n let recommendation: string;\n let nextStep: string | undefined;\n if (noMatch) {\n recommendation = isStyleQuery\n ? `No matching components found. Your query seems styling-related — try ${TOOL_NAMES.tokens} to find CSS custom properties.`\n : 'No matching components found. Try different keywords or browse all components with fragments_discover.';\n nextStep = isStyleQuery\n ? `Use ${TOOL_NAMES.tokens}(search: \"${useCaseLower.split(/\\s+/)[0]}\") to find design tokens.`\n : undefined;\n } else if (weakMatch) {\n recommendation = `Weak matches only — ${suggestions[0]!.component} might work but confidence is low.${isStyleQuery ? ` If you need a CSS variable, try ${TOOL_NAMES.tokens}.` : ''}`;\n nextStep = `Use ${TOOL_NAMES.inspect}(\"${suggestions[0]!.component}\") to check if it fits, or try broader search terms.`;\n } else {\n recommendation = `Best match: ${suggestions[0]!.component} (${suggestions[0]!.confidence} confidence) - ${suggestions[0]!.description}`;\n nextStep = `Use ${TOOL_NAMES.inspect}(\"${suggestions[0]!.component}\") for full details.`;\n }\n\n // Always hint toward tokens tool when query uses styling keywords,\n // even when component matches exist — the user may want CSS variables\n const tokenHint = isStyleQuery && !noMatch\n ? `Your query includes styling terms. For CSS custom properties, also try ${TOOL_NAMES.tokens}(search: \"${useCaseLower.split(/\\s+/)[0]}\").`\n : undefined;\n\n // Surface matching blocks in the response — helps with abstract queries\n // like \"landing page hero section\" where blocks provide better answers\n const blockNames = blockMatches\n .map(bm => allBlocks.find(b => b.name.toLowerCase() === bm.name.toLowerCase()))\n .filter(Boolean)\n .slice(0, 3)\n .map(b => b!.name);\n const blockHint = blockNames.length > 0\n ? `Related blocks: ${blockNames.join(', ')}. Use ${TOOL_NAMES.blocks}(search: \"${useCase}\") for ready-to-use patterns.`\n : undefined;\n\n // Apply verbosity level\n const suggestResponse = verbosity === 'compact'\n ? {\n useCase,\n suggestions: suggestions.map(s => ({\n component: s!.component,\n description: s!.description,\n confidence: s!.confidence,\n })),\n recommendation,\n }\n : {\n useCase,\n context: context || undefined,\n suggestions,\n noMatch,\n weakMatch,\n recommendation,\n compositionHint,\n ...(tokenHint && { tokenHint }),\n ...(blockHint && { blockHint }),\n nextStep,\n };\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(suggestResponse),\n }],\n };\n }\n\n // --- Alternatives mode ---\n if (componentForAlts) {\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentForAlts.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentForAlts, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentForAlts}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const relations = fragment.relations ?? [];\n\n const referencedBy = Object.values(data.fragments)\n .filter((s) =>\n s.relations?.some((r) => r.component.toLowerCase() === componentForAlts.toLowerCase())\n )\n .map((s) => ({\n component: s.meta.name,\n relationship: s.relations?.find(\n (r) => r.component.toLowerCase() === componentForAlts.toLowerCase()\n )?.relationship,\n note: s.relations?.find(\n (r) => r.component.toLowerCase() === componentForAlts.toLowerCase()\n )?.note,\n }));\n\n const sameCategory = Object.values(data.fragments)\n .filter(\n (s) =>\n s.meta.category === fragment.meta.category &&\n s.meta.name.toLowerCase() !== componentForAlts.toLowerCase()\n )\n .map((s) => ({\n component: s.meta.name,\n description: s.meta.description,\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: fragment.meta.name,\n category: fragment.meta.category,\n directRelations: relations,\n referencedBy,\n sameCategory,\n suggestion: relations.find((r) => r.relationship === 'alternative')\n ? `Consider ${relations.find((r) => r.relationship === 'alternative')?.component}: ${relations.find((r) => r.relationship === 'alternative')?.note}`\n : undefined,\n }),\n }],\n };\n }\n\n // --- Default: list mode ---\n const fragments = Object.values(data.fragments)\n .filter((s) => {\n if (category && !categoryMatches(s.meta.category, category)) return false;\n if (status && (s.meta.status ?? 'stable') !== status) return false;\n if (search) {\n const nameMatch = s.meta.name.toLowerCase().includes(search);\n const descMatch = s.meta.description?.toLowerCase().includes(search);\n const tagMatch = s.meta.tags?.some((t) => t.toLowerCase().includes(search));\n if (!nameMatch && !descMatch && !tagMatch) return false;\n }\n return true;\n })\n .map((s) => {\n if (verbosity === 'compact') {\n return { name: s.meta.name, category: s.meta.category };\n }\n return {\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n status: s.meta.status ?? 'stable',\n variantCount: s.variants.length,\n tags: s.meta.tags ?? [],\n ...((includeCode || verbosity === 'full') && s.variants[0]?.code && {\n example: s.variants[0].code,\n }),\n };\n });\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: fragments.length,\n fragments,\n categories: [...new Set(fragments.map((s) => s.category))],\n hint: fragments.length === 0\n ? 'No components found. Try broader search terms or check available categories.'\n : fragments.length > 5\n ? 'Use fragments_discover with useCase for recommendations, or fragments_inspect for details on a specific component.'\n : undefined,\n }),\n }],\n };\n }\n\n // ================================================================\n // INSPECT\n // ================================================================\n case TOOL_NAMES.inspect: {\n const data = await loadFragments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n const variantName = (args?.variant as string) ?? undefined;\n const maxExamples = args?.maxExamples as number | undefined;\n const maxLines = args?.maxLines as number | undefined;\n const verbosity = (args?.verbosity as string) ?? 'standard';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"? Use ${TOOL_NAMES.inspect}(\"${closest}\") to inspect it.` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const pkgName = await getPackageName(fragment.meta.name);\n\n let variants = fragment.variants;\n if (variantName) {\n const query = variantName.toLowerCase();\n let filtered = variants.filter((v) => v.name.toLowerCase() === query);\n if (filtered.length === 0) {\n filtered = variants.filter((v) => v.name.toLowerCase().startsWith(query));\n }\n if (filtered.length === 0) {\n filtered = variants.filter((v) => v.name.toLowerCase().includes(query));\n }\n if (filtered.length > 0) {\n variants = filtered;\n } else {\n throw new Error(\n `Variant \"${variantName}\" not found for ${componentName}. ` +\n `Available: ${fragment.variants.map((v) => v.name).join(', ')}`\n );\n }\n }\n if (maxExamples && maxExamples > 0) {\n variants = variants.slice(0, maxExamples);\n }\n\n const truncateCode = (code: string): string => {\n if (!maxLines || maxLines <= 0) return code;\n const lines = code.split('\\n');\n if (lines.length <= maxLines) return code;\n return lines.slice(0, maxLines).join('\\n') + '\\n// ... truncated';\n };\n\n const examples = variants.map((variant) => {\n if (variant.code) {\n return {\n variant: variant.name,\n description: variant.description,\n code: truncateCode(variant.code),\n };\n }\n return {\n variant: variant.name,\n description: variant.description,\n code: `<${fragment.meta.name} />`,\n note: 'No code example provided in fragment. Refer to props for customization.',\n };\n });\n\n const propsReference = Object.entries(fragment.props ?? {}).map(([propName, prop]) => ({\n name: propName,\n type: prop.type,\n required: prop.required,\n default: prop.default,\n description: prop.description,\n }));\n\n const propConstraints = Object.entries(fragment.props ?? {})\n .filter(([, prop]) => prop.constraints && prop.constraints.length > 0)\n .map(([pName, prop]) => ({\n prop: pName,\n constraints: prop.constraints,\n }));\n\n const fullResult = {\n meta: fragment.meta,\n props: fragment.props,\n variants: fragment.variants,\n relations: fragment.relations,\n contract: fragment.contract,\n generated: fragment._generated,\n guidelines: {\n when: filterPlaceholders(fragment.usage?.when),\n whenNot: filterPlaceholders(fragment.usage?.whenNot),\n guidelines: fragment.usage?.guidelines ?? [],\n accessibility: fragment.usage?.accessibility ?? [],\n propConstraints,\n alternatives: fragment.relations\n ?.filter((r) => r.relationship === 'alternative')\n .map((r) => ({\n component: r.component,\n note: r.note,\n })) ?? [],\n },\n examples: {\n import: `import { ${fragment.meta.name} } from '${pkgName}';`,\n code: examples,\n propsReference,\n },\n };\n\n // Alias legacy field paths (e.g., \"usage.when\" → \"guidelines.when\")\n const aliasMap: Record<string, string> = { 'usage': 'guidelines' };\n const resolvedFields = fields?.map(f => {\n const parts = f.split('.');\n if (aliasMap[parts[0]]) parts[0] = aliasMap[parts[0]];\n return parts.join('.');\n });\n\n let result: unknown;\n if (verbosity === 'compact' && !resolvedFields?.length) {\n // Compact: meta + prop names + variant names only\n result = {\n meta: fullResult.meta,\n propNames: Object.keys(fragment.props ?? {}),\n variantNames: fragment.variants.map(v => v.name),\n };\n } else {\n result = resolvedFields && resolvedFields.length > 0\n ? projectFields(fullResult as unknown as Record<string, unknown>, resolvedFields)\n : fullResult;\n }\n\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result) }],\n };\n }\n\n // ================================================================\n // BLOCKS\n // ================================================================\n case TOOL_NAMES.blocks: {\n const data = await loadFragments();\n const blockName = args?.name as string | undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const component = (args?.component as string)?.toLowerCase() ?? undefined;\n const category = (args?.category as string)?.toLowerCase() ?? undefined;\n const blocksLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 50) : (search ? 10 : undefined);\n\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n if (allBlocks.length === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n blocks: [],\n hint: `No composition blocks found. Blocks are reusable patterns showing how components wire together (e.g., \"Login Form\", \"Settings Page\"). Create .block.ts files and run \\`${BRAND.cliCommand} build\\`.`,\n }),\n }],\n };\n }\n\n let filtered = allBlocks;\n\n if (blockName) {\n filtered = filtered.filter(\n b => b.name.toLowerCase() === blockName.toLowerCase()\n );\n if (filtered.length === 0) {\n const allBlockNames = allBlocks.map(b => b.name);\n const closest = findClosestMatch(blockName, allBlockNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Block \"${blockName}\" not found.${suggestion} Use ${TOOL_NAMES.blocks} to see available blocks.`);\n }\n }\n\n if (search) {\n if (blockIndex) {\n // Use Orama BM25 search with synonym expansion for relevance-ranked results\n const ranked = searchBlocks(search, blockIndex, 50);\n const rankedNames = new Set(ranked.map(r => r.name.toLowerCase()));\n filtered = filtered.filter(b => rankedNames.has(b.name.toLowerCase()));\n // Re-order filtered to match Orama relevance ranking\n filtered.sort((a, b) => {\n const aIdx = ranked.findIndex(r => r.name.toLowerCase() === a.name.toLowerCase());\n const bIdx = ranked.findIndex(r => r.name.toLowerCase() === b.name.toLowerCase());\n return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);\n });\n } else {\n // Fallback: substring matching (blockIndex should always exist, but defensive)\n filtered = filtered.filter(b => {\n const haystack = [\n b.name,\n b.description,\n ...(b.tags ?? []),\n ...b.components,\n b.category,\n ].join(' ').toLowerCase();\n return haystack.includes(search);\n });\n }\n }\n\n if (component) {\n filtered = filtered.filter(b =>\n b.components.some(c => c.toLowerCase() === component)\n );\n }\n\n if (category) {\n filtered = filtered.filter(b =>\n b.category.toLowerCase() === category\n );\n }\n\n // Check if any blocks use Icon components — add import hint\n const blocksUseIcons = filtered.some(\n (b) => b.components.some((c) => c === 'Icon') ||\n (b.code && /\\bIcon\\b/.test(b.code))\n );\n const iconHint = blocksUseIcons\n ? \"Icon components in block code are from @phosphor-icons/react. Import them as: import { IconName } from '@phosphor-icons/react';\"\n : undefined;\n\n // Apply limit if specified\n if (blocksLimit !== undefined) {\n filtered = filtered.slice(0, blocksLimit);\n }\n\n const verbosity = (args?.verbosity as string) ?? 'standard';\n const blocksWithImports = await Promise.all(filtered.map(async (b) => {\n const imports = await buildImportStatements(\n b.components,\n async (componentName) => getPackageName(componentName)\n );\n const base = {\n name: b.name,\n description: b.description,\n category: b.category,\n components: b.components,\n tags: b.tags,\n import: imports.join('\\n'),\n imports,\n };\n if (verbosity === 'compact') return base;\n if (verbosity === 'full') return { ...base, code: b.code };\n // standard: code preview for long blocks\n const codeLines = b.code.split('\\n');\n const code = codeLines.length > 30\n ? codeLines.slice(0, 20).join('\\n') + '\\n// ... truncated (' + codeLines.length + ' lines total)'\n : b.code;\n return { ...base, code };\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: blocksWithImports.length,\n blocks: blocksWithImports,\n ...(iconHint && { iconHint }),\n ...(blocksWithImports.length === 0 && allBlocks.length > 0 && {\n hint: 'No blocks matching your query. Try broader search terms.',\n }),\n }),\n }],\n };\n }\n\n // ================================================================\n // TOKENS\n // ================================================================\n case TOOL_NAMES.tokens: {\n const data = await loadFragments();\n const category = (args?.category as string)?.toLowerCase() ?? undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const tokensLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 100) : (search ? 25 : undefined);\n\n const tokenData = data.tokens;\n\n if (!tokenData || tokenData.total === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n categories: {},\n hint: `No design tokens found. Add a tokens.include pattern to your ${BRAND.configFile} and run \\`${BRAND.cliCommand} build\\`.`,\n }),\n }],\n };\n }\n\n let filteredCategories: Record<string, Array<{ name: string; description?: string }>> = {};\n let filteredTotal = 0;\n\n // Fix: when search term matches a category name exactly, return all\n // tokens in that category (previously only searched token names/descriptions)\n const searchMatchesCategory = search\n ? Object.keys(tokenData.categories).find(cat => cat.toLowerCase() === search)\n : undefined;\n\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n if (category && cat !== category) continue;\n\n let filtered = tokens;\n if (search) {\n // If the search term IS a category name, include all tokens in that category\n if (searchMatchesCategory && cat.toLowerCase() === search) {\n filtered = tokens; // include all\n } else {\n filtered = tokens.filter(\n (t) => t.name.toLowerCase().includes(search) ||\n (t.description && t.description.toLowerCase().includes(search)) ||\n cat.toLowerCase().includes(search)\n );\n }\n }\n\n if (filtered.length > 0) {\n filteredCategories[cat] = filtered;\n filteredTotal += filtered.length;\n }\n }\n\n // Apply token limit per category (default 25 per category for search queries)\n if (tokensLimit !== undefined) {\n const limited = limitTokensPerCategory(filteredCategories, tokensLimit);\n filteredCategories = limited.categories;\n filteredTotal = limited.total;\n }\n\n let hint: string | undefined;\n if (filteredTotal === 0) {\n const availableCategories = Object.keys(tokenData.categories);\n if (category && search) {\n // Combined category + search returned no results\n const categoryTotal = tokenData.categories[category]?.length ?? 0;\n hint = categoryTotal > 0\n ? `No tokens matching \"${search}\" in category \"${category}\" (${categoryTotal} tokens in this category). Try a broader search or remove the search term.`\n : `Category \"${category}\" not found. Available: ${availableCategories.join(', ')}`;\n } else if (search) {\n hint = `No tokens matching \"${search}\". Available categories: ${availableCategories.join(', ')}`;\n } else if (category) {\n hint = `Category \"${category}\" not found. Available: ${availableCategories.join(', ')}`;\n }\n } else if (!category && !search) {\n hint = `Use var(--token-name) in your CSS/styles. Filter by category or search to narrow results.`;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n prefix: tokenData.prefix,\n total: filteredTotal,\n totalAvailable: tokenData.total,\n categories: filteredCategories,\n ...(hint && { hint }),\n ...((!category && !search) && {\n availableCategories: Object.entries(tokenData.categories).map(\n ([cat, tokens]) => ({ category: cat, count: tokens.length })\n ),\n }),\n }),\n }],\n };\n }\n\n // ================================================================\n // IMPLEMENT — one-shot discover + inspect + blocks + tokens\n // ================================================================\n case TOOL_NAMES.implement: {\n const data = await loadFragments();\n const useCase = args?.useCase as string;\n if (!useCase) {\n throw new Error('useCase is required');\n }\n\n const verbosity = (args?.verbosity as string) ?? 'standard';\n const { allFragments, allBlocks, localData } = buildLocalSearchData(\n data,\n {\n componentIndex,\n blockIndex,\n tokenIndex,\n }\n );\n const tokenData = data.tokens;\n const implLimit = typeof args?.limit === 'number' ? Math.min(Math.max(args.limit, 1), 15) : 5;\n\n // Search each kind independently — no cross-kind competition for slots\n const [componentResults, blockResults, tokenResults] = await Promise.all([\n hybridSearch(useCase, localData, implLimit * 3, 'component', config.apiKey),\n hybridSearch(useCase, localData, implLimit, 'block', config.apiKey),\n hybridSearch(useCase, localData, implLimit, 'token', config.apiKey),\n ]);\n\n // Filter blocks by relevance floor (30% of top block score)\n const topBlockScore = blockResults.length > 0 ? blockResults[0].score : 0;\n const filteredBlockResults = blockResults.filter(r => r.score >= topBlockScore * 0.3);\n\n // Block-first component ranking: boost by block component frequency\n if (filteredBlockResults.length > 0) {\n const matchedBlocks = filteredBlockResults\n .map(r => allBlocks.find(b => b.name.toLowerCase() === r.name.toLowerCase()))\n .filter(Boolean) as typeof allBlocks;\n const blockFreq = buildBlockComponentFrequency(matchedBlocks);\n boostByBlockFrequency(componentResults, blockFreq);\n }\n\n // Take top matches after boosting (respects limit param)\n const topComponentResults = componentResults.slice(0, implLimit);\n const maxCompScore = topComponentResults.length > 0 ? topComponentResults[0].score : 0;\n\n // Map component results back to fragments\n const topMatches = topComponentResults.map((result) => {\n const fragment = allFragments.find(\n (s) => s.meta.name.toLowerCase() === result.name.toLowerCase()\n );\n return fragment ? { fragment, score: result.score } : null;\n }).filter(Boolean) as Array<{ fragment: CompiledFragment; score: number }>;\n\n // Build component details for top matches\n const components = await Promise.all(\n topMatches.map(async ({ fragment: s, score }) => {\n const pkgName = await getPackageName(s.meta.name);\n if (verbosity === 'compact') {\n return {\n name: s.meta.name,\n description: s.meta.description,\n confidence: assignConfidence(score, maxCompScore),\n import: `import { ${s.meta.name} } from '${pkgName}';`,\n };\n }\n const exampleLimit = verbosity === 'full' ? s.variants.length : 2;\n const propsLimit = verbosity === 'full' ? Object.keys(s.props ?? {}).length : 5;\n const examples = s.variants.slice(0, exampleLimit).map((v) => ({\n variant: v.name,\n code: v.code ?? `<${s.meta.name} />`,\n }));\n const propsSummary = Object.entries(s.props ?? {}).slice(0, propsLimit).map(\n ([pName, p]) => `${pName}${p.required ? ' (required)' : ''}: ${p.type}${p.values ? ` = ${p.values.join('|')}` : ''}`\n );\n return {\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n confidence: assignConfidence(score, maxCompScore),\n import: `import { ${s.meta.name} } from '${pkgName}';`,\n props: propsSummary,\n examples,\n guidelines: filterPlaceholders(s.usage?.when).slice(0, 3),\n accessibility: s.usage?.accessibility?.slice(0, 2) ?? [],\n };\n })\n );\n\n // Map block results back to full block data (up to 5)\n const matchingBlocks = (await Promise.all(filteredBlockResults.slice(0, 5).map(async (result) => {\n const block = allBlocks.find(\n (b) => b.name.toLowerCase() === result.name.toLowerCase()\n );\n if (!block) return null;\n const imports = await buildImportStatements(\n block.components,\n async (componentName) => getPackageName(componentName)\n );\n const codeLines = block.code.split('\\n');\n const code = codeLines.length > 30\n ? codeLines.slice(0, 20).join('\\n') + '\\n// ... truncated (' + codeLines.length + ' lines total)'\n : block.code;\n return {\n name: block.name,\n description: block.description,\n components: block.components,\n code,\n import: imports.join('\\n'),\n imports,\n };\n }))).filter(Boolean) as Array<{\n name: string;\n description: string;\n components: string[];\n code: string;\n import: string;\n imports: string[];\n }>;\n\n // Map token results to grouped format.\n // Fix: when BM25 search returns empty (use-case terms don't match token\n // names like \"--fui-space-2\"), extract semantic categories from the query\n // and return representative tokens from those categories.\n let relevantTokens: Record<string, string[]> | undefined;\n if (tokenResults.length > 0 && tokenData) {\n relevantTokens = {};\n for (const result of tokenResults) {\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n if (tokens.some((t) => t.name === result.name)) {\n if (!relevantTokens[cat]) relevantTokens[cat] = [];\n relevantTokens[cat].push(result.name);\n break;\n }\n }\n }\n if (Object.keys(relevantTokens).length === 0) relevantTokens = undefined;\n }\n\n // Fallback: extract relevant token categories from the use-case query\n if (!relevantTokens && tokenData) {\n const categories = extractTokenCategories(useCase);\n relevantTokens = {};\n for (const cat of categories) {\n const tokens = tokenData.categories[cat];\n if (tokens && tokens.length > 0) {\n // Include up to 5 representative tokens per category\n relevantTokens[cat] = tokens.slice(0, 5).map(t => t.name);\n }\n }\n if (Object.keys(relevantTokens).length === 0) relevantTokens = undefined;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n useCase,\n components,\n blocks: verbosity !== 'compact' && matchingBlocks.length > 0 ? matchingBlocks : undefined,\n tokens: verbosity !== 'compact' ? relevantTokens : undefined,\n noMatch: components.length === 0,\n summary: components.length > 0\n ? `Found ${components.length} component(s) for \"${useCase}\". ${matchingBlocks.length > 0 ? `Plus ${matchingBlocks.length} ready-to-use block(s).` : ''}`\n : `No components match \"${useCase}\". Try ${TOOL_NAMES.discover} with different terms${tokenData ? ` or ${TOOL_NAMES.tokens} for CSS variables` : ''}.`,\n }),\n }],\n };\n }\n\n // ================================================================\n // RENDER — HTTP-only (no Playwright)\n // ================================================================\n case TOOL_NAMES.render: {\n const componentName = args?.component as string;\n const variantName = args?.variant as string | undefined;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const viewport = args?.viewport as { width?: number; height?: number } | undefined;\n const figmaUrl = args?.figmaUrl as string | undefined;\n const threshold = (args?.threshold as number) ?? (figmaUrl ? 1.0 : config.threshold ?? DEFAULTS.diffThreshold);\n\n if (!componentName) {\n return {\n content: [{ type: 'text' as const, text: 'Error: component name is required' }],\n isError: true,\n };\n }\n\n // Validate component exists (provides \"did you mean?\" on typos)\n {\n const data = await loadFragments();\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n // --- Figma compare mode ---\n if (figmaUrl) {\n try {\n const result = await compareComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n props,\n figmaUrl,\n threshold,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Compare error: ${result.error}${result.suggestion ? `\\nSuggestion: ${result.suggestion}` : ''}`,\n }],\n isError: true,\n };\n }\n\n const content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> = [];\n\n const summaryText = result.match\n ? `MATCH: ${componentName} matches Figma design (${result.diffPercentage}% diff, threshold: ${result.threshold}%)`\n : `MISMATCH: ${componentName} differs from Figma design by ${result.diffPercentage}% (threshold: ${result.threshold}%)`;\n\n content.push({ type: 'text' as const, text: summaryText });\n\n if (result.diff && !result.match) {\n content.push({\n type: 'image' as const,\n data: result.diff.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n });\n content.push({\n type: 'text' as const,\n text: `Diff image above shows visual differences (red highlights). Changed regions: ${result.changedRegions?.length ?? 0}`,\n });\n }\n\n content.push({\n type: 'text' as const,\n text: JSON.stringify({\n match: result.match,\n diffPercentage: result.diffPercentage,\n threshold: result.threshold,\n figmaUrl: result.figmaUrl,\n changedRegions: result.changedRegions,\n }),\n });\n\n return { content };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to compare component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running and FIGMA_ACCESS_TOKEN is set.`,\n }],\n isError: true,\n };\n }\n }\n\n // --- Default: pure render mode ---\n try {\n const result = await renderComponent(viewerUrl, {\n component: componentName,\n props,\n variant: variantName,\n viewport: viewport ?? { width: 800, height: 600 },\n });\n\n if (result.error) {\n return {\n content: [{ type: 'text' as const, text: `Render error: ${result.error}` }],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'image' as const,\n data: result.screenshot!.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n },\n {\n type: 'text' as const,\n text: `Successfully rendered ${componentName}${variantName ? ` (variant: \"${variantName}\")` : ''}${Object.keys(props).length > 0 ? ` with props: ${JSON.stringify(props)}` : ''}`,\n },\n ],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to render component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // FIX — HTTP-only (no Playwright)\n // ================================================================\n case TOOL_NAMES.fix: {\n const data = await loadFragments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const fixType = (args?.fixType as 'token' | 'all') ?? 'all';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n try {\n const result = await fixComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n fixType,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Fix generation error: ${result.error}`,\n }],\n isError: true,\n };\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n fixType,\n patches: result.patches,\n summary: result.summary,\n patchCount: result.patches.length,\n nextStep: result.patches.length > 0\n ? 'Apply patches using your editor or `patch` command, then run fragments_render to confirm fixes.'\n : undefined,\n }),\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to generate fixes: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // A11Y — accessibility audit\n // ================================================================\n case TOOL_NAMES.a11y: {\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const standard = (args?.standard as 'AA' | 'AAA') ?? 'AA';\n const includeFixPatches = (args?.includeFixPatches as boolean) ?? false;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n // Validate component exists (provides \"did you mean?\" on typos)\n {\n const data = await loadFragments();\n const fragment = Object.values(data.fragments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n if (!fragment) {\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const closest = findClosestMatch(componentName, allNames);\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n throw new Error(`Component \"${componentName}\" not found.${suggestion} Use ${TOOL_NAMES.discover} to see available components.`);\n }\n }\n\n const viewerUrl = config.viewerUrl;\n if (!viewerUrl) {\n return {\n content: [{\n type: 'text' as const,\n text: NO_VIEWER_MSG,\n }],\n isError: true,\n };\n }\n\n try {\n const result = await auditComponent(viewerUrl, {\n component: componentName,\n variant: variantName,\n standard,\n includeFixPatches,\n });\n\n if (result.error) {\n return {\n content: [{\n type: 'text' as const,\n text: `A11y audit error: ${result.error}`,\n }],\n isError: true,\n };\n }\n\n let nextStep: string;\n if (result.emptyAudit) {\n nextStep = `No testable elements found for ${variantName ? `variant \"${variantName}\"` : componentName}. The variant may not exist or renders no accessible content. Check available variants with ${TOOL_NAMES.inspect}(\"${componentName}\").`;\n } else if (result.passed) {\n nextStep = 'All accessibility checks passed. Consider running with standard: \"AAA\" for enhanced compliance.';\n } else {\n nextStep = `Fix the violations above, then re-run ${TOOL_NAMES.a11y} to verify. Use ${TOOL_NAMES.fix} for automated fixes.`;\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n standard,\n totalViolations: result.results.reduce((sum, r) => sum + r.summary.total, 0),\n variantsPassingAA: `${result.aaPercent}%`,\n variantsPassingAAA: `${result.aaaPercent}%`,\n passed: result.passed,\n ...(result.emptyAudit && { emptyAudit: true }),\n results: result.results,\n nextStep,\n }),\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: `Failed to audit component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n }],\n isError: true,\n };\n }\n }\n\n // ================================================================\n // GRAPH — component relationship queries\n // ================================================================\n case TOOL_NAMES.graph: {\n const data = await loadFragments();\n const graphArgs: GraphToolArgs = {\n mode: (args?.mode as string) ?? 'health',\n component: args?.component as string | undefined,\n target: args?.target as string | undefined,\n edgeTypes: args?.edgeTypes as string[] | undefined,\n maxDepth: args?.maxDepth as number | undefined,\n };\n\n const allNames = Object.values(data.fragments).map(s => s.meta.name);\n const result = handleGraphTool(\n graphArgs,\n data.graph,\n data.blocks ?? data.recipes,\n allNames,\n );\n\n if (result.isError) {\n return {\n content: [{ type: 'text' as const, text: result.text }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: 'text' as const, text: result.text }],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n }),\n }],\n isError: true,\n };\n }\n });\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<void> {\n const server = createMcpServer(config);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n/**\n * Smithery sandbox server for capability scanning.\n * Returns a server instance with default config so Smithery can enumerate tools.\n */\nexport function createSandboxServer() {\n return createMcpServer({ projectRoot: process.cwd() });\n}\n","/**\n * Brand constants for easy rebranding if domain availability requires it.\n * All naming throughout the codebase should reference these constants.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\nexport const BRAND = {\n /** Display name (e.g., \"Fragments\") */\n name: \"Fragments\",\n\n /** Lowercase name for file paths and CLI (e.g., \"fragments\") */\n nameLower: \"fragments\",\n\n /** File extension for fragment definition files (e.g., \".fragment.tsx\") */\n fileExtension: \".fragment.tsx\",\n\n /** Legacy file extension for segments (still supported for migration) */\n legacyFileExtension: \".segment.tsx\",\n\n /** JSON file extension for compiled output */\n jsonExtension: \".fragment.json\",\n\n /** Default output file name (e.g., \"fragments.json\") */\n outFile: \"fragments.json\",\n\n /** Config file name (e.g., \"fragments.config.ts\") */\n configFile: \"fragments.config.ts\",\n\n /** Legacy config file name (still supported for migration) */\n legacyConfigFile: \"segments.config.ts\",\n\n /** CLI command name (e.g., \"fragments\") */\n cliCommand: \"fragments\",\n\n /** Package scope (e.g., \"@fragments\") */\n packageScope: \"@fragments\",\n\n /** Directory for storing fragments, registry, and cache */\n dataDir: \".fragments\",\n\n /** Components subdirectory within .fragments/ */\n componentsDir: \"components\",\n\n /** Registry file name */\n registryFile: \"registry.json\",\n\n /** Context file name (AI-ready markdown) */\n contextFile: \"context.md\",\n\n /** Screenshots subdirectory */\n screenshotsDir: \"screenshots\",\n\n /** Cache subdirectory (gitignored) */\n cacheDir: \"cache\",\n\n /** Diff output subdirectory (gitignored) */\n diffDir: \"diff\",\n\n /** Manifest filename */\n manifestFile: \"manifest.json\",\n\n /** Prefix for localStorage keys (e.g., \"fragments-\") */\n storagePrefix: \"fragments-\",\n\n /** Static viewer HTML file name */\n viewerHtmlFile: \"fragments-viewer.html\",\n\n /** MCP tool name prefix (e.g., \"fragments_\") */\n mcpToolPrefix: \"fragments_\",\n\n /** File extension for block definition files */\n blockFileExtension: \".block.ts\",\n\n /** @deprecated Use blockFileExtension instead */\n recipeFileExtension: \".recipe.ts\",\n\n /** Vite plugin namespace */\n vitePluginNamespace: \"fragments-core-shim\",\n} as const;\n\nexport type Brand = typeof BRAND;\n\n/**\n * Default configuration values for the service.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\nexport const DEFAULTS = {\n /** Default viewport dimensions */\n viewport: {\n width: 1280,\n height: 800,\n },\n\n /** Default diff threshold (percentage) */\n diffThreshold: 5,\n\n /** Browser pool size */\n poolSize: 3,\n\n /** Idle timeout before browser shutdown (ms) - 5 minutes */\n idleTimeoutMs: 5 * 60 * 1000,\n\n /** Delay after render before capture (ms) */\n captureDelayMs: 100,\n\n /** Font loading timeout (ms) */\n fontTimeoutMs: 3000,\n\n /** Default theme */\n theme: \"light\" as const,\n\n /** Dev server port */\n port: 6006,\n} as const;\n\nexport type Defaults = typeof DEFAULTS;\n","/**\n * Fragment discovery — finds fragments.json files in the project.\n *\n * Extracted from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\n\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { BRAND } from './constants.js';\n\n/**\n * Resolve workspace directory globs (e.g. \"apps/*\") into actual paths.\n */\nfunction resolveWorkspaceGlob(baseDir: string, pattern: string): string[] {\n const parts = pattern.split('/');\n let dirs = [baseDir];\n\n for (const part of parts) {\n if (part === '**') continue;\n const next: string[] = [];\n for (const d of dirs) {\n if (part === '*') {\n try {\n for (const entry of readdirSync(d, { withFileTypes: true })) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {\n next.push(join(d, entry.name));\n }\n }\n } catch { /* unreadable dir */ }\n } else {\n const candidate = join(d, part);\n if (existsSync(candidate)) next.push(candidate);\n }\n }\n dirs = next;\n }\n\n return dirs;\n}\n\n/**\n * Detect workspace directories from package.json \"workspaces\" or pnpm-workspace.yaml.\n */\nfunction getWorkspaceDirs(rootDir: string): string[] {\n const dirs: string[] = [];\n\n // npm/yarn: package.json \"workspaces\" field\n const rootPkgPath = join(rootDir, 'package.json');\n if (existsSync(rootPkgPath)) {\n try {\n const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));\n const workspaces = Array.isArray(rootPkg.workspaces)\n ? rootPkg.workspaces\n : rootPkg.workspaces?.packages;\n if (Array.isArray(workspaces)) {\n for (const pattern of workspaces) {\n dirs.push(...resolveWorkspaceGlob(rootDir, pattern));\n }\n return dirs;\n }\n } catch { /* unreadable */ }\n }\n\n // pnpm: pnpm-workspace.yaml\n const pnpmWsPath = join(rootDir, 'pnpm-workspace.yaml');\n if (existsSync(pnpmWsPath)) {\n try {\n const content = readFileSync(pnpmWsPath, 'utf-8');\n const lines = content.split('\\n');\n let inPackages = false;\n for (const line of lines) {\n if (/^packages\\s*:/.test(line)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n const match = line.match(/^\\s+-\\s+['\"]?([^'\"#\\n]+)['\"]?/);\n if (match) {\n dirs.push(...resolveWorkspaceGlob(rootDir, match[1].trim()));\n } else if (/^\\S/.test(line) && line.trim()) {\n break;\n }\n }\n }\n } catch { /* unreadable */ }\n }\n\n return dirs;\n}\n\n/**\n * Resolve a dependency's package.json path. Tries the standard subpath first,\n * then falls back to resolving the package's main entry and walking up to\n * find package.json — necessary when the package's `exports` map doesn't\n * expose `./package.json`.\n */\nfunction resolveDepPackageJson(\n localRequire: NodeRequire,\n depName: string\n): string | null {\n // Fast path: package exposes ./package.json in exports\n try {\n return localRequire.resolve(`${depName}/package.json`);\n } catch {\n // Blocked by exports map\n }\n\n // Fallback: resolve the package's main entry and walk up to package.json\n try {\n const mainPath = localRequire.resolve(depName);\n let dir = dirname(mainPath);\n while (true) {\n const candidate = join(dir, 'package.json');\n if (existsSync(candidate)) {\n const pkg = JSON.parse(readFileSync(candidate, 'utf-8'));\n if (pkg.name === depName) return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // Package not resolvable at all\n }\n\n return null;\n}\n\n/**\n * Scan a directory's package.json deps for packages with a \"fragments\" field.\n */\nfunction findFragmentsInDeps(dir: string, found: string[]): void {\n const pkgJsonPath = join(dir, 'package.json');\n if (!existsSync(pkgJsonPath)) return;\n\n try {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies,\n };\n const localRequire = createRequire(join(dir, 'noop.js'));\n for (const depName of Object.keys(allDeps)) {\n try {\n const depPkgPath = resolveDepPackageJson(localRequire, depName);\n if (!depPkgPath) continue;\n const depPkg = JSON.parse(readFileSync(depPkgPath, 'utf-8'));\n if (depPkg.fragments) {\n const fragmentsPath = join(dirname(depPkgPath), depPkg.fragments);\n if (existsSync(fragmentsPath) && !found.includes(fragmentsPath)) {\n found.push(fragmentsPath);\n }\n }\n } catch {\n // Package not resolvable or unreadable, skip\n }\n }\n } catch {\n // No package.json or unreadable\n }\n}\n\n/**\n * Find fragments.json files:\n * 1. Walk up from startDir (for library authors with a local build)\n * 2. Read package.json deps and resolve packages with a \"fragments\" field\n * 3. Check workspace packages' deps (monorepo support)\n *\n * Uses Node.js module resolution (createRequire) to handle all package\n * managers: pnpm symlinks, yarn PnP, monorepo hoisting, etc.\n */\nexport function findFragmentsJson(startDir: string): string[] {\n const found: string[] = [];\n const resolvedStart = resolve(startDir);\n\n // 1. Walk upward from startDir (library author flow)\n let dir = resolvedStart;\n while (true) {\n const candidate = join(dir, BRAND.outFile);\n if (existsSync(candidate)) {\n found.push(candidate);\n break;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // 2. Check root package.json deps\n findFragmentsInDeps(resolvedStart, found);\n\n // 3. Check workspace packages' deps (monorepo support)\n if (found.length === 0 || existsSync(join(resolvedStart, 'pnpm-workspace.yaml'))) {\n const workspaceDirs = getWorkspaceDirs(resolvedStart);\n for (const wsDir of workspaceDirs) {\n findFragmentsInDeps(wsDir, found);\n }\n }\n\n return found;\n}\n","/**\n * Orama-powered BM25 search indexes for components, blocks, and tokens.\n *\n * Replaces the bag-of-words keyword scorer with Orama's built-in BM25 engine,\n * which provides IDF weighting (automatically downweights common terms like\n * \"page\", \"section\", \"content\"), stemming, and field-level boosting.\n */\n\nimport { create, insertMultiple, search } from '@orama/orama';\nimport type { AnyOrama } from '@orama/orama';\nimport type { CompiledFragment, CompiledBlock, CompiledTokenData } from '@fragments-sdk/context/types';\nimport type { ScoredResult, EntryKind } from './search.js';\n\n// ---------------------------------------------------------------------------\n// Synonym map (shared with search.ts — imported via re-export)\n// ---------------------------------------------------------------------------\n\nexport const SYNONYM_MAP: Record<string, string[]> = {\n 'form': ['input', 'field', 'submit', 'validation'],\n 'input': ['form', 'field', 'text', 'entry'],\n 'button': ['action', 'click', 'submit', 'trigger'],\n 'action': ['button', 'click', 'trigger'],\n 'submit': ['button', 'form', 'action', 'send'],\n 'alert': ['notification', 'message', 'warning', 'error', 'feedback'],\n 'notification': ['alert', 'message', 'toast'],\n 'feedback': ['form', 'comment', 'review', 'rating'],\n 'card': ['container', 'panel', 'box', 'content'],\n 'toggle': ['switch', 'checkbox', 'boolean', 'on/off'],\n 'switch': ['toggle', 'checkbox', 'boolean'],\n 'badge': ['tag', 'label', 'status', 'indicator'],\n 'status': ['badge', 'indicator', 'state'],\n 'login': ['auth', 'signin', 'authentication', 'form'],\n 'auth': ['login', 'signin', 'authentication'],\n 'chat': ['message', 'conversation', 'ai'],\n 'table': ['data', 'grid', 'list', 'rows'],\n 'textarea': ['text', 'input', 'multiline', 'area', 'comment'],\n 'area': ['textarea', 'multiline', 'text'],\n 'landing': ['page', 'hero', 'marketing', 'section', 'layout'],\n 'hero': ['landing', 'marketing', 'banner', 'headline', 'section'],\n 'marketing': ['landing', 'hero', 'pricing', 'testimonial', 'cta'],\n 'cta': ['marketing', 'banner', 'action', 'button'],\n 'testimonial': ['marketing', 'review', 'quote', 'feedback'],\n 'layout': ['stack', 'grid', 'box', 'container', 'page'],\n 'page': ['layout', 'landing', 'section', 'container'],\n 'section': ['hero', 'feature', 'testimonial', 'cta', 'faq'],\n 'pricing': ['card', 'plan', 'tier', 'marketing'],\n 'plan': ['pricing', 'card', 'tier', 'subscription'],\n 'dashboard': ['metrics', 'stats', 'chart', 'card', 'grid'],\n 'metrics': ['dashboard', 'stats', 'progress', 'number'],\n 'stats': ['metrics', 'dashboard', 'progress', 'badge'],\n 'chart': ['dashboard', 'metrics', 'data', 'graph'],\n};\n\n// ---------------------------------------------------------------------------\n// Query expansion via synonyms\n// ---------------------------------------------------------------------------\n\n/**\n * Expand a query string with synonym terms.\n * Returns the expanded query as a single string suitable for Orama `term`.\n */\nexport function expandQuery(query: string): string {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const expanded = new Set(terms);\n for (const term of terms) {\n const synonyms = SYNONYM_MAP[term];\n if (synonyms) {\n for (const syn of synonyms) expanded.add(syn);\n }\n }\n return Array.from(expanded).join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// Shared two-pass search pattern\n// ---------------------------------------------------------------------------\n\ninterface TwoPassConfig {\n index: AnyOrama;\n query: string;\n properties: string[];\n boost: Record<string, number>;\n limit: number;\n kind: EntryKind;\n}\n\n/**\n * Two-pass BM25 search: original terms weighted 2x, synonym-expanded terms 1x.\n * Prevents synonym noise from outranking truly relevant results.\n */\nexport function twoPassSearch(config: TwoPassConfig): ScoredResult[] {\n const { index, query, properties, boost, limit, kind } = config;\n\n const baseConfig = {\n mode: 'fulltext' as const,\n properties,\n boost,\n limit,\n };\n\n const originalTermsQuery = query.toLowerCase().split(/\\s+/).filter(Boolean).join(' ');\n const expandedQuery = expandQuery(query);\n\n // First pass: original terms only (moderate threshold to filter weak matches)\n const originalResults = search(index, { term: originalTermsQuery, ...baseConfig, threshold: 0.8 });\n // Second pass: synonym-expanded (permissive — scoring handles relevance via 1x weight)\n const expandedResults = search(index, { term: expandedQuery, ...baseConfig, threshold: 1 });\n\n type Hit = { score: number; document: { name: string } };\n const origHits = (originalResults as unknown as { hits: Hit[] }).hits;\n const expHits = (expandedResults as unknown as { hits: Hit[] }).hits;\n\n // Combine scores: original terms get 2x weight\n const scoreMap = new Map<string, number>();\n for (const hit of origHits) {\n scoreMap.set(hit.document.name, (hit.score || 0) * 2);\n }\n for (const hit of expHits) {\n const name = hit.document.name;\n const existing = scoreMap.get(name) ?? 0;\n scoreMap.set(name, existing + (hit.score || 0));\n }\n\n const scored: ScoredResult[] = [];\n for (const [name, score] of scoreMap) {\n if (score > 0) {\n scored.push({ name, kind, rank: scored.length, score });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n scored.forEach((s, i) => { s.rank = i; });\n\n return scored;\n}\n\n// ---------------------------------------------------------------------------\n// Component index\n// ---------------------------------------------------------------------------\n\nconst componentSchema = {\n name: 'string' as const,\n description: 'string' as const,\n category: 'string' as const,\n tags: 'string' as const,\n whenUsed: 'string' as const,\n variants: 'string' as const,\n status: 'string' as const,\n};\n\nexport type ComponentIndex = AnyOrama;\n\nexport function buildComponentIndex(fragments: CompiledFragment[]): ComponentIndex {\n const db = create({ schema: componentSchema, language: 'english' });\n\n const docs = fragments.map((f) => ({\n name: f.meta.name,\n description: f.meta.description ?? '',\n category: f.meta.category ?? '',\n tags: (f.meta.tags ?? []).join(' '),\n whenUsed: (f.usage?.when ?? []).join(' '),\n variants: f.variants.map(v => `${v.name} ${v.description || ''}`).join(' '),\n status: f.meta.status ?? 'stable',\n }));\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchComponents(\n query: string,\n index: ComponentIndex,\n fragments: CompiledFragment[],\n limit = 50,\n): ScoredResult[] {\n const boostConfig = {\n mode: 'fulltext' as const,\n properties: ['name', 'whenUsed', 'description', 'category', 'tags', 'variants'],\n boost: {\n name: 3,\n whenUsed: 2.5,\n description: 2,\n category: 1.5,\n tags: 1.5,\n variants: 1,\n },\n limit,\n };\n\n // Two-pass search: original terms weighted 2x, synonym terms 1x\n // This prevents synonym noise (\"box\", \"container\") from outranking truly relevant results\n const originalTermsList = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const originalTermsQuery = originalTermsList.join(' ');\n const expandedQuery = expandQuery(query);\n\n // First pass: original terms, moderate threshold; second pass: synonyms, permissive\n const originalResults = search(index, { term: originalTermsQuery, ...boostConfig, threshold: 0.8 });\n const expandedResults = search(index, { term: expandedQuery, ...boostConfig, threshold: 1 });\n\n type Hit = { score: number; document: { name: string } };\n const origHits = (originalResults as unknown as { hits: Hit[] }).hits;\n const expHits = (expandedResults as unknown as { hits: Hit[] }).hits;\n\n // Combine scores: original terms get 2x weight\n const scoreMap = new Map<string, number>();\n for (const hit of origHits) {\n scoreMap.set(hit.document.name, (hit.score || 0) * 2);\n }\n for (const hit of expHits) {\n const name = hit.document.name;\n const existing = scoreMap.get(name) ?? 0;\n scoreMap.set(name, existing + (hit.score || 0));\n }\n\n // Build a name→fragment lookup for status bonuses\n const fragmentMap = new Map<string, CompiledFragment>();\n for (const f of fragments) {\n fragmentMap.set(f.meta.name.toLowerCase(), f);\n }\n\n // Exact name match bonus: if a component name matches an original query term exactly,\n // boost it above similar-named components (e.g., \"Button\" > \"ButtonGroup\" for \"button action\")\n const originalTermsSet = new Set(originalTermsList);\n\n // Build scored results with status + name match adjustments\n const scored: ScoredResult[] = [];\n for (const [name, rawScore] of scoreMap) {\n let score = rawScore;\n const nameLower = name.toLowerCase();\n const fragment = fragmentMap.get(nameLower);\n\n // Exact name match bonus — strong signal that this specific component was requested\n // Must be large enough to overcome BM25 score differences from compound names\n // (e.g., \"ButtonGroup\" matching more fields than \"Button\")\n if (originalTermsSet.has(nameLower)) {\n score += 25;\n }\n\n // Apply status bonus/penalty (matches old scorer)\n if (fragment) {\n if (fragment.meta.status === 'stable') score += 5;\n else if (fragment.meta.status === 'beta') score += 2;\n if (fragment.meta.status === 'deprecated') score -= 25;\n }\n\n if (score > 0) {\n scored.push({ name, kind: 'component' as EntryKind, rank: scored.length, score });\n }\n }\n\n // Sort by score descending and assign ranks\n scored.sort((a, b) => b.score - a.score);\n scored.forEach((s, i) => { s.rank = i; });\n\n return scored;\n}\n\n// ---------------------------------------------------------------------------\n// Block index\n// ---------------------------------------------------------------------------\n\nconst blockSchema = {\n name: 'string' as const,\n description: 'string' as const,\n category: 'string' as const,\n tags: 'string' as const,\n components: 'string' as const,\n};\n\nexport type BlockIndex = AnyOrama;\n\nexport function buildBlockIndex(blocks: CompiledBlock[]): BlockIndex {\n const db = create({ schema: blockSchema, language: 'english' });\n\n const docs = blocks.map((b) => ({\n name: b.name,\n description: b.description ?? '',\n category: b.category ?? '',\n tags: (b.tags ?? []).join(' '),\n components: b.components.join(' '),\n }));\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchBlocks(\n query: string,\n index: BlockIndex,\n limit = 50,\n): ScoredResult[] {\n return twoPassSearch({\n index,\n query,\n properties: ['name', 'description', 'components', 'tags', 'category'],\n boost: {\n name: 3,\n description: 2,\n components: 1.5,\n tags: 1.5,\n category: 1.5,\n },\n limit,\n kind: 'block' as EntryKind,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Token index\n// ---------------------------------------------------------------------------\n\nconst tokenSchema = {\n name: 'string' as const,\n category: 'string' as const,\n description: 'string' as const,\n};\n\nexport type TokenIndex = AnyOrama;\n\nexport function buildTokenIndex(tokenData: CompiledTokenData): TokenIndex {\n const db = create({ schema: tokenSchema, language: 'english' });\n\n const docs: Array<{ name: string; category: string; description: string }> = [];\n for (const [cat, tokens] of Object.entries(tokenData.categories)) {\n for (const token of tokens) {\n docs.push({\n name: token.name,\n category: cat,\n description: token.description ?? '',\n });\n }\n }\n\n insertMultiple(db, docs);\n return db;\n}\n\nexport function searchTokens(\n query: string,\n index: TokenIndex,\n limit = 50,\n): ScoredResult[] {\n return twoPassSearch({\n index,\n query,\n properties: ['name', 'category', 'description'],\n boost: {\n name: 2.5,\n category: 2,\n description: 1.5,\n },\n limit,\n kind: 'token' as EntryKind,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Semantic category extraction for implement tool token matching\n// ---------------------------------------------------------------------------\n\n/** Maps use-case keywords to relevant token categories */\nconst USE_CASE_TOKEN_CATEGORIES: Record<string, string[]> = {\n 'table': ['spacing', 'borders', 'surfaces', 'text'],\n 'data': ['spacing', 'borders', 'surfaces'],\n 'grid': ['spacing', 'layout'],\n 'form': ['spacing', 'borders', 'radius', 'focus'],\n 'input': ['spacing', 'borders', 'radius', 'focus'],\n 'card': ['surfaces', 'shadows', 'radius', 'borders', 'spacing'],\n 'button': ['colors', 'radius', 'spacing', 'focus'],\n 'layout': ['spacing', 'layout', 'surfaces'],\n 'dashboard': ['spacing', 'surfaces', 'borders', 'shadows'],\n 'chat': ['spacing', 'surfaces', 'radius', 'shadows'],\n 'modal': ['shadows', 'surfaces', 'radius', 'spacing'],\n 'dialog': ['shadows', 'surfaces', 'radius', 'spacing'],\n 'navigation': ['spacing', 'surfaces', 'borders'],\n 'sidebar': ['spacing', 'surfaces', 'borders'],\n 'hero': ['spacing', 'typography', 'colors'],\n 'landing': ['spacing', 'typography', 'colors'],\n 'pricing': ['spacing', 'surfaces', 'borders', 'radius'],\n 'auth': ['spacing', 'borders', 'radius', 'focus'],\n 'login': ['spacing', 'borders', 'radius', 'focus'],\n 'dark': ['colors', 'surfaces'],\n 'theme': ['colors', 'surfaces', 'text'],\n};\n\n/**\n * Extract relevant token categories from a use-case query.\n * Returns category names that should be included in implement results.\n */\nexport function extractTokenCategories(query: string): string[] {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const categories = new Set<string>();\n\n for (const term of terms) {\n const cats = USE_CASE_TOKEN_CATEGORIES[term];\n if (cats) {\n for (const cat of cats) categories.add(cat);\n }\n }\n\n // If nothing matched, return common defaults\n if (categories.size === 0) {\n return ['spacing', 'colors', 'surfaces'];\n }\n\n return Array.from(categories);\n}\n","/**\n * Search module for MCP server component discovery.\n *\n * Default (free): BM25 scoring via Orama with synonym expansion and multi-field\n * boosted matching against fragments.json. No external API calls.\n *\n * Premium (--api-key): adds Convex-hosted vector search (Voyage-Code-3 embeddings)\n * fused with keyword results via Reciprocal Rank Fusion (RRF).\n */\n\nimport type { CompiledFragment, CompiledBlock, CompiledTokenData } from '@fragments-sdk/context/types';\nimport type { SerializedComponentGraph } from '@fragments-sdk/context/graph';\nimport {\n buildComponentIndex,\n buildBlockIndex,\n buildTokenIndex,\n searchComponents as oramaSearchComponents,\n searchBlocks as oramaSearchBlocks,\n searchTokens as oramaSearchTokens,\n type ComponentIndex,\n type BlockIndex,\n type TokenIndex,\n} from './orama-index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Entry kind discriminator — matches the Convex schema */\nexport type EntryKind = 'component' | 'block' | 'token';\n\nexport interface ScoredResult {\n /** Entry name */\n name: string;\n /** What kind of entry (component, block, token) */\n kind: EntryKind;\n /** Rank position (0-indexed) */\n rank: number;\n /** Raw score from the search system */\n score: number;\n}\n\ninterface ConvexSearchResponse {\n results: Array<{\n kind: string;\n name: string;\n score: number;\n description: string;\n category: string;\n }>;\n}\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nconst CONVEX_SEARCH_URL = 'https://combative-jay-834.convex.site/search';\nconst CONVEX_TIMEOUT_MS = 3000;\n\n// ---------------------------------------------------------------------------\n// Vector search via Convex (PREMIUM)\n// ---------------------------------------------------------------------------\n\n/**\n * PREMIUM — Convex-hosted semantic vector search.\n *\n * This function is only called when a valid API key is provided via --api-key.\n * The Convex endpoint is auth-gated (SEARCH_API_KEY env var in Convex dashboard).\n *\n * Re-enablement checklist (for when you're ready to sell premium):\n * 1. Convex endpoint auth is already in place (SEARCH_API_KEY env var)\n * 2. --api-key CLI flag and Authorization header plumbing already wired below\n * 3. To enable for a paying customer: issue them a key matching SEARCH_API_KEY,\n * they add --api-key <key> to their MCP config\n * 4. Optionally add per-key rate limiting in convex/search.ts later\n *\n * @param apiKey - Bearer token passed as Authorization header to Convex\n * @param kind - Optional filter to only search components, blocks, or tokens\n * Returns an empty array if Convex is unreachable (offline, timeout, error, 401).\n */\nexport async function searchConvex(\n query: string,\n apiKey: string,\n limit = 10,\n kind?: EntryKind\n): Promise<ScoredResult[]> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), CONVEX_TIMEOUT_MS);\n\n const response = await fetch(CONVEX_SEARCH_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ query, limit, ...(kind && { kind }) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return [];\n }\n\n const data = (await response.json()) as ConvexSearchResponse;\n\n return data.results.map((r, i) => ({\n name: r.name,\n kind: (r.kind as EntryKind) ?? 'component',\n rank: i,\n score: r.score,\n }));\n } catch {\n // Network error, timeout, or Convex unreachable — silent fallback\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — components\n// ---------------------------------------------------------------------------\n\n/**\n * Score components against a query using BM25 via Orama.\n *\n * If an Orama index is provided (via LocalSearchData.componentIndex),\n * it will be used directly. Otherwise, a temporary index is built on the fly.\n */\nexport function keywordScoreComponents(\n query: string,\n fragments: CompiledFragment[],\n componentIndex?: ComponentIndex,\n): ScoredResult[] {\n const index = componentIndex ?? buildComponentIndex(fragments);\n return oramaSearchComponents(query, index, fragments);\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — blocks\n// ---------------------------------------------------------------------------\n\n/**\n * Score blocks against a query using BM25 via Orama.\n */\nexport function keywordScoreBlocks(\n query: string,\n blocks: CompiledBlock[],\n blockIndex?: BlockIndex,\n): ScoredResult[] {\n const index = blockIndex ?? buildBlockIndex(blocks);\n return oramaSearchBlocks(query, index);\n}\n\n// ---------------------------------------------------------------------------\n// Local BM25 scoring via Orama — tokens\n// ---------------------------------------------------------------------------\n\n/**\n * Score tokens against a query using BM25 via Orama.\n */\nexport function keywordScoreTokens(\n query: string,\n tokenData: CompiledTokenData,\n tokenIndex?: TokenIndex,\n): ScoredResult[] {\n const index = tokenIndex ?? buildTokenIndex(tokenData);\n return oramaSearchTokens(query, index);\n}\n\n// ---------------------------------------------------------------------------\n// Reciprocal Rank Fusion\n// ---------------------------------------------------------------------------\n\n/**\n * Reciprocal Rank Fusion (RRF) — merges multiple ranked result lists\n * into a single ranking using the formula: score = sum(1 / (k + rank))\n */\nfunction reciprocalRankFusion(\n resultSets: Array<{ label: string; results: ScoredResult[] }>,\n k = 60\n): ScoredResult[] {\n // Use kind:name as key to avoid collisions across kinds\n const scoreMap = new Map<string, { score: number; kind: EntryKind; name: string }>();\n\n for (const { results } of resultSets) {\n for (let rank = 0; rank < results.length; rank++) {\n const result = results[rank];\n const key = `${result.kind}:${result.name}`;\n const rrfScore = 1 / (k + rank + 1);\n\n const existing = scoreMap.get(key);\n if (existing) {\n existing.score += rrfScore;\n } else {\n scoreMap.set(key, { score: rrfScore, kind: result.kind, name: result.name });\n }\n }\n }\n\n const fused: ScoredResult[] = [];\n for (const [, { score, kind, name }] of scoreMap) {\n fused.push({ name, kind, rank: 0, score });\n }\n\n fused.sort((a, b) => b.score - a.score);\n fused.forEach((r, i) => { r.rank = i; });\n\n return fused;\n}\n\n// ---------------------------------------------------------------------------\n// Hybrid search (public API)\n// ---------------------------------------------------------------------------\n\n/** Data sources for local keyword scoring */\nexport interface LocalSearchData {\n fragments: CompiledFragment[];\n blocks?: CompiledBlock[];\n tokenData?: CompiledTokenData;\n /** Serialized component graph for neighbor boosting */\n graph?: SerializedComponentGraph;\n /** Pre-built Orama indexes (set at server startup for performance) */\n componentIndex?: ComponentIndex;\n blockIndex?: BlockIndex;\n tokenIndex?: TokenIndex;\n}\n\n/** Options for hybridSearch */\nexport interface HybridSearchOptions {\n /** Max results to return */\n limit?: number;\n /** Filter to a specific entry kind */\n kind?: EntryKind;\n /** Premium API key — when provided, enables Convex vector search + RRF fusion */\n apiKey?: string;\n}\n\n/**\n * Search across components, blocks, and tokens.\n *\n * Default: BM25 scoring via Orama with synonym expansion and field boosting.\n * Premium (apiKey provided): adds Convex vector search fused via RRF.\n *\n * @param kind - Optional filter to restrict results to a specific kind\n */\nexport async function hybridSearch(\n query: string,\n data: LocalSearchData,\n limit = 10,\n kind?: EntryKind,\n apiKey?: string,\n): Promise<ScoredResult[]> {\n // Build local BM25 results based on requested kind(s)\n const keywordResults: ScoredResult[] = [];\n\n if (!kind || kind === 'component') {\n keywordResults.push(...keywordScoreComponents(query, data.fragments, data.componentIndex));\n }\n if ((!kind || kind === 'block') && data.blocks) {\n keywordResults.push(...keywordScoreBlocks(query, data.blocks, data.blockIndex));\n }\n if ((!kind || kind === 'token') && data.tokenData) {\n keywordResults.push(...keywordScoreTokens(query, data.tokenData, data.tokenIndex));\n }\n\n // Re-sort combined keyword results\n keywordResults.sort((a, b) => b.score - a.score);\n keywordResults.forEach((r, i) => { r.rank = i; });\n\n // --- Premium: vector search (only when API key is provided) ---\n if (!apiKey) {\n return keywordResults.slice(0, limit);\n }\n\n const vectorResults = await searchConvex(query, apiKey, limit, kind);\n\n // If vector search returned nothing, just use keyword results\n if (vectorResults.length === 0) {\n return keywordResults.slice(0, limit);\n }\n\n // Build graph neighbor boost list if graph data is available\n const graphBoostResults: ScoredResult[] = [];\n if (data.graph) {\n try {\n const { ComponentGraphEngine, deserializeGraph } = await import('@fragments-sdk/context/graph');\n const graph = deserializeGraph(data.graph);\n const engine = new ComponentGraphEngine(graph);\n\n // Collect top component results from keyword+vector\n const topComponents = [...keywordResults, ...vectorResults]\n .filter(r => r.kind === 'component')\n .slice(0, 5);\n\n // Find graph neighbors of top results\n const neighborSet = new Set<string>();\n for (const result of topComponents) {\n const neighbors = engine.neighbors(result.name, 1);\n for (const n of neighbors.neighbors) {\n if (!neighborSet.has(n.component)) {\n neighborSet.add(n.component);\n graphBoostResults.push({\n name: n.component,\n kind: 'component',\n rank: graphBoostResults.length,\n score: 1, // Will be normalized through RRF\n });\n }\n }\n }\n } catch {\n // Graph boost is best-effort — fail silently\n }\n }\n\n // Fuse with RRF\n const resultSets: Array<{ label: string; results: ScoredResult[] }> = [\n { label: 'vector', results: vectorResults },\n { label: 'keyword', results: keywordResults },\n ];\n\n if (graphBoostResults.length > 0) {\n resultSets.push({ label: 'graph', results: graphBoostResults });\n }\n\n const fused = reciprocalRankFusion(resultSets);\n\n return fused.slice(0, limit);\n}\n","/**\n * Scoring utilities for MCP tool result ranking.\n *\n * Extracted as pure functions for easy testing and reuse across\n * discover, implement, and other search-driven tools.\n */\n\nimport type { CompiledBlock } from '@fragments-sdk/context/types';\nimport type { ScoredResult } from './search.js';\n\n// ---------------------------------------------------------------------------\n// Confidence assignment — ratio-to-max (scale-independent)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimum absolute score floor. If the best result scores below this,\n * results are considered a no-match rather than low-confidence garbage.\n *\n * BM25 scores for a 60-component corpus typically range 10-100+ for real\n * matches (including name-match bonuses of +25 and status bonuses of +5).\n * A maxScore below 5 means no meaningful term overlap was found — only\n * status bonuses and/or minimal synonym noise.\n *\n * Note: this threshold is calibrated for BM25 keyword scores. When hybrid\n * search uses RRF fusion (premium API key), scores are in a different range\n * (~0.01-0.05) and the threshold should be bypassed via a maxScore > 1 guard.\n */\nexport const MINIMUM_SCORE_THRESHOLD = 5;\n\n/**\n * Assign a confidence level based on how a score compares to the best result.\n *\n * Uses ratio-to-max instead of absolute thresholds so the same function works\n * for both keyword scores (8-50+) and RRF scores (0.01-0.02).\n *\n * - high: score >= 70% of maxScore (\"this is almost certainly what you need\")\n * - medium: score >= 40% of maxScore (\"this could be useful\")\n * - low: score < 40% of maxScore (\"tangentially related\")\n */\nexport function assignConfidence(\n score: number,\n maxScore: number,\n): 'high' | 'medium' | 'low' {\n if (maxScore <= 0) return 'low';\n const ratio = score / maxScore;\n if (ratio >= 0.7) return 'high';\n if (ratio >= 0.4) return 'medium';\n return 'low';\n}\n\n/**\n * Check if the best score in a result set meets the minimum quality threshold.\n * Returns true if results are meaningful, false if they're noise.\n */\nexport function meetsMinimumThreshold(maxScore: number): boolean {\n return maxScore >= MINIMUM_SCORE_THRESHOLD;\n}\n\n// ---------------------------------------------------------------------------\n// Levenshtein distance — for fuzzy \"did you mean?\" suggestions\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the Levenshtein edit distance between two strings.\n * Used for suggesting closest component name matches on typos.\n */\nexport function levenshtein(a: string, b: string): number {\n const la = a.length;\n const lb = b.length;\n const dp: number[] = Array.from({ length: lb + 1 }, (_, i) => i);\n\n for (let i = 1; i <= la; i++) {\n let prev = i - 1;\n dp[0] = i;\n for (let j = 1; j <= lb; j++) {\n const temp = dp[j];\n dp[j] = a[i - 1] === b[j - 1]\n ? prev\n : 1 + Math.min(prev, dp[j], dp[j - 1]);\n prev = temp;\n }\n }\n\n return dp[lb];\n}\n\n/**\n * Find the closest matching name from a list, using Levenshtein distance.\n * Returns the closest match if it's within `maxDistance`, or null otherwise.\n */\nexport function findClosestMatch(\n input: string,\n candidates: string[],\n maxDistance = 3,\n): string | null {\n const inputLower = input.toLowerCase();\n let bestMatch: string | null = null;\n let bestDist = maxDistance + 1;\n\n for (const candidate of candidates) {\n const candidateLower = candidate.toLowerCase();\n const dist = levenshtein(inputLower, candidateLower);\n if (dist < bestDist) {\n bestDist = dist;\n bestMatch = candidate;\n } else if (dist === bestDist && bestMatch) {\n // Tie-break: prefer the candidate whose length is closer to input length\n const currentLenDiff = Math.abs(bestMatch.length - input.length);\n const newLenDiff = Math.abs(candidate.length - input.length);\n if (newLenDiff < currentLenDiff) {\n bestMatch = candidate;\n }\n }\n }\n\n return bestDist <= maxDistance ? bestMatch : null;\n}\n\n// ---------------------------------------------------------------------------\n// Block-first component ranking\n// ---------------------------------------------------------------------------\n\n/** Points added per block occurrence (e.g., Card in 3 blocks → +15) */\nexport const BLOCK_BOOST_PER_OCCURRENCE = 5;\n\n/**\n * Count how many blocks each component appears in.\n *\n * Returns a Map<lowercase component name, count>.\n * This is the core signal for block-first ranking: if Card appears in 5/5\n * marketing blocks, it's clearly more important than Sidebar which appears in 0.\n */\nexport function buildBlockComponentFrequency(\n blocks: CompiledBlock[],\n): Map<string, number> {\n const freq = new Map<string, number>();\n for (const block of blocks) {\n for (const comp of block.components) {\n const key = comp.toLowerCase();\n freq.set(key, (freq.get(key) ?? 0) + 1);\n }\n }\n return freq;\n}\n\n/**\n * Boost component search results by how frequently they appear in matching blocks.\n *\n * Mutates scores in-place and re-sorts. Components that appear in more blocks\n * get a proportionally higher boost (freq * BLOCK_BOOST_PER_OCCURRENCE).\n *\n * Returns the mutated+sorted array for convenience.\n */\nexport function boostByBlockFrequency(\n results: ScoredResult[],\n freq: Map<string, number>,\n): ScoredResult[] {\n for (const result of results) {\n const count = freq.get(result.name.toLowerCase()) ?? 0;\n if (count > 0) {\n result.score += count * BLOCK_BOOST_PER_OCCURRENCE;\n }\n }\n results.sort((a, b) => b.score - a.score);\n results.forEach((r, i) => { r.rank = i; });\n return results;\n}\n","/**\n * HTTP-based render/fix service — no Playwright dependency.\n *\n * When a viewer URL is configured (e.g., the Fragments dev server is running),\n * these functions proxy render/fix requests to the viewer's HTTP API.\n * When no viewer is available, they return helpful error messages.\n */\n\nexport interface RenderRequest {\n component: string;\n props?: Record<string, unknown>;\n variant?: string;\n viewport?: { width?: number; height?: number };\n}\n\nexport interface RenderResult {\n screenshot?: string;\n error?: string;\n}\n\nexport interface CompareRequest {\n component: string;\n variant?: string;\n props?: Record<string, unknown>;\n figmaUrl: string;\n threshold?: number;\n}\n\nexport interface CompareResult {\n match?: boolean;\n diffPercentage?: number;\n threshold?: number;\n rendered?: string;\n figma?: string;\n diff?: string;\n figmaUrl?: string;\n changedRegions?: Array<{ x: number; y: number; width: number; height: number }>;\n error?: string;\n suggestion?: string;\n}\n\nexport interface FixRequest {\n component: string;\n variant?: string;\n fixType?: 'token' | 'all';\n}\n\nexport interface FixResult {\n patches: Array<{ file: string; diff: string }>;\n summary: string;\n error?: string;\n}\n\nexport interface A11yRequest {\n component: string;\n variant?: string;\n standard?: 'AA' | 'AAA';\n includeFixPatches?: boolean;\n}\n\nexport interface A11yVariantResult {\n variant: string;\n violations: number;\n passes: number;\n incomplete: number;\n summary: {\n total: number;\n critical: number;\n serious: number;\n moderate: number;\n minor: number;\n };\n violationDetails?: Array<{\n id: string;\n impact: string;\n description: string;\n helpUrl: string;\n nodes: number;\n }>;\n}\n\nexport interface A11yResult {\n component: string;\n results: A11yVariantResult[];\n score: number;\n aaPercent: number;\n aaaPercent: number;\n passed: boolean;\n /** True when axe found no testable elements (e.g., nonexistent variant) */\n emptyAudit?: boolean;\n standard: string;\n error?: string;\n}\n\n/**\n * Render a component via the viewer's HTTP API.\n */\nexport async function renderComponent(\n viewerUrl: string,\n request: RenderRequest\n): Promise<RenderResult> {\n const renderUrl = `${viewerUrl}/fragments/render`;\n\n const response = await fetch(renderUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: request.component,\n props: request.props ?? {},\n variant: request.variant,\n viewport: request.viewport ?? { width: 800, height: 600 },\n }),\n });\n\n return (await response.json()) as RenderResult;\n}\n\n/**\n * Compare a component render against a Figma design via the viewer's HTTP API.\n */\nexport async function compareComponent(\n viewerUrl: string,\n request: CompareRequest\n): Promise<CompareResult> {\n const compareUrl = `${viewerUrl}/fragments/compare`;\n\n const response = await fetch(compareUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n return (await response.json()) as CompareResult;\n}\n\n/**\n * Generate fix patches via the viewer's HTTP API.\n */\nexport async function fixComponent(\n viewerUrl: string,\n request: FixRequest\n): Promise<FixResult> {\n const fixUrl = `${viewerUrl}/fragments/fix`;\n\n const response = await fetch(fixUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n return (await response.json()) as FixResult;\n}\n\n/**\n * Run an accessibility audit on a component via the viewer's HTTP API.\n */\nexport async function auditComponent(\n viewerUrl: string,\n request: A11yRequest\n): Promise<A11yResult> {\n const a11yUrl = `${viewerUrl}/fragments/a11y`;\n\n const response = await fetch(a11yUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: request.component,\n variant: request.variant,\n standard: request.standard,\n includeFixPatches: request.includeFixPatches,\n }),\n });\n\n const raw = (await response.json()) as {\n results: A11yVariantResult[];\n error?: string;\n };\n\n if (raw.error) {\n return {\n component: request.component,\n results: [],\n score: 0,\n aaPercent: 0,\n aaaPercent: 0,\n passed: false,\n standard: request.standard ?? 'AA',\n error: raw.error,\n };\n }\n\n const results = raw.results ?? [];\n const standard = request.standard ?? 'AA';\n\n // Calculate totals\n let totalCritical = 0;\n let totalSerious = 0;\n let totalModerate = 0;\n let totalMinor = 0;\n\n for (const r of results) {\n totalCritical += r.summary.critical;\n totalSerious += r.summary.serious;\n totalModerate += r.summary.moderate;\n totalMinor += r.summary.minor;\n }\n\n // Score: start at 100, subtract per violation\n const deductions =\n totalCritical * 10 +\n totalSerious * 5 +\n totalModerate * 2 +\n totalMinor * 1;\n const score = Math.max(0, 100 - deductions);\n\n // Per-variant compliance: calculate the percentage of variants that pass,\n // not a binary gate. A component with 5 clean variants and 1 with a violation\n // should show ~83% AA compliance, not 0%.\n const variantCount = results.length;\n const aaPassCount = results.filter(r => {\n const critical = r.summary.critical;\n const serious = r.summary.serious;\n return critical === 0 && serious === 0;\n }).length;\n const aaaPassCount = results.filter(r => {\n const total = r.summary.critical + r.summary.serious + r.summary.moderate + r.summary.minor;\n return total === 0;\n }).length;\n // Detect empty audits: if every variant has 0 passes AND 0 violations,\n // axe found no testable elements (e.g., nonexistent variant rendered empty).\n // Report this as an inconclusive result rather than a false pass.\n const totalPasses = results.reduce((sum, r) => sum + r.passes, 0);\n const totalViolations = totalCritical + totalSerious + totalModerate + totalMinor;\n const emptyAudit = results.length > 0 && totalPasses === 0 && totalViolations === 0;\n\n const aaPercent = variantCount > 0 ? Math.round((aaPassCount / variantCount) * 100) : 100;\n const aaaPercent = variantCount > 0 ? Math.round((aaaPassCount / variantCount) * 100) : 100;\n\n // Overall pass/fail uses aggregate totals (matches original behavior for the `passed` field)\n // An empty audit (nothing tested) is NOT a pass\n const aaPass = !emptyAudit && totalCritical === 0 && totalSerious === 0;\n const aaaPass = !emptyAudit && totalViolations === 0;\n\n const passed = standard === 'AAA' ? aaaPass : aaPass;\n\n return {\n component: request.component,\n results,\n score: emptyAudit ? 0 : score,\n aaPercent: emptyAudit ? 0 : aaPercent,\n aaaPercent: emptyAudit ? 0 : aaaPercent,\n ...(emptyAudit && { emptyAudit }),\n passed,\n standard,\n };\n}\n","/**\n * Utility functions for the MCP server.\n *\n * Inlined from @fragments-sdk/cli to avoid pulling in the full CLI dependency.\n */\n\n/**\n * Extract specific fields from an object using dot notation paths.\n * E.g., projectFields(obj, ['meta.name', 'usage.when']) returns { meta: { name: ... }, usage: { when: ... } }\n *\n * @param obj - The source object to extract fields from\n * @param fields - Array of field paths (supports dot notation for nested fields)\n * @returns A new object containing only the requested fields\n */\nexport function projectFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[]\n): Partial<T> {\n if (!fields || fields.length === 0) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n const parts = field.split('.');\n let source: unknown = obj;\n let target = result;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isLast = i === parts.length - 1;\n\n if (source === null || source === undefined || typeof source !== 'object') {\n break;\n }\n\n const sourceObj = source as Record<string, unknown>;\n const value = sourceObj[part];\n\n if (isLast) {\n // Set the final value\n target[part] = value;\n } else {\n // Create nested object if needed\n if (!(part in target)) {\n target[part] = {};\n }\n target = target[part] as Record<string, unknown>;\n source = value;\n }\n }\n }\n\n return result as Partial<T>;\n}\n","/**\n * MCP tool handler for the fragments_graph tool.\n *\n * Dispatches graph queries to the ComponentGraphEngine and formats\n * results as structured markdown/JSON for AI consumption.\n */\n\nimport {\n ComponentGraphEngine,\n deserializeGraph,\n} from '@fragments-sdk/context/graph';\nimport type {\n SerializedComponentGraph,\n GraphEdgeType,\n ComponentGraph,\n} from '@fragments-sdk/context/graph';\nimport type { CompiledBlock } from '@fragments-sdk/context/types';\nimport { findClosestMatch } from './scoring.js';\n\nexport interface GraphToolArgs {\n mode: string;\n component?: string;\n target?: string;\n edgeTypes?: string[];\n maxDepth?: number;\n}\n\nexport function handleGraphTool(\n args: GraphToolArgs,\n serializedGraph: SerializedComponentGraph | undefined,\n blocks?: Record<string, CompiledBlock>,\n componentNames?: string[],\n): { text: string; isError?: boolean } {\n if (!serializedGraph) {\n return {\n text: JSON.stringify({\n error: 'No graph data available. Run `fragments build` to generate the component graph.',\n hint: 'The graph is built automatically during `fragments build` and embedded in fragments.json.',\n }),\n isError: true,\n };\n }\n\n const graph = deserializeGraph(serializedGraph);\n const blockData = blocks\n ? Object.fromEntries(\n Object.entries(blocks).map(([k, v]) => [k, { components: v.components }])\n )\n : undefined;\n const engine = new ComponentGraphEngine(graph, blockData);\n const edgeTypes = args.edgeTypes as GraphEdgeType[] | undefined;\n\n switch (args.mode) {\n case 'health': {\n const health = engine.getHealth();\n const blockCount = blocks ? Object.keys(blocks).length : 0;\n return {\n text: JSON.stringify({\n mode: 'health',\n ...health,\n ...(health.compositionCoverage === 0 && blockCount === 0 && {\n compositionNote: 'No composition blocks defined yet — compositionCoverage will increase as blocks are added',\n }),\n summary: `${health.nodeCount} components, ${health.edgeCount} edges, ${health.connectedComponents.length} island(s), ${health.orphans.length} orphan(s), ${health.compositionCoverage}% in blocks`,\n }),\n };\n }\n\n case 'dependencies': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for dependencies mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const deps = engine.dependencies(args.component, edgeTypes);\n return {\n text: JSON.stringify({\n mode: 'dependencies',\n component: args.component,\n count: deps.length,\n dependencies: deps.map(e => ({\n component: e.target,\n type: e.type,\n weight: e.weight,\n note: e.note,\n provenance: e.provenance,\n })),\n }),\n };\n }\n\n case 'dependents': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for dependents mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const deps = engine.dependents(args.component, edgeTypes);\n return {\n text: JSON.stringify({\n mode: 'dependents',\n component: args.component,\n count: deps.length,\n dependents: deps.map(e => ({\n component: e.source,\n type: e.type,\n weight: e.weight,\n note: e.note,\n provenance: e.provenance,\n })),\n }),\n };\n }\n\n case 'impact': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for impact mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const result = engine.impact(args.component, args.maxDepth ?? 3);\n return {\n text: JSON.stringify({\n mode: 'impact',\n ...result,\n summary: `Changing ${args.component} affects ${result.totalAffected} component(s) and ${result.affectedBlocks.length} block(s)`,\n }),\n };\n }\n\n case 'path': {\n if (!args.component || !args.target) {\n return { text: JSON.stringify({ error: 'component and target are required for path mode' }), isError: true };\n }\n const result = engine.path(args.component, args.target);\n return {\n text: JSON.stringify({\n mode: 'path',\n from: args.component,\n to: args.target,\n ...result,\n edges: result.edges.map(e => ({\n source: e.source,\n target: e.target,\n type: e.type,\n })),\n }),\n };\n }\n\n case 'composition': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for composition mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const tree = engine.composition(args.component);\n return {\n text: JSON.stringify({\n mode: 'composition',\n ...tree,\n }),\n };\n }\n\n case 'alternatives': {\n if (!args.component) {\n return { text: JSON.stringify({ error: 'component is required for alternatives mode' }), isError: true };\n }\n if (!engine.hasNode(args.component)) {\n const closest = componentNames ? findClosestMatch(args.component, componentNames) : null;\n const suggestion = closest ? ` Did you mean \"${closest}\"?` : '';\n return { text: JSON.stringify({ error: `Component \"${args.component}\" not found in graph.${suggestion}` }), isError: true };\n }\n const alts = engine.alternatives(args.component);\n return {\n text: JSON.stringify({\n mode: 'alternatives',\n component: args.component,\n count: alts.length,\n alternatives: alts,\n }),\n };\n }\n\n case 'islands': {\n const islands = engine.islands();\n return {\n text: JSON.stringify({\n mode: 'islands',\n count: islands.length,\n islands: islands.map((island, i) => ({\n id: i + 1,\n size: island.length,\n components: island,\n })),\n }),\n };\n }\n\n default:\n return {\n text: JSON.stringify({\n error: `Unknown mode: \"${args.mode}\". Valid modes: dependencies, dependents, impact, path, composition, alternatives, islands, health`,\n }),\n isError: true,\n };\n }\n}\n","import type {\n CompiledBlock,\n CompiledFragment,\n CompiledFragmentsFile,\n CompiledTokenData,\n} from '@fragments-sdk/context/types';\n\nimport type { LocalSearchData } from './search.js';\nimport type { BlockIndex, ComponentIndex, TokenIndex } from './orama-index.js';\n\ninterface SearchIndexes {\n componentIndex: ComponentIndex | null;\n blockIndex: BlockIndex | null;\n tokenIndex: TokenIndex | null;\n}\n\ninterface BuildSearchDataResult {\n allFragments: CompiledFragment[];\n allBlocks: CompiledBlock[];\n localData: LocalSearchData;\n}\n\nexport function normalizeFilter(value: string | undefined): string | undefined {\n const normalized = value?.trim().toLowerCase();\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\nexport function categoryMatches(\n category: string | undefined,\n categoryFilter: string | undefined\n): boolean {\n if (!categoryFilter) return true;\n return normalizeFilter(category) === categoryFilter;\n}\n\nexport function buildLocalSearchData(\n data: Pick<CompiledFragmentsFile, 'fragments' | 'blocks' | 'recipes' | 'tokens' | 'graph'>,\n indexes: SearchIndexes\n): BuildSearchDataResult {\n const allFragments = Object.values(data.fragments);\n const allBlocks = Object.values(data.blocks ?? data.recipes ?? {});\n\n const localData: LocalSearchData = {\n fragments: allFragments,\n blocks: allBlocks,\n tokenData: data.tokens as CompiledTokenData | undefined,\n graph: data.graph,\n componentIndex: indexes.componentIndex ?? undefined,\n blockIndex: indexes.blockIndex ?? undefined,\n tokenIndex: indexes.tokenIndex ?? undefined,\n };\n\n return { allFragments, allBlocks, localData };\n}\n\nexport async function buildImportStatements(\n components: string[],\n resolvePackageName: (component: string) => Promise<string>\n): Promise<string[]> {\n const grouped = new Map<string, string[]>();\n\n for (const component of components) {\n if (!component) continue;\n\n const packageName = await resolvePackageName(component);\n const existing = grouped.get(packageName);\n\n if (!existing) {\n grouped.set(packageName, [component]);\n continue;\n }\n\n if (!existing.includes(component)) {\n existing.push(component);\n }\n }\n\n return Array.from(grouped.entries()).map(\n ([packageName, componentNames]) =>\n `import { ${componentNames.join(', ')} } from '${packageName}';`\n );\n}\n\nexport function limitTokensPerCategory<T>(\n categories: Record<string, T[]>,\n limit: number | undefined\n): { categories: Record<string, T[]>; total: number } {\n if (limit === undefined) {\n return {\n categories,\n total: Object.values(categories).reduce((sum, tokens) => sum + tokens.length, 0),\n };\n }\n\n const limited: Record<string, T[]> = {};\n let total = 0;\n\n for (const [category, tokens] of Object.entries(categories)) {\n const sliced = tokens.slice(0, limit);\n if (sliced.length === 0) continue;\n limited[category] = sliced;\n total += sliced.length;\n }\n\n return { categories: limited, total };\n}\n","import { readFileSync } from 'node:fs';\n\ninterface PackageJson {\n version?: string;\n}\n\nfunction readPackageVersion(): string {\n try {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf-8');\n const pkg = JSON.parse(raw) as PackageJson;\n return pkg.version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nexport const MCP_SERVER_VERSION = readPackageVersion();\n"],"mappings":"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","names":["existsSync","readFileSync","join","ComponentGraphEngine","deserializeGraph","readFileSync","join","existsSync","readFileSync","search","fragments"]}