@fridaplatform-stk/figma2frida-mcp 1.0.5 → 1.0.6
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/README.md +4 -4
- package/dist/figma2frida.js +53 -18
- package/dist/figma2frida.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
Your AI assistant gets four specialized tools:
|
|
18
18
|
|
|
19
|
-
1. **`
|
|
20
|
-
2. **`
|
|
21
|
-
3. **`
|
|
22
|
-
4. **`
|
|
19
|
+
1. **`analyze_design`** - Get design context and generated code from Figma *(main tool)*
|
|
20
|
+
2. **`analyze_frame`** - Screenshot of current Figma selection for visual reference and UI analysis
|
|
21
|
+
3. **`analyze_frame_extraction`** - Screenshot + metadata + design context; then call `get_components_from_library`
|
|
22
|
+
4. **`get_components_from_library`** - Search your design system (Pinecone + Frida AI) by query
|
|
23
23
|
|
|
24
24
|
## 🔄 How It Works
|
|
25
25
|
|
package/dist/figma2frida.js
CHANGED
|
@@ -28,6 +28,16 @@ var writeToLog = (level, message, ...args) => {
|
|
|
28
28
|
console.log(fullMessage);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
+
var PUBLIC_PREFIX = "FIGMA2FRIDA:";
|
|
32
|
+
var writePublic = (message) => {
|
|
33
|
+
const line = `${PUBLIC_PREFIX} ${message}
|
|
34
|
+
`;
|
|
35
|
+
if (isStdioMode) {
|
|
36
|
+
process.stderr.write(line);
|
|
37
|
+
} else {
|
|
38
|
+
console.error(line);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
31
41
|
var logger = {
|
|
32
42
|
debug: (message, ...args) => {
|
|
33
43
|
if (getLogLevel() <= 0 /* DEBUG */) {
|
|
@@ -48,6 +58,10 @@ var logger = {
|
|
|
48
58
|
if (getLogLevel() <= 3 /* ERROR */) {
|
|
49
59
|
writeToLog("ERROR", message, ...args);
|
|
50
60
|
}
|
|
61
|
+
},
|
|
62
|
+
/** User-facing message; always written to stderr with FIGMA2FRIDA: prefix. */
|
|
63
|
+
public: (message) => {
|
|
64
|
+
writePublic(message);
|
|
51
65
|
}
|
|
52
66
|
};
|
|
53
67
|
|
|
@@ -1874,9 +1888,9 @@ ${match.technical || "No technical documentation available"}
|
|
|
1874
1888
|
};
|
|
1875
1889
|
|
|
1876
1890
|
// src/figma2frida/services/auth/token-validator.ts
|
|
1877
|
-
var VALIDATION_URL = "https://us-central1-figma2frida-mcp.cloudfunctions.net/
|
|
1878
|
-
async function
|
|
1879
|
-
logger.info("\u{1F510}
|
|
1891
|
+
var VALIDATION_URL = "https://us-central1-figma2frida-mcp.cloudfunctions.net/authenticateMcpLogin";
|
|
1892
|
+
async function authenticateMcpLogin(llmopsApiKey, projectId) {
|
|
1893
|
+
logger.info("\u{1F510} Authenticating MCP login...");
|
|
1880
1894
|
try {
|
|
1881
1895
|
const response = await fetch(VALIDATION_URL, {
|
|
1882
1896
|
method: "POST",
|
|
@@ -1885,49 +1899,67 @@ async function validateFridaApiToken(apiToken) {
|
|
|
1885
1899
|
},
|
|
1886
1900
|
body: JSON.stringify({
|
|
1887
1901
|
data: {
|
|
1888
|
-
llmopsApiKey
|
|
1902
|
+
llmopsApiKey,
|
|
1903
|
+
projectId
|
|
1889
1904
|
}
|
|
1890
1905
|
})
|
|
1891
1906
|
});
|
|
1892
1907
|
const responseData = await response.json();
|
|
1893
1908
|
if (response.ok && "result" in responseData && responseData.result?.valid === true) {
|
|
1894
|
-
logger.info(
|
|
1909
|
+
logger.info(
|
|
1910
|
+
`\u2705 ${responseData.result.message || "API token is valid"}`
|
|
1911
|
+
);
|
|
1895
1912
|
return;
|
|
1896
1913
|
}
|
|
1897
1914
|
if ("error" in responseData) {
|
|
1898
1915
|
const error = responseData.error;
|
|
1899
1916
|
const errorMessage = error.message || "Unknown error";
|
|
1900
1917
|
const errorStatus = error.status || "UNKNOWN";
|
|
1901
|
-
logger.error(`\u274C
|
|
1918
|
+
logger.error(`\u274C MCP login authentication failed: ${errorMessage}`);
|
|
1902
1919
|
logger.error(` Status: ${errorStatus}`);
|
|
1903
1920
|
if (errorStatus === "RESOURCE_EXHAUSTED") {
|
|
1904
1921
|
logger.error(" Rate limit exceeded. Please try again later.");
|
|
1905
1922
|
} else if (errorStatus === "NOT_FOUND") {
|
|
1906
|
-
logger.error("
|
|
1923
|
+
logger.error(" Project not found. Please check your project ID.");
|
|
1907
1924
|
} else if (errorStatus === "PERMISSION_DENIED") {
|
|
1908
|
-
logger.error(
|
|
1925
|
+
logger.error(
|
|
1926
|
+
" Invalid API token. Please check your token and try again."
|
|
1927
|
+
);
|
|
1909
1928
|
}
|
|
1910
|
-
throw new Error(
|
|
1929
|
+
throw new Error(
|
|
1930
|
+
`Authentication failed: ${errorMessage} (${errorStatus})`
|
|
1931
|
+
);
|
|
1911
1932
|
}
|
|
1912
|
-
logger.error(
|
|
1913
|
-
|
|
1933
|
+
logger.error(
|
|
1934
|
+
`\u274C Unexpected authentication response format: ${JSON.stringify(responseData)}`
|
|
1935
|
+
);
|
|
1936
|
+
throw new Error("Unexpected authentication response format");
|
|
1914
1937
|
} catch (error) {
|
|
1915
|
-
if (error instanceof Error && error.message.startsWith("
|
|
1938
|
+
if (error instanceof Error && error.message.startsWith("Authentication failed:")) {
|
|
1916
1939
|
throw error;
|
|
1917
1940
|
}
|
|
1918
|
-
logger.error(
|
|
1941
|
+
logger.error(
|
|
1942
|
+
"\u274C Failed to authenticate MCP login:",
|
|
1943
|
+
error instanceof Error ? error.message : String(error)
|
|
1944
|
+
);
|
|
1919
1945
|
if (error instanceof Error) {
|
|
1920
1946
|
if (error.message.includes("fetch failed") || error.message.includes("ECONNREFUSED")) {
|
|
1921
1947
|
logger.error(" Network error: Could not reach validation service.");
|
|
1922
1948
|
logger.error(" Please check your internet connection and try again.");
|
|
1923
1949
|
throw new Error("Network error: Could not reach validation service");
|
|
1924
1950
|
} else if (error.message.includes("timeout")) {
|
|
1925
|
-
logger.error(
|
|
1951
|
+
logger.error(
|
|
1952
|
+
" Request timeout: Validation service did not respond in time."
|
|
1953
|
+
);
|
|
1926
1954
|
logger.error(" Please try again later.");
|
|
1927
|
-
throw new Error(
|
|
1955
|
+
throw new Error(
|
|
1956
|
+
"Request timeout: Validation service did not respond in time"
|
|
1957
|
+
);
|
|
1928
1958
|
}
|
|
1929
1959
|
}
|
|
1930
|
-
throw new Error(
|
|
1960
|
+
throw new Error(
|
|
1961
|
+
`Authentication failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1962
|
+
);
|
|
1931
1963
|
}
|
|
1932
1964
|
}
|
|
1933
1965
|
|
|
@@ -2247,7 +2279,7 @@ async function filterComponentsWithFrida(options) {
|
|
|
2247
2279
|
}
|
|
2248
2280
|
|
|
2249
2281
|
// src/figma2frida/figma2frida.ts
|
|
2250
|
-
var ENVIRONMENT = "
|
|
2282
|
+
var ENVIRONMENT = "production";
|
|
2251
2283
|
process.env.NODE_ENV = ENVIRONMENT;
|
|
2252
2284
|
var __filename = fileURLToPath(import.meta.url);
|
|
2253
2285
|
var __dirname = dirname(__filename);
|
|
@@ -2305,9 +2337,12 @@ if (!FRIDA_TOKEN || FRIDA_TOKEN === "" || FRIDA_TOKEN === "your_api_token_here")
|
|
|
2305
2337
|
process.env.FRIDA_BEARER_TOKEN = FRIDA_TOKEN;
|
|
2306
2338
|
logger.debug(`FRIDA_API_TOKEN: ${FRIDA_TOKEN.substring(0, 8)}... (hidden)`);
|
|
2307
2339
|
try {
|
|
2308
|
-
await
|
|
2340
|
+
await authenticateMcpLogin(FRIDA_TOKEN, argv.projectId);
|
|
2309
2341
|
} catch (error) {
|
|
2310
2342
|
logger.error("\u274C SHUTDOWN: Authentication failed. MCP server cannot start without valid token.");
|
|
2343
|
+
logger.public(
|
|
2344
|
+
`\u274C ${error instanceof Error ? error.message : String(error)}`
|
|
2345
|
+
);
|
|
2311
2346
|
process.exit(1);
|
|
2312
2347
|
}
|
|
2313
2348
|
var HTTP_STREAM = process.env.HTTP_STREAM === "true" || process.env.HTTP_STREAM === "1";
|
package/dist/figma2frida.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/utils/design-query-extractor/metadata-extractor-simpler.ts","../src/figma2frida/utils/design-query-extractor/design-context-extractor.ts","../src/figma2frida/utils/design-query-extractor/query-builder.ts","../src/figma2frida/utils/design-query-extractor/index.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/services/auth/token-validator.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/handlers/library-filter-handler.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Figma MCP Proxy Server\n * \n * Simple wrapper around official Figma Desktop MCP.\n * \n * Tools:\n * 1. test_figma_connection - Get a screenshot to verify connection\n * 2. figma_get_design_context - Get design data and generated code from Figma\n */\n\n// ============================================================================\n// IMPORTS (before environment setup)\n// ============================================================================\nimport { z } from \"zod\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { FastMCP, type ContentResult, type Content } from \"fastmcp\";\nimport { createRequire } from \"module\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// ENVIRONMENT CONFIGURATION (set before logger import)\n// ============================================================================\nconst ENVIRONMENT = \"development\"; // Change mode to \"production\" / \"development\"\nprocess.env.NODE_ENV = ENVIRONMENT; // Set BEFORE importing logger\n\n// Now import logger (it will read NODE_ENV correctly)\nimport { logger } from \"./utils/logger.js\";\nimport { FigmaClient } from \"./clients/figma-client.js\";\n// import { FigmaDesignContextResult } from \"./clients/figma-client.js\";\n// import { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\n// import { ComponentExtractor } from \"./utils/component-extractor.js\";\n// import { ComponentLookupService } from \"./services/component-lookup.js\";\n// import type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor/index.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.js\";\nimport { validateFridaApiToken } from \"./services/auth/token-validator.js\";\nimport { filterComponentsWithFrida } from \"./handlers/library-filter-handler.js\";\n\n// ============================================================================\n// VERSION INFO\n// ============================================================================\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst require = createRequire(import.meta.url);\n// When running from dist/figma2frida.js, __dirname is dist/, so go up one level to find package.json\nconst packageJson = require(join(__dirname, \"../package.json\"));\nconst MCP_VERSION = packageJson.version;\nconst LOCAL_VERSION = \"1.0.1\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${LOCAL_VERSION}) [${ENVIRONMENT}]`);\nlogger.info(`Transport: ${process.env.HTTP_STREAM === \"true\" ? \"HTTP Stream\" : \"stdio\"}`);\nlogger.info(`Node.js: ${process.version}`);\n\n// ============================================================================\n// HARDCODED CONFIGURATION - Set process.env variables\n// ============================================================================\nlogger.debug(\"Loading hardcoded configuration...\");\n\n// Pinecone Configuration\nprocess.env.PINECONE_INDEX = \"figma2frida\";\nprocess.env.PINECONE_MIN_SCORE = \"0.4\";\nprocess.env.PINECONE_TOP_K = \"12\";\nprocess.env.FRIDA_PINECONE_PROXY_URL = \"https://azf-frida-pinecone-proxy.azurewebsites.net\";\n\n// Frida AI Configuration\n// FRIDA_BEARER_TOKEN is now set from CLI argument (see below)\nprocess.env.FRIDA_API_URL = \"https://frida-llm-api.azurewebsites.net/v1/responses\";\nprocess.env.FRIDA_EMBEDDING_URL = \"https://frida-llm-api.azurewebsites.net/v1/embeddings\";\nprocess.env.FRIDA_EMBEDDING_MODEL = \"text-embedding-ada-002\";\nprocess.env.FRIDA_MODEL = \"gpt-5.1-codex\";\nprocess.env.FRIDA_MAX_TOKENS = \"9000\";\n\n// Server Configuration\nprocess.env.HTTP_STREAM = \"false\"; // Set to \"true\" for HTTP mode, \"false\" for stdio\nprocess.env.PORT = \"8080\";\n\n// Log configuration (only in debug mode - hide sensitive values in production)\nlogger.debug(`PINECONE_INDEX: ${process.env.PINECONE_INDEX}`);\nlogger.debug(`PINECONE_MIN_SCORE: ${process.env.PINECONE_MIN_SCORE}`);\nlogger.debug(`PINECONE_TOP_K: ${process.env.PINECONE_TOP_K}`);\nlogger.debug(`FRIDA_PINECONE_PROXY_URL: ${process.env.FRIDA_PINECONE_PROXY_URL}`);\nlogger.debug(`FRIDA_API_URL: ${process.env.FRIDA_API_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_URL: ${process.env.FRIDA_EMBEDDING_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_MODEL: ${process.env.FRIDA_EMBEDDING_MODEL}`);\nlogger.debug(`FRIDA_MODEL: ${process.env.FRIDA_MODEL}`);\nlogger.debug(`FRIDA_MAX_TOKENS: ${process.env.FRIDA_MAX_TOKENS}`);\nlogger.debug(`HTTP_STREAM: ${process.env.HTTP_STREAM}`);\nlogger.debug(`PORT: ${process.env.PORT}`);\nlogger.info(\"Configuration loaded\");\n\n// Parse command-line arguments - PINECONE_NAMESPACE and FRIDA_API_TOKEN as parameters\nconst argv = yargs(hideBin(process.argv))\n .option(\"project-id\", {\n type: \"string\",\n description: \"Pinecone namespace (required for component search)\",\n demandOption: true,\n })\n .option(\"frida-api-token\", {\n type: \"string\",\n description: \"Frida API token for authentication\",\n demandOption: true,\n })\n .parseSync();\n\n// Store and validate namespace from CLI\nconst PINECONE_NAMESPACE = argv.projectId?.trim();\nif (!PINECONE_NAMESPACE || PINECONE_NAMESPACE === \"\" || PINECONE_NAMESPACE === \"your_namespace_here\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --project-id. This argument is required for Pinecone search.\");\n process.exit(1);\n}\nlogger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE} (from CLI)`);\n\n// Validate and set FRIDA_BEARER_TOKEN from CLI argument\nconst FRIDA_TOKEN = argv.fridaApiToken?.trim();\nif (!FRIDA_TOKEN || FRIDA_TOKEN === \"\" || FRIDA_TOKEN === \"your_api_token_here\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --frida-api-token. This token is required for authentication.\");\n process.exit(1);\n}\n\nprocess.env.FRIDA_BEARER_TOKEN = FRIDA_TOKEN;\nlogger.debug(`FRIDA_API_TOKEN: ${FRIDA_TOKEN.substring(0, 8)}... (hidden)`);\n\n// ============================================================================\n// FIREBASE TOKEN VALIDATION\n// ============================================================================\n// Validate token before proceeding\ntry {\n await validateFridaApiToken(FRIDA_TOKEN);\n} catch (error) {\n logger.error(\"❌ SHUTDOWN: Authentication failed. MCP server cannot start without valid token.\");\n process.exit(1);\n}\n\n// Read HTTP_STREAM and PORT from environment variables (.env file)\nconst HTTP_STREAM = process.env.HTTP_STREAM === \"true\" || process.env.HTTP_STREAM === \"1\";\nconst PORT = parseInt(process.env.PORT || \"8080\", 10);\n\n\nconst server = new FastMCP({\n instructions: `You are a Figma design developer. Use the available tools to analyze Figma designs.`,\n name: \"figma2frida_mcp\",\n version: MCP_VERSION,\n});\n\n// Initialize Figma MCP client\nlogger.debug(\"Initializing Figma Client...\");\nconst figmaClient = new FigmaClient(\"http://127.0.0.1:3845/sse\");\nlogger.debug(\"Figma Client object created\");\n\n// Connect to Figma MCP on startup\nlet figmaConnected = false;\nlogger.debug(\"Starting initial connection attempt to Figma MCP (non-blocking)...\");\n\nconst connectionStartTime = Date.now();\nfigmaClient\n .connect()\n .then(() => {\n const connectionTime = Date.now() - connectionStartTime;\n figmaConnected = true;\n logger.debug(`Connected to Figma MCP (${connectionTime}ms)`);\n })\n .catch((error) => {\n const connectionTime = Date.now() - connectionStartTime;\n logger.warn(`Failed to connect to Figma MCP (${connectionTime}ms)`);\n logger.debug(\"Error type:\", error?.constructor?.name || typeof error);\n logger.debug(\"Error message:\", error instanceof Error ? error.message : String(error));\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(\"Error code:\", errorObj.code);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n logger.warn(\"Make sure Figma Desktop is running with MCP enabled at http://127.0.0.1:3845/sse\");\n logger.debug(\"Tools will attempt to reconnect when called\");\n });\n\n\n// TOOL 1: Get Design Context (Design Data and Generated Code)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_design\",\n description: `Get design context from a Figma node including design data and generated code.\n\n**What this does:**\n- Fetches design data and generated code from Figma\n- Returns React/TypeScript code based on the Figma design\n- Includes design tokens and styling information\n\n**Output:**\n- Generated React/TypeScript code\n- Design tokens and styles\n- Design structure information\n\n**Usage:**\n- Set withLibrarySearch to enable component library search flow (default: false)\n\n**Input:**\njson\n{\n \"withLibrarySearch\": false\n}`,\n annotations: {\n title: \"Analyze Design\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n withLibrarySearch: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Enable component library search flow (default: false). When true will trigger analyze_frame_extraction, when false call analyze_frame.\"),\n }),\n execute: async (args, _context) => {\n try {\n const withLibrarySearch = args.withLibrarySearch ?? false;\n logger.debug(`withLibrarySearch: ${withLibrarySearch}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const designContext = await figmaClient.getDesignContext();\n\n if (!designContext.content || designContext.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No design context returned\" }],\n };\n return result;\n }\n\n // Add mandatory workflow instruction - conditionally based on withLibrarySearch\n const workflowInstruction: Content = {\n type: \"text\" as const,\n text: `**MANDATORY NEXT STEP - YOU MUST COMPLETE:**\n\nAfter receiving this design context, you **MUST** call the tool ${withLibrarySearch ? '`analyze_frame_extraction`' : '`analyze_frame`'} to get the visual reference and keywords.\n`,\n };\n\n return {\n content: [...(designContext.content as Content[]), workflowInstruction],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get design context:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get design context: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n// TOOL 2: Get Screenshot (Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame\",\n description: `Get a screenshot of a Figma node for visual reference with UI element analysis.`,\n annotations: {\n title: \"Analyze Frame\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async (_context) => {\n try {\n // logger.debug(`Tool called with nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot();\n\n if (!screenshot.content || screenshot.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n };\n return result;\n }\n\n // Add instruction for AI to analyze the image and provide UI elements list\n const analysisInstruction: Content = {\n type: \"text\" as const,\n text: `**Screenshot Retrieved**\n\nYou **MUST** analyze the screenshot image above and generate pixel perfect code to the Figma design.\n\n**Output:**\nGenerate complete, pixel perfect code that visually matches the screenshot with pixel-perfect accuracy. The generated code should be indistinguishable from the design when rendered.\n\n**What to Identify:**\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars\n`,\n };\n\n return {\n content: [analysisInstruction, ...(screenshot.content as Content[])],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get screenshot:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get screenshot: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 2: FIGMA SUGGEST COMPONENTS\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL 3: Figma Extract Components: Analyze All Extracted (Frame + Metadata + Design) and get components from library\n// From already having a screen I want to suggest components from the library that fit. Will call get_components_from_library.\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame_extraction\",\n description: `Analyze all data from frame and extract to identify components and UI elements in parallel and return all results combined.\n\n**What this does:**\n- Executes tools 1 (screenshot), 2 (metadata), and 3 (design context) concurrently\n- Returns everything in one response: visual reference, structure, and generated code\n\n**Output:**\n- Keywords extracted from figma metadata and design context.\n\n**Input:**\njson\n{\n}\n`,\n annotations: {\n title: \"Analyze All Extracted\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async ( _context) => {\n try {\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n } as ContentResult;\n }\n\n\n const [screenshot, metadata, designContext] = await Promise.all([\n figmaClient.getScreenshot(),\n figmaClient.getMetadata(),\n figmaClient.getDesignContext(),\n ]);\n\n // Extract queries from metadata and design context\n const queryExtractor = new DesignQueryExtractor();\n\n // Extract query from metadata (using metadata-specific extraction)\n let metadataQuery = \"UI component\";\n try {\n // Use metadata-specific extraction method\n const metadataAsDesignContext = {\n content: metadata.content || []\n };\n metadataQuery = queryExtractor.extractQueryFromMetadata(metadataAsDesignContext);\n } catch (error) {\n logger.warn(\"Failed to extract query from metadata:\", error instanceof Error ? error.message : String(error));\n }\n\n // Extract query from design context\n let designContextQuery = \"UI component\";\n try {\n designContextQuery = queryExtractor.extractQuery(designContext, \"UI component\");\n } catch (error) {\n logger.warn(\"Failed to extract query from design context:\", error instanceof Error ? error.message : String(error));\n }\n\n const combined: Content[] = [];\n\n // Add screenshot first (needed for analysis)\n if (screenshot.content?.length) {\n combined.push(...(screenshot.content as Content[]));\n }\n\n // Add instruction to analyze screenshot and create description\n combined.push({\n type: \"text\" as const,\n text: `## 2. Frame Description\\n\\nYou **MUST** analyze the screenshot image above and identify all components and UI elements visible in the Figma frame.\\n\\n**What to Identify:**\\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars.`,\n });\n\n combined.push({\n type: \"text\" as const,\n text: `\n**MANDATORY NEXT STEP — YOU MUST COMPLETE:**\n\nAfter receiving this analyze_frame_extraction output, you **MUST** call the tool \\`get_components_from_library\\` with a \\`query\\` that describes the UI elements, components, or patterns from the design above (a description of the components found in the UI\").\n\n**Required call:**\n\\`\\`\\`json\n{\n \"query\": \"your description query of the components and UI elements found in the UI. MANDATORY: MUST Include '${metadataQuery}' and '${designContextQuery}' \"\n}\n`,\n });\n\n return { content: combined } as ContentResult;\n } catch (error) {\n logger.error(\"analyze_frame_extraction failed:\", error instanceof Error ? error.message : String(error));\n return {\n content: [{\n type: \"text\" as const,\n text: `❌ analyze_frame_extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n }],\n } as ContentResult;\n }\n },\n});\n\n// ============================================================================\n// TOOL 4: Get Components From Library BY Query\n// ============================================================================\n\nserver.addTool({\n name: \"get_components_from_library\",\n description: `Get components from library.`,\n annotations: {\n title: \"Get Components From Library\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n query: z\n .string()\n .describe(\"User query text to search for components in the library.\"),\n }),\n execute: async (args, _context) => {\n try {\n logger.debug(\"get_components_from_library called\");\n logger.debug(`query: ${args.query}`);\n\n // Create PineconeSearchService instance with namespace\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n\n // Search for components\n const searchResults = await searchService.search(args.query);\n\n // Filter components using Frida AI (if enabled)\n const { filteredResults } = await filterComponentsWithFrida({\n query: args.query,\n searchResults,\n });\n\n // Format results using Formatters\n const formattedResults = Formatters.toMarkdown(filteredResults);\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: formattedResults,\n },\n ],\n };\n } catch (error) {\n logger.error(\"get_components_from_library error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n };\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 3: IMPROVE LAYOUT AND DESIGN\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL: Improve Layout — Screenshot + refine generated code to match frame UI\n// ============================================================================\n\n// server.addTool({\n// name: \"improve_layout\",\n// description: `Get a screenshot of the Figma frame and improve the already generated code to look more like the frame UI.\n\n// **What this does:**\n// - Returns the screenshot image of the selected Figma node\n// - Instructs you to refine the existing generated code so it visually matches the frame better (spacing, alignment, typography, colors, etc.)\n\n// **When to use:**\n// - After you have generated code from \\`analyze_design\\` or \\`analyze_frame_extraction\\`\n// - When the output doesn't quite match the Figma design and you want to improve it\n\n// **Output:**\n// - Screenshot image\n// - Instruction to improve the code to match the frame UI\n\n// **Usage:**\n// - Provide a nodeId (e.g., \"315-2920\") or leave empty for current Figma selection\n\n// **Example:**\n// \\`\\`\\`json\n// {\n// \"nodeId\": \"315-2920\"\n// }\n// \\`\\`\\``,\n// annotations: {\n// title: \"Improve Layout\",\n// readOnlyHint: true,\n// openWorldHint: false,\n// },\n// parameters: z.object({\n// nodeId: z\n// .string()\n// .optional()\n// .describe('Figma node ID (e.g., \"315-2920\"). Leave empty for current selection.'),\n// }),\n// execute: async (args, _context) => {\n// try {\n// logger.debug(`improve_layout called with nodeId: ${args.nodeId ?? \"current selection\"}`);\n// logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n// if (!figmaConnected) {\n// logger.warn(\"Early return: figmaConnected is false\");\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n// }],\n// } as ContentResult;\n// }\n\n// logger.debug(\"Calling figmaClient.getScreenshot() for improve_layout...\");\n// const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n// if (!screenshot.content || screenshot.content.length === 0) {\n// return {\n// content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n// } as ContentResult;\n// }\n\n// const instruction: Content = {\n// type: \"text\" as const,\n// text: `**Improve Layout**\n\n// You **MUST** use the screenshot image above as the visual reference. Improve the already generated code so it looks more like the frame UI.\n\n// **What to refine:**\n// - Spacing, padding, and margins\n// - Alignment and layout\n// - Typography (font sizes, weights, line height)\n// - Colors and contrast\n// - Border radius, shadows, and other visual details\n// - Any mismatch between the code output and the Figma design\n\n// Output the improved code.`,\n// };\n\n// return {\n// content: [instruction, ...(screenshot.content as Content[])],\n// } as ContentResult;\n// } catch (error) {\n// logger.error(\"improve_layout failed:\", error instanceof Error ? error.message : String(error));\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: `❌ improve_layout failed: ${error instanceof Error ? error.message : String(error)}`,\n// }],\n// } as ContentResult;\n// }\n// },\n// });\n\n\n\n// ============================================================================\n// Start Server\n// ============================================================================\n\nif (HTTP_STREAM) {\n server.start({\n httpStream: {\n port: PORT,\n },\n transportType: \"httpStream\",\n });\n\n logger.info(\"Figma Proxy MCP Server running on HTTP Stream!\");\n logger.info(`Endpoint: http://localhost:${PORT}/mcp`);\n logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE || \"not set (use --project-id)\"}`);\n logger.debug(`\nTest with curl:\ncurl -X POST http://localhost:${PORT}/mcp \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'\n`);\n} else {\n server.start({ transportType: \"stdio\" });\n logger.info(\"Started with stdio transport (for MCP clients)\");\n}\n","/**\n * Structured Logger Utility\n * Provides leveled logging with environment-based filtering\n * \n * IMPORTANT: In stdio mode, all logs must go to stderr to avoid interfering\n * with MCP's JSON-RPC protocol on stdout.\n */\n\nenum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n SILENT = 4,\n}\n\n/**\n * Gets the current log level dynamically.\n * This ensures it picks up changes to process.env.NODE_ENV made after import\n * (solving ESM hoisting issues).\n */\nfunction getLogLevel(): LogLevel {\n const isVerbose = process.argv.includes(\"--verbose\") || process.env.DEBUG === \"true\";\n const isProduction = process.env.NODE_ENV === \"production\";\n\n if (isProduction && !isVerbose) {\n return LogLevel.SILENT; // Production: No logs at all\n }\n \n // Development or Verbose: Show everything\n return LogLevel.DEBUG; \n}\n\n// Detect if we're in stdio mode (MCP uses stdout for JSON-RPC)\n// HTTP_STREAM is set in process.env before this module loads\nconst isStdioMode = process.env.HTTP_STREAM !== \"true\" && process.env.HTTP_STREAM !== \"1\";\n\n// Helper to write to stderr in stdio mode, stdout otherwise\nconst writeToLog = (level: string, message: string, ...args: any[]) => {\n const fullMessage = args.length > 0 \n ? `[${level}] ${message} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`\n : `[${level}] ${message}`;\n \n if (isStdioMode) {\n process.stderr.write(`${fullMessage}\\n`);\n } else {\n console.log(fullMessage);\n }\n};\n\nexport const logger = {\n debug: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.DEBUG) {\n writeToLog(\"DEBUG\", message, ...args);\n }\n },\n info: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.INFO) {\n writeToLog(\"INFO\", message, ...args);\n }\n },\n warn: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.WARN) {\n writeToLog(\"WARN\", message, ...args);\n }\n },\n error: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.ERROR) {\n writeToLog(\"ERROR\", message, ...args);\n }\n },\n};\n\n","/**\n * Figma MCP Client Wrapper\n * Connects to official Figma Desktop MCP via SSE\n */\n\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FigmaDesignContextResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaScreenshotResult {\n content: Array<{\n type: string;\n data?: string;\n mimeType?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaMetadataResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\n/**\n * Client for communicating with official Figma Desktop MCP\n */\nexport class FigmaClient {\n private client: Client | null = null;\n private connected: boolean = false;\n private figmaUrl: string;\n\n constructor(figmaUrl: string = \"http://127.0.0.1:3845/sse\") {\n this.figmaUrl = figmaUrl;\n }\n\n /**\n * Connect to Figma MCP server\n */\n async connect(retries: number = 3): Promise<void> {\n if (this.connected && this.client) {\n logger.debug(\"Already connected, skipping connection attempt\");\n return;\n }\n\n logger.debug(\"Starting connection attempt\");\n logger.debug(`URL: ${this.figmaUrl}`);\n logger.debug(`Max retries: ${retries}`);\n logger.debug(`Current status: connected=${this.connected}, client=${!!this.client}`);\n\n for (let attempt = 0; attempt < retries; attempt++) {\n const attemptStartTime = Date.now();\n logger.debug(`Attempt ${attempt + 1}/${retries} starting...`);\n\n try {\n logger.debug(\"Creating MCP Client object...\");\n this.client = new Client(\n {\n name: \"figma-proxy-client\",\n version: \"1.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n );\n logger.debug(\"Client object created\");\n\n logger.debug(`Creating SSE Transport for: ${this.figmaUrl}`);\n const transport = new SSEClientTransport(new URL(this.figmaUrl));\n logger.debug(\"Transport object created\");\n\n logger.debug(\"Attempting to connect...\");\n const connectStartTime = Date.now();\n await this.client.connect(transport);\n const connectTime = Date.now() - connectStartTime;\n logger.debug(`Connection established in ${connectTime}ms`);\n\n this.connected = true;\n const totalTime = Date.now() - attemptStartTime;\n\n logger.debug(`Connected to Figma MCP (${totalTime}ms)`);\n return;\n } catch (error) {\n const attemptTime = Date.now() - attemptStartTime;\n logger.debug(`Connection attempt ${attempt + 1}/${retries} FAILED (${attemptTime}ms)`);\n logger.debug(`Error type: ${error?.constructor?.name || typeof error}`);\n logger.debug(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n\n // Log additional error properties if available\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(`Error code: ${errorObj.code}`);\n }\n if ('cause' in errorObj) {\n logger.debug(\"Error cause:\", errorObj.cause);\n }\n if ('status' in errorObj) {\n logger.debug(`HTTP status: ${errorObj.status}`);\n }\n if ('statusText' in errorObj) {\n logger.debug(`HTTP status text: ${errorObj.statusText}`);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n if (attempt === retries - 1) {\n logger.error(`All connection attempts failed (${retries} attempts)`);\n logger.error(`URL: ${this.figmaUrl}`);\n throw new Error(\n `Failed to connect to Figma MCP at ${this.figmaUrl} after ${retries} attempts. Make sure Figma Desktop is running with MCP enabled.`,\n );\n }\n\n const waitTime = 1000 * (attempt + 1);\n logger.debug(`Waiting ${waitTime}ms before retry...`);\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, waitTime),\n );\n logger.debug(\"Wait complete, retrying...\");\n }\n }\n }\n\n /**\n * Ensure connection is established\n */\n private async ensureConnected(): Promise<void> {\n if (!this.connected || !this.client) {\n logger.debug(\"ensureConnected() called - not connected, attempting connection...\");\n await this.connect();\n } else {\n logger.debug(\"ensureConnected() called - already connected, skipping\");\n }\n }\n\n /**\n * Normalize nodeId format: convert \"XXXX-XXXX\" to \"XXXX:XXXX\" for Figma MCP compatibility\n */\n private normalizeNodeId(nodeId?: string): string | undefined {\n if (!nodeId) return undefined;\n // Convert dash format to colon format (e.g., \"315-2920\" -> \"315:2920\")\n return nodeId.replace(/-/g, \":\");\n }\n\n /**\n * Call Figma's get_design_context tool\n */\n async getDesignContext(\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_design_context with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (code) , 1 (rules to use and ignore) and 3 (design tokens)\n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Generated React code\n parsedResult.content[1], // Item 1: Rules to Use and Ignore\n parsedResult.content[3], // Item 3: Design tokens/styles\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_design_context, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args\n });\n\n return result as FigmaDesignContextResult;\n }\n }\n\n /**\n * Call Figma's get_metadata tool to get actual node structure\n */\n async getMetadata(\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_metadata with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (raw metadata) \n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Metadata Raw\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_metadata, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n return result as FigmaMetadataResult;\n }\n }\n\n /**\n * Call Figma's get_screenshot tool\n * Note: clientLanguages and clientFrameworks are not needed for screenshots\n * (only required for get_design_context which generates code)\n */\n async getScreenshot(\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n // Normalize nodeId format for Figma MCP compatibility\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined to use frame current selection,\n },\n });\n\n return result as FigmaScreenshotResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_screenshot, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined,\n },\n });\n\n return result as FigmaScreenshotResult;\n }\n }\n\n /**\n * Close connection\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.connected = false;\n this.client = null;\n logger.debug(\"Disconnected from Figma MCP\");\n }\n }\n}\n\n","/**\n * Metadata Extractor (Simpler)\n *\n * Extracts ALL `name=\"...\"` / `name='...'` attribute values from the Figma\n * metadata XML-like text and returns them as a list.\n *\n * This is intentionally minimal (no heuristics, no categorization).\n */\nexport class MetadataExtractorSimpler {\n /**\n * Returns every `name=` attribute value in appearance order.\n * Automatically removes exact duplicates (case-sensitive) while preserving first-seen order.\n *\n * Example match:\n * `<frame id=\"28:2524\" name=\"Referral/New 1.1\" ...>`\n * ^^^^^^^^^^^^^^^\n */\n extractNames(metadataText: string): string[] {\n if (!metadataText) return [];\n\n const names: string[] = [];\n const seen = new Set<string>();\n const matches = metadataText.matchAll(/\\bname\\s*=\\s*([\"'])(.*?)\\1/gi);\n\n for (const match of matches) {\n const raw = match[2];\n const name = typeof raw === \"string\" ? raw.trim() : \"\";\n \n // Only add if not empty and not already seen (exact duplicate check)\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n\n return names;\n }\n}\n\n","/**\n * Design Context Extractor\n * Extracts component information from Figma design context (code + tokens)\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\nexport class DesignContextExtractor {\n /**\n * Extract semantic information from JSX/HTML code and design tokens\n */\n extractFromCodeAndTokens(code: string, tokens: string, descriptor: ComponentDescriptor): void {\n // Extract from code section\n this.extractFromCode(code, descriptor);\n\n // Extract from design tokens\n this.extractFromTokens(tokens, descriptor);\n }\n\n /**\n * Extract semantic information from JSX/HTML code\n */\n private extractFromCode(code: string, descriptor: ComponentDescriptor): void {\n // Extract all data-name attributes to understand component structure\n const dataNameMatches = code.matchAll(/data-name=[\"']([^\"']+)[\"']/gi);\n const dataNames: string[] = [];\n \n for (const match of dataNameMatches) {\n const name = match[1].trim();\n if (name && name.length > 0) {\n dataNames.push(name.toLowerCase());\n }\n }\n\n // Track primary component (usually the first/root data-name)\n const primaryDataName = dataNames[0] || \"\";\n\n // 1. EXTRACT HIERARCHY from data-name structure\n this.extractHierarchy(dataNames, descriptor);\n\n // 2. IDENTIFY ALL COMPONENT TYPES from data-names and elements\n this.identifyComponents(code, dataNames, descriptor);\n\n // 3. DETERMINE PURPOSE from primary component and text content\n this.determinePurpose(code, primaryDataName, descriptor);\n\n // 4. EXTRACT VISUAL CHARACTERISTICS\n this.extractVisualTraits(code, dataNames, descriptor);\n\n // 5. EXTRACT LAYOUT PATTERNS\n this.extractLayoutPatterns(code, descriptor);\n\n // 6. DETECT INTERACTIONS\n this.detectInteractions(code, descriptor);\n\n // 7. EXTRACT REACT PROPS AND STATE\n this.extractReactPropsAndState(code, descriptor);\n\n // 8. EXTRACT SIZE AND SPACING PATTERNS\n this.extractSizeAndSpacing(code, descriptor);\n\n // 9. EXTRACT BORDER AND STYLING PATTERNS\n this.extractBorderAndStyling(code, descriptor);\n\n // 10. EXTRACT ADDITIONAL KEYWORDS\n this.extractKeywords(code, dataNames, descriptor);\n }\n\n /**\n * Extract hierarchy structure from data-name attributes\n * Identifies structural parts like Header, Body, Footer, Container, etc.\n */\n private extractHierarchy(dataNames: string[], descriptor: ComponentDescriptor): void {\n const hierarchyKeywords = [\n 'header', 'footer', 'body', 'container', 'content', 'wrapper',\n 'main', 'sidebar', 'nav', 'navigation', 'section', 'panel',\n 'card', 'tile', 'box', 'frame', 'group', 'stack', 'row', 'column',\n 'top'\n ];\n\n for (const name of dataNames) {\n const lowerName = name.toLowerCase();\n \n // Check if this data-name represents a structural part\n for (const keyword of hierarchyKeywords) {\n if (lowerName.includes(keyword)) {\n // Normalize to common terms\n if (keyword === 'nav' || keyword === 'navigation') {\n if (!descriptor.hierarchy.includes('navigation')) {\n descriptor.hierarchy.push('navigation');\n }\n } else if (keyword === 'content' || keyword === 'wrapper' || keyword === 'container') {\n if (!descriptor.hierarchy.includes('container')) {\n descriptor.hierarchy.push('container');\n }\n } else if (keyword === 'section' || keyword === 'panel') {\n if (!descriptor.hierarchy.includes('section')) {\n descriptor.hierarchy.push('section');\n }\n } else if (!descriptor.hierarchy.includes(keyword)) {\n descriptor.hierarchy.push(keyword);\n }\n break;\n }\n }\n }\n }\n\n /**\n * Identify all component types in the design\n */\n private identifyComponents(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Extract React component/function names (e.g., \"function SearchInput\", \"const Button =\")\n const functionMatches = code.matchAll(/(?:function|const|export\\s+(?:default\\s+)?function)\\s+([A-Z][a-zA-Z0-9]*)/g);\n const componentNames: string[] = [];\n for (const match of functionMatches) {\n if (match[1]) componentNames.push(match[1].toLowerCase());\n }\n const componentNamesText = componentNames.join(\" \");\n\n // Combine all text for analysis\n const combinedText = allText + \" \" + componentNamesText;\n\n // Modal/Dialog/Overlay\n if (/modal|dialog|popup|overlay|sheet|drawer/i.test(combinedText)) {\n descriptor.components.add(\"modal\");\n }\n\n // Buttons - check component names, HTML tags, and data-names\n if (/<button/i.test(code) || /button|btn/i.test(combinedText)) {\n // Check for icon button first (more specific)\n if (/icon.*button|button.*icon|<button[^>]*>.*<img|<button[^>]*>.*<svg|<button[^>]*>.*icon/i.test(code) ||\n /showicon|iconbutton/i.test(combinedText)) {\n descriptor.components.add(\"icon button\");\n } else {\n descriptor.components.add(\"button\");\n }\n }\n\n // Form Inputs - check component names (e.g., SearchInput, TextInput), HTML tags, and data-names\n if (/<input/i.test(code) || /input|textfield|text.?field|searchinput|textinput/i.test(combinedText)) {\n descriptor.components.add(\"input\");\n // Check if it's a search input\n if (/search/i.test(combinedText) || /data-name.*search/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n if (/<textarea/i.test(code) || /textarea|text.?area/i.test(allText)) {\n descriptor.components.add(\"textarea\");\n }\n if (/<select/i.test(code) || /dropdown|select|picker|combobox/i.test(allText)) {\n descriptor.components.add(\"dropdown\");\n }\n if (/type=[\"']checkbox/i.test(code) || /checkbox|check.?box/i.test(allText)) {\n descriptor.components.add(\"checkbox\");\n }\n if (/type=[\"']radio/i.test(code) || /radio|radio.?button/i.test(allText)) {\n descriptor.components.add(\"radio\");\n }\n if (/switch|toggle/i.test(allText)) {\n descriptor.components.add(\"switch\");\n }\n if (/slider|range/i.test(allText)) {\n descriptor.components.add(\"slider\");\n }\n\n // Navigation - only detect if actual navbar/navigation element exists\n if (/<nav|<Navbar|navbar|nav.?bar|navigation.?bar|app.?bar/i.test(code)) {\n descriptor.components.add(\"navbar\");\n }\n if (/sidebar|side.?bar|side.?nav|drawer/i.test(allText)) {\n descriptor.components.add(\"sidebar\");\n }\n if (/breadcrumb|breadcrumbs|bread.?crumb/i.test(allText)) {\n descriptor.components.add(\"breadcrumb\");\n }\n if (/tab|tabs|tab.?bar|tab.?navigation/i.test(allText)) {\n descriptor.components.add(\"tabs\");\n }\n if (/menu|dropdown.?menu|context.?menu/i.test(allText)) {\n descriptor.components.add(\"menu\");\n }\n if (/pagination|pager|page.?navigation/i.test(allText)) {\n descriptor.components.add(\"pagination\");\n }\n\n // Data Display\n if (/<table|<tr|<td|<th/i.test(code) || /table|data.?table|grid.?table/i.test(allText)) {\n descriptor.components.add(\"table\");\n }\n if (/card|panel|tile/i.test(allText)) {\n descriptor.components.add(\"card\");\n }\n if (/list|list.?item/i.test(allText)) {\n descriptor.components.add(\"list\");\n }\n if (/grid|grid.?layout/i.test(allText)) {\n descriptor.components.add(\"grid\");\n }\n if (/calendar|date.?picker|date.?calendar/i.test(allText)) {\n descriptor.components.add(\"calendar\");\n }\n if (/chart|graph|visualization/i.test(allText)) {\n descriptor.components.add(\"chart\");\n }\n\n // Feedback\n if (/alert|notification|banner|message/i.test(allText)) {\n descriptor.components.add(\"alert\");\n }\n if (/badge|label|tag|chip/i.test(allText)) {\n descriptor.components.add(\"badge\");\n }\n if (/tooltip|popover|tip/i.test(allText)) {\n descriptor.components.add(\"tooltip\");\n }\n if (/progress|loader|spinner|loading/i.test(allText)) {\n descriptor.components.add(\"progress\");\n }\n if (/toast|snackbar/i.test(allText)) {\n descriptor.components.add(\"toast\");\n }\n\n // Layout - only detect if actual header/footer elements exist (not just data-name labels)\n if (/<header|<Header/i.test(code) || \n (/page.?header|site.?header|main.?header/i.test(allText) && !/data-name.*header/i.test(code))) {\n descriptor.components.add(\"header\");\n }\n if (/<footer|<Footer/i.test(code) || \n (/page.?footer|site.?footer|main.?footer/i.test(allText) && !/data-name.*footer/i.test(code))) {\n descriptor.components.add(\"footer\");\n }\n\n // Specialized\n if (/avatar|profile.?picture|user.?image/i.test(allText)) {\n descriptor.components.add(\"avatar\");\n }\n if (/stepper|steps|wizard/i.test(allText)) {\n descriptor.components.add(\"stepper\");\n }\n if (/accordion|collapsible|expandable/i.test(allText)) {\n descriptor.components.add(\"accordion\");\n }\n if (/carousel|slider|slideshow/i.test(allText)) {\n descriptor.components.add(\"carousel\");\n }\n if (/segmented.?control|segment/i.test(allText)) {\n descriptor.components.add(\"segmented control\");\n }\n }\n\n /**\n * Determine overall purpose of the design\n */\n private determinePurpose(code: string, primaryName: string, descriptor: ComponentDescriptor): void {\n const combinedText = (code + \" \" + primaryName).toLowerCase();\n\n // Action purposes\n if (/delete|remove|borrar/i.test(combinedText)) {\n descriptor.purpose = \"delete confirmation\";\n } else if (/edit|modify|change|update/i.test(combinedText)) {\n descriptor.purpose = \"edit form\";\n } else if (/create|new|add/i.test(combinedText)) {\n descriptor.purpose = \"create form\";\n } else if (/save|submit|apply/i.test(combinedText)) {\n descriptor.purpose = \"submit form\";\n } else if (/search|find|query/i.test(combinedText)) {\n descriptor.purpose = \"search interface\";\n } else if (/filter|sort|organize/i.test(combinedText)) {\n descriptor.purpose = \"data filtering\";\n } else if (/login|signin|sign.in|authenticate/i.test(combinedText)) {\n descriptor.purpose = \"authentication\";\n } else if (/register|signup|sign.up/i.test(combinedText)) {\n descriptor.purpose = \"registration\";\n } else if (/dashboard|overview|summary/i.test(combinedText)) {\n descriptor.purpose = \"dashboard\";\n } else if (/warning|alert|caution/i.test(combinedText)) {\n descriptor.purpose = \"warning\";\n } else if (/error|fail|problem/i.test(combinedText)) {\n descriptor.purpose = \"error\";\n } else if (/success|complete|done/i.test(combinedText)) {\n descriptor.purpose = \"success\";\n }\n }\n\n /**\n * Extract visual characteristics\n */\n private extractVisualTraits(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Check data-names specifically for icon types (e.g., \"Info icon\", \"Search icon\")\n for (const dataName of dataNames) {\n const lowerDataName = dataName.toLowerCase();\n if (/icon/i.test(lowerDataName)) {\n if (/info|information/i.test(lowerDataName)) {\n descriptor.visual.push(\"info icon\");\n descriptor.keywords.push(\"info icon\");\n } else if (/search|magnify/i.test(lowerDataName)) {\n descriptor.visual.push(\"search icon\");\n descriptor.keywords.push(\"search icon\");\n } else if (/warning|alert|caution/i.test(lowerDataName)) {\n descriptor.visual.push(\"warning icon\");\n } else if (/success|check|confirm/i.test(lowerDataName)) {\n descriptor.visual.push(\"success icon\");\n } else if (/error|danger/i.test(lowerDataName)) {\n descriptor.visual.push(\"error icon\");\n } else if (/close|exit|dismiss/i.test(lowerDataName)) {\n descriptor.visual.push(\"close icon\");\n }\n }\n }\n\n // Icons from general patterns\n if (/icon|svg/i.test(allText)) {\n if (/warning|alert|caution/i.test(allText)) {\n descriptor.visual.push(\"warning icon\");\n }\n if (/close|exit|dismiss|×|cancel/i.test(allText)) {\n descriptor.visual.push(\"close icon\");\n }\n if (/success|check|confirm|✓/i.test(allText)) {\n descriptor.visual.push(\"success icon\");\n }\n if (/error|danger|problem|×/i.test(allText)) {\n descriptor.visual.push(\"error icon\");\n }\n if (/info|information|help|\\?/i.test(allText)) {\n descriptor.visual.push(\"info icon\");\n }\n if (/search|magnify|🔍/i.test(allText)) {\n descriptor.visual.push(\"search icon\");\n }\n }\n\n // Images\n if (/<img|<image/i.test(code) || /image|picture|photo|imgDash|imgAvatar/i.test(allText)) {\n descriptor.visual.push(\"image\");\n }\n\n // Check for field/container patterns (indicates form input structure)\n if (/field.*container|input.*container|search.*text/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n }\n }\n\n /**\n * Extract layout patterns from styling\n */\n private extractLayoutPatterns(code: string, descriptor: ComponentDescriptor): void {\n // Flex layouts\n if (/flex-col|flex.col/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered vertical\");\n } else if (/flex-row/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered horizontal\");\n } else if (/flex/i.test(code)) {\n descriptor.layout.push(\"flex layout\");\n }\n\n // Grid layouts\n if (/grid-cols|grid.cols/i.test(code)) {\n descriptor.layout.push(\"grid layout\");\n }\n\n // Visual effects\n if (/rounded-\\[?[0-9]/i.test(code) || /rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n descriptor.layout.push(\"rounded\");\n }\n \n if (/shadow-\\[/i.test(code) || /shadow-(?:sm|md|lg|xl|2xl)/i.test(code)) {\n descriptor.layout.push(\"elevated\");\n }\n\n // Responsive indicators\n if (/responsive|mobile|desktop|tablet/i.test(code)) {\n descriptor.layout.push(\"responsive\");\n }\n }\n\n /**\n * Detect interaction patterns\n */\n private detectInteractions(code: string, descriptor: ComponentDescriptor): void {\n const lowerCode = code.toLowerCase();\n\n // Dialog interactions\n if (descriptor.components.has(\"modal\")) {\n if (/confirm|yes|no|ok|cancel/i.test(code)) {\n descriptor.interactions.add(\"confirmation\");\n }\n if (/dismiss|close|exit/i.test(code)) {\n descriptor.interactions.add(\"dismissible\");\n }\n }\n\n // Form interactions\n if (descriptor.components.has(\"input\") || descriptor.components.has(\"button\")) {\n if (/submit|save|send|apply/i.test(lowerCode)) {\n descriptor.interactions.add(\"form submission\");\n }\n if (/validate|validation|error|required/i.test(lowerCode)) {\n descriptor.interactions.add(\"validation\");\n }\n }\n\n // Navigation interactions\n if (descriptor.components.has(\"tabs\") || descriptor.components.has(\"menu\")) {\n descriptor.interactions.add(\"navigation\");\n }\n\n // Data interactions\n if (descriptor.components.has(\"table\") || descriptor.components.has(\"list\")) {\n if (/sort|filter|search/i.test(lowerCode)) {\n descriptor.interactions.add(\"data manipulation\");\n }\n if (/select|checkbox|radio/i.test(lowerCode)) {\n descriptor.interactions.add(\"selection\");\n }\n }\n }\n\n /**\n * Extract React props and TypeScript state types\n */\n private extractReactPropsAndState(code: string, descriptor: ComponentDescriptor): void {\n // Extract TypeScript interface/type definitions\n const interfaceMatches = code.matchAll(/(?:interface|type)\\s+(\\w+Props)\\s*\\{/gi);\n for (const match of interfaceMatches) {\n const interfaceName = match[1].toLowerCase();\n if (/input|search|field/i.test(interfaceName)) {\n descriptor.components.add(\"input\");\n }\n if (/button/i.test(interfaceName)) {\n descriptor.components.add(\"button\");\n }\n if (/modal|dialog/i.test(interfaceName)) {\n descriptor.components.add(\"modal\");\n }\n }\n\n // Extract props that indicate features\n if (/showLabel|showlabel/i.test(code)) {\n descriptor.keywords.push(\"label\");\n }\n if (/showInfoIcon|showinfoicon|showInfo|showinfo/i.test(code)) {\n descriptor.keywords.push(\"info icon\");\n descriptor.visual.push(\"info icon\");\n }\n if (/showHelper|showhelper|helperText|helpertext/i.test(code)) {\n descriptor.keywords.push(\"helper\");\n descriptor.keywords.push(\"helper text\");\n }\n if (/showIcon|showicon/i.test(code)) {\n descriptor.keywords.push(\"icon\");\n }\n if (/showSearch|showsearch/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.keywords.push(\"search icon\");\n }\n if (/filledText|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/className/i.test(code)) {\n descriptor.keywords.push(\"customizable\");\n }\n\n // Extract state types from TypeScript (e.g., state?: \"enabled\" | \"hover\" | \"error\")\n const stateMatches = code.matchAll(/state[?:].*[\"']([^\"']+)[\"']/gi);\n const states: string[] = [];\n for (const match of stateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n \n // Also extract from union types: \"enabled\" | \"hover\" | \"pressed\" | \"error\"\n const unionStateMatches = code.matchAll(/[\"'](enabled|hover|pressed|active-focus|read-only|error|success|disabled|loading|empty|filled)[\"']/gi);\n for (const match of unionStateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n\n // Process states\n for (const state of states) {\n if (state === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.visual.push(\"error state\");\n } else if (state === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.visual.push(\"success state\");\n } else if (state === \"disabled\") {\n descriptor.keywords.push(\"disabled\");\n } else if (state === \"loading\") {\n descriptor.components.add(\"progress\");\n } else if (state === \"hover\") {\n descriptor.keywords.push(\"hover\");\n descriptor.interactions.add(\"hover\");\n } else if (state === \"pressed\") {\n descriptor.keywords.push(\"pressed\");\n descriptor.interactions.add(\"press\");\n } else if (state === \"active-focus\") {\n descriptor.keywords.push(\"focus\");\n descriptor.keywords.push(\"active\");\n descriptor.interactions.add(\"focus\");\n } else if (state === \"read-only\") {\n descriptor.keywords.push(\"read only\");\n }\n }\n\n // Extract content types (e.g., content?: \"placeholder\" | \"filled text\")\n const contentMatches = code.matchAll(/content[?:].*[\"']([^\"']+)[\"']/gi);\n for (const match of contentMatches) {\n if (match[1]) {\n const content = match[1].toLowerCase();\n if (content.includes(\"placeholder\")) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (content.includes(\"filled\")) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (content.includes(\"empty\")) {\n descriptor.keywords.push(\"empty\");\n }\n }\n }\n \n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/filled.*text|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n }\n\n // Extract from data-name patterns that indicate search\n if (/data-name.*search|search.*text|search.*input/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n\n /**\n * Extract size and spacing patterns from className and styles\n */\n private extractSizeAndSpacing(code: string, descriptor: ComponentDescriptor): void {\n // Size patterns (e.g., size-[24px], h-[48px], w-[1440px])\n if (/size-\\[(\\d+)|h-\\[(\\d+)|w-\\[(\\d+)|height:\\s*(\\d+)|width:\\s*(\\d+)/i.test(code)) {\n const sizeMatches = code.matchAll(/(?:size|h|w|height|width)[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 64) {\n descriptor.keywords.push(\"large\");\n } else if (size >= 48) {\n descriptor.keywords.push(\"medium\");\n } else if (size >= 24) {\n descriptor.keywords.push(\"small\");\n }\n // Icon sizes\n if (size === 24 || size === 48 || size === 64) {\n descriptor.keywords.push(`${size}px icon`);\n }\n }\n }\n\n // Gap/spacing patterns (e.g., gap-[4px], gap-[12px], gap-[16px])\n if (/gap-\\[(\\d+)|gap:\\s*(\\d+)/i.test(code)) {\n const gapMatches = code.matchAll(/gap[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of gapMatches) {\n const gap = parseInt(match[1], 10);\n if (gap >= 16) {\n descriptor.keywords.push(\"spaced\");\n descriptor.layout.push(\"spaced layout\");\n } else if (gap >= 8) {\n descriptor.keywords.push(\"compact\");\n }\n }\n }\n\n // Padding patterns (e.g., p-[12px])\n if (/p-\\[(\\d+)|padding:\\s*(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"padded\");\n }\n\n // Max/min height/width patterns\n if (/max-h-\\[(\\d+)|min-h-\\[(\\d+)|max-w-\\[(\\d+)|min-w-\\[(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n }\n\n /**\n * Extract border and styling patterns\n */\n private extractBorderAndStyling(code: string, descriptor: ComponentDescriptor): void {\n // Border patterns\n if (/border\\s+border-\\[|border:\\s*1px|border-solid/i.test(code)) {\n descriptor.keywords.push(\"bordered\");\n // Check border color\n if (/border-\\[var\\(--color\\/border/i.test(code)) {\n descriptor.keywords.push(\"default border\");\n }\n if (/border-\\[var\\(--color\\/border\\/default/i.test(code)) {\n descriptor.keywords.push(\"border\");\n }\n }\n\n // Rounded corners (e.g., rounded-[8px], rounded-lg)\n if (/rounded-\\[(\\d+)|rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n const roundedMatches = code.matchAll(/rounded-\\[(\\d+)|rounded-(sm|md|lg|xl|full)/gi);\n for (const match of roundedMatches) {\n const value = match[1] || match[2];\n if (value === \"full\" || value === \"xl\") {\n descriptor.keywords.push(\"fully rounded\");\n } else {\n descriptor.keywords.push(\"rounded\");\n }\n }\n }\n\n // Background patterns\n if (/bg-\\[var\\(--color\\/surface|background:\\s*var\\(--color/i.test(code)) {\n descriptor.keywords.push(\"background\");\n if (/surface\\/flat|surface.*flat/i.test(code)) {\n descriptor.keywords.push(\"flat surface\");\n }\n if (/surface\\/floating|surface.*floating/i.test(code)) {\n descriptor.keywords.push(\"floating surface\");\n }\n }\n\n // Shadow patterns (already in layout, but add keywords)\n if (/shadow-\\[0px_0px_0px_0px/i.test(code)) {\n descriptor.keywords.push(\"no shadow\");\n } else if (/shadow-\\[|drop-shadow/i.test(code)) {\n descriptor.keywords.push(\"shadow\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden/i.test(code)) {\n descriptor.keywords.push(\"clipped\");\n }\n\n // Flex patterns (more detailed)\n if (/flex\\s+flex-\\[1_0_0\\]|flex-1/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n descriptor.layout.push(\"flexible layout\");\n }\n\n // Content stretch pattern\n if (/content-stretch/i.test(code)) {\n descriptor.keywords.push(\"stretched\");\n descriptor.layout.push(\"stretched layout\");\n }\n }\n\n /**\n * Extract additional keywords from code and data-names for Pinecone search\n */\n private extractKeywords(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = (code + \" \" + dataNames.join(\" \")).toLowerCase();\n\n // Dialog/modal keywords\n if (/modal|dialog|popup|overlay/i.test(allText)) {\n descriptor.keywords.push(\"dialog\");\n descriptor.keywords.push(\"overlay\");\n }\n\n // Destructive / irreversible action\n if (/delete|remove|borrar|irreversible|undo|destructive/i.test(allText)) {\n descriptor.keywords.push(\"destructive\");\n if (/irreversible|undo|no way to undo/i.test(allText)) {\n descriptor.keywords.push(\"irreversible\");\n }\n }\n\n // Button / action labels (common CTA words)\n if (/cancel|dismiss|close/i.test(allText)) {\n descriptor.keywords.push(\"cancel\");\n descriptor.keywords.push(\"dismissible\");\n }\n if (/\\bdelete\\b|remove|borrar/i.test(allText)) descriptor.keywords.push(\"delete\");\n if (/confirm|ok|submit|save|apply/i.test(allText)) descriptor.keywords.push(\"confirm\");\n\n // Support / hero icon (large centered icon)\n if (/support\\s*icon|hero|lead\\s*icon|centered\\s*icon|large\\s*icon/i.test(allText)) {\n descriptor.keywords.push(\"support icon\");\n descriptor.keywords.push(\"centered icon\");\n }\n\n // Structure keywords\n if (/header|body|footer|container/i.test(allText)) {\n if (/header.*body|body.*header/i.test(allText)) descriptor.keywords.push(\"header body\");\n }\n\n // Navigation / navbar keywords (e.g. NAV/Header, NAV/Top, Header/MenuPral)\n if (/data-name=[\"'][^\"']*\\bnav\\b|data-name=[\"'][^\"']*\\/nav\\b/i.test(allText) ||\n /\\bnav\\/|nav\\s*\\/|\\/nav\\b/i.test(allText)) {\n descriptor.keywords.push(\"navbar\");\n descriptor.keywords.push(\"navigation\");\n descriptor.keywords.push(\"top nav\");\n }\n if (/data-name=[\"'][^\"']*\\bmenu\\b|data-name=[\"'][^\"']*menu\\w*/i.test(allText)) {\n descriptor.keywords.push(\"menu\");\n }\n if (/data-name=[\"'][^\"']*\\btop\\b/i.test(allText) && /nav|header/i.test(allText)) {\n descriptor.keywords.push(\"top nav\");\n descriptor.keywords.push(\"header nav\");\n }\n // Nav links: multiple <p> inside nav-like structure\n const pCount = (code.match(/<p\\b|<\\/p>/gi) || []).length;\n if (pCount >= 3 && /nav|NAV|header|menu/i.test(allText)) {\n descriptor.keywords.push(\"nav links\");\n descriptor.keywords.push(\"navigation links\");\n }\n\n // Text / label / heading elements (<p>, <h1>-<h6>, <label>, <span>, etc.)\n if (/<p\\b|<\\/p>/i.test(code)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/<h[1-6]\\b|<\\/h[1-6]>/i.test(code)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/<label\\b|<\\/label>/i.test(code)) descriptor.keywords.push(\"label\");\n if (/<span\\b|<\\/span>/i.test(code)) {\n descriptor.keywords.push(\"text\");\n descriptor.keywords.push(\"label\");\n }\n if (/<figcaption\\b|<caption\\b/i.test(code)) descriptor.keywords.push(\"caption\");\n if (/<blockquote\\b/i.test(code)) descriptor.keywords.push(\"quote\");\n\n // Data-name hints for text roles (e.g. data-name=\"Title\", data-name=\"Description\")\n if (/data-name=[\"'][^\"']*\\btext\\b/i.test(allText)) descriptor.keywords.push(\"text\");\n if (/data-name=[\"'][^\"']*\\blabel\\b/i.test(allText)) {\n descriptor.keywords.push(\"label\");\n // Check for \"Label container\" pattern\n if (/data-name=[\"'][^\"']*label.*container/i.test(allText)) {\n descriptor.keywords.push(\"label container\");\n }\n }\n if (/data-name=[\"'][^\"']*\\btitle\\b/i.test(allText)) {\n descriptor.keywords.push(\"title\");\n descriptor.keywords.push(\"heading\");\n }\n if (/data-name=[\"'][^\"']*\\bheading\\b/i.test(allText)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/data-name=[\"'][^\"']*\\b(paragraph|description)\\b/i.test(allText)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/data-name=[\"'][^\"']*\\bsubtitle\\b/i.test(allText)) descriptor.keywords.push(\"subtitle\");\n if (/data-name=[\"'][^\"']*\\bbody\\b/i.test(allText)) descriptor.keywords.push(\"body text\");\n \n // Field/Container patterns\n if (/data-name=[\"'][^\"']*field.*container|data-name=[\"'][^\"']*input.*container/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n descriptor.keywords.push(\"field container\");\n }\n if (/data-name=[\"'][^\"']*search/i.test(allText)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n if (/data-name=[\"'][^\"']*search.*text|data-name=[\"'][^\"']*search.*input|data-name=[\"'][^\"']*search\\s*\\+/i.test(allText)) {\n descriptor.keywords.push(\"search input\");\n descriptor.keywords.push(\"search\");\n }\n\n // State combinations in data-names (e.g., \"State=enabled, Content=filled text\")\n const stateContentMatches = code.matchAll(/data-name=[\"']([^\"']*state[^\"']*)[\"']/gi);\n for (const match of stateContentMatches) {\n const stateContent = match[1].toLowerCase();\n if (/state.*enabled/i.test(stateContent)) {\n descriptor.keywords.push(\"enabled\");\n }\n if (/state.*disabled/i.test(stateContent)) {\n descriptor.keywords.push(\"disabled\");\n }\n if (/state.*error/i.test(stateContent)) {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (/state.*success/i.test(stateContent)) {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n if (/content.*filled|content.*filled.*text/i.test(stateContent)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/content.*placeholder/i.test(stateContent)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/content.*empty/i.test(stateContent)) {\n descriptor.keywords.push(\"empty\");\n }\n }\n\n // Vector/Icon patterns in data-names\n if (/data-name=[\"'][^\"']*\\bvector\\b/i.test(allText)) {\n descriptor.keywords.push(\"vector\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Import patterns (images, SVGs)\n if (/import\\s+img|import.*from.*svg|import.*from.*asset/i.test(code)) {\n descriptor.visual.push(\"image\");\n descriptor.keywords.push(\"image import\");\n }\n if (/import.*svg/i.test(code)) {\n descriptor.keywords.push(\"svg\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Size/layout hints from code\n if (/size-\\[64|h-\\[64|w-\\[64|64px|size-\\[48|h-\\[48/i.test(code)) descriptor.keywords.push(\"large icon\");\n if (/gap-\\[16\\]|gap-\\[24\\]|gap-\\[32\\]/i.test(code)) descriptor.keywords.push(\"spaced\");\n if (/rounded-\\[8\\]|rounded-\\[12\\]|rounded-lg/i.test(code)) descriptor.keywords.push(\"rounded\");\n\n // Shadow / elevation from code\n if (/shadow-\\[|drop-shadow|elevation/i.test(allText)) descriptor.keywords.push(\"shadow\");\n\n // Conditional rendering patterns (e.g., if (state === \"enabled\" && content === \"filled text\"))\n if (/if\\s*\\(.*state.*===|if\\s*\\(.*content.*===/i.test(code)) {\n descriptor.keywords.push(\"conditional\");\n descriptor.keywords.push(\"stateful\");\n }\n\n // CSS class patterns (e.g., css-ew64yg, css-4hzbpn)\n if (/css-[a-z0-9]+/i.test(code)) {\n descriptor.keywords.push(\"styled\");\n }\n\n // Relative/absolute positioning\n if (/relative|absolute/i.test(code)) {\n descriptor.keywords.push(\"positioned\");\n }\n\n // Shrink/grow patterns\n if (/shrink-0|grow|flex-\\[1_0_0\\]/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n }\n\n // Min/max width/height patterns\n if (/min-w-|max-w-|min-h-|max-h-/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden|overflow-scroll/i.test(code)) {\n descriptor.keywords.push(\"overflow\");\n }\n\n // Inset patterns (e.g., inset-[8.33%])\n if (/inset-\\[/i.test(code)) {\n descriptor.keywords.push(\"inset\");\n }\n\n // Var() CSS variable patterns\n if (/var\\(--color|var\\(--typescale/i.test(code)) {\n descriptor.keywords.push(\"design tokens\");\n descriptor.keywords.push(\"themed\");\n }\n\n // Extract className values for additional patterns\n const classNameMatches = code.matchAll(/className=[\"']([^\"']+)[\"']/gi);\n for (const match of classNameMatches) {\n const className = match[1].toLowerCase();\n // Extract meaningful class patterns\n if (/flex|grid/i.test(className)) {\n descriptor.layout.push(\"flex layout\");\n }\n if (/items-center|justify-center/i.test(className)) {\n descriptor.layout.push(\"centered\");\n }\n if (/gap-/i.test(className)) {\n descriptor.keywords.push(\"spaced\");\n }\n if (/rounded/i.test(className)) {\n descriptor.keywords.push(\"rounded\");\n }\n if (/shadow/i.test(className)) {\n descriptor.keywords.push(\"shadow\");\n }\n }\n\n // Extract default prop values (e.g., showLabel = true, state = \"enabled\")\n const defaultPropMatches = code.matchAll(/(\\w+)\\s*=\\s*[\"']?([^\"',\\s\\)]+)[\"']?/gi);\n for (const match of defaultPropMatches) {\n const propName = match[1].toLowerCase();\n const propValue = match[2].toLowerCase();\n if (propName === \"state\" && propValue) {\n if (propValue === \"enabled\") descriptor.keywords.push(\"enabled\");\n if (propValue === \"disabled\") descriptor.keywords.push(\"disabled\");\n if (propValue === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (propValue === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n }\n if (propName === \"content\" && propValue) {\n if (propValue.includes(\"placeholder\")) descriptor.keywords.push(\"placeholder\");\n if (propValue.includes(\"filled\")) descriptor.keywords.push(\"filled\");\n }\n }\n }\n\n /**\n * Extract visual characteristics from design tokens\n * Parses Figma design token format: \"TokenName: Value\" or \"TokenName/SubToken: Value\"\n */\n private extractFromTokens(tokens: string, descriptor: ComponentDescriptor): void {\n if (!tokens || tokens.trim().length === 0) return;\n\n if (!descriptor.visual) descriptor.visual = [];\n if (!descriptor.colors) descriptor.colors = [];\n if (!descriptor.typography) descriptor.typography = [];\n if (!descriptor.effects) descriptor.effects = [];\n if (!descriptor.layout) descriptor.layout = [];\n if (!descriptor.keywords) descriptor.keywords = [];\n\n // Parse tokens - they're comma-separated: \"Token: Value, Token2: Value\"\n const tokenEntries = tokens.split(',').map(t => t.trim());\n\n for (const entry of tokenEntries) {\n // Extract token name and value\n // Format: \"TokenName/SubToken: Value\" or \"TokenName: Value\"\n const match = entry.match(/^([^:]+):\\s*(.+)$/);\n if (!match) continue;\n\n const tokenName = match[1].trim();\n const tokenValue = match[2].trim();\n const lowerTokenName = tokenName.toLowerCase();\n\n // Extract semantic color names\n if (lowerTokenName.includes('color') || lowerTokenName.includes('background') || \n lowerTokenName.includes('icon') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('action') || lowerTokenName.includes('border')) {\n \n // Extract semantic color category\n if (lowerTokenName.includes('warning')) {\n if (!descriptor.colors.includes('warning')) {\n descriptor.colors.push('warning');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('warning background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('warning icon');\n }\n } else if (lowerTokenName.includes('error') || lowerTokenName.includes('danger')) {\n if (!descriptor.colors.includes('error')) {\n descriptor.colors.push('error');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('error background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('error icon');\n }\n } else if (lowerTokenName.includes('success')) {\n if (!descriptor.colors.includes('success')) {\n descriptor.colors.push('success');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('success background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('success icon');\n }\n } else if (lowerTokenName.includes('primary') || lowerTokenName.includes('main') || lowerTokenName.includes('brand')) {\n if (!descriptor.colors.includes('primary')) {\n descriptor.colors.push('primary');\n }\n if (lowerTokenName.includes('brand')) {\n descriptor.keywords.push('brand color');\n }\n } else if (lowerTokenName.includes('secondary') || lowerTokenName.includes('alternative')) {\n if (!descriptor.colors.includes('secondary')) {\n descriptor.colors.push('secondary');\n }\n } else if (lowerTokenName.includes('default') || lowerTokenName.includes('neutral')) {\n if (!descriptor.colors.includes('neutral')) {\n descriptor.colors.push('neutral');\n }\n } else if (lowerTokenName.includes('info')) {\n if (!descriptor.colors.includes('info')) {\n descriptor.colors.push('info');\n }\n descriptor.visual.push('info color');\n }\n }\n\n // Extract typography information\n if (lowerTokenName.includes('font') || lowerTokenName.includes('typescale') || \n lowerTokenName.includes('headline') || lowerTokenName.includes('body') ||\n lowerTokenName.includes('button') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('label') || lowerTokenName.includes('helper') ||\n lowerTokenName.includes('placeholder')) {\n \n if (lowerTokenName.includes('headline')) {\n if (!descriptor.typography.includes('headline')) {\n descriptor.typography.push('headline');\n }\n // Extract size if available\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large headline');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium headline');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small headline');\n }\n // Desktop/Mobile variants\n if (lowerTokenName.includes('desktop')) {\n descriptor.keywords.push('desktop');\n }\n if (lowerTokenName.includes('mobile')) {\n descriptor.keywords.push('mobile');\n }\n } else if (lowerTokenName.includes('body')) {\n if (!descriptor.typography.includes('body')) {\n descriptor.typography.push('body text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large body');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium body');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small body');\n }\n // Strong/default variations\n if (lowerTokenName.includes('strong')) {\n descriptor.typography.push('bold');\n descriptor.keywords.push('strong text');\n }\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default text');\n }\n } else if (lowerTokenName.includes('button')) {\n if (!descriptor.typography.includes('button')) {\n descriptor.typography.push('button text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large button');\n descriptor.keywords.push('large button');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium button');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small button');\n }\n } else if (lowerTokenName.includes('label')) {\n descriptor.keywords.push('label');\n if (lowerTokenName.includes('large')) {\n descriptor.keywords.push('large label');\n }\n } else if (lowerTokenName.includes('helper')) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n } else if (lowerTokenName.includes('placeholder')) {\n descriptor.keywords.push('placeholder');\n }\n\n // Extract font weight if mentioned\n if (tokenValue.includes('weight') || tokenValue.includes('700') || tokenValue.includes('bold')) {\n descriptor.typography.push('bold');\n } else if (tokenValue.includes('400') || tokenValue.includes('regular')) {\n descriptor.typography.push('regular');\n } else if (tokenValue.includes('600') || tokenValue.includes('semibold')) {\n descriptor.typography.push('semibold');\n }\n\n // Extract line height and letter spacing\n if (tokenValue.includes('lineHeight') || tokenValue.includes('line-height')) {\n descriptor.keywords.push('line height');\n }\n if (tokenValue.includes('letterSpacing') || tokenValue.includes('letter-spacing')) {\n descriptor.keywords.push('letter spacing');\n }\n }\n\n // Extract elevation and shadow effects\n if (lowerTokenName.includes('elevation') || lowerTokenName.includes('shadow') || \n lowerTokenName.includes('effect')) {\n \n if (lowerTokenName.includes('floating') || lowerTokenName.includes('raised')) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n } else if (lowerTokenName.includes('drop') || lowerTokenName.includes('shadow')) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n } else if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat');\n descriptor.keywords.push('no elevation');\n }\n }\n\n // Extract surface types\n if (lowerTokenName.includes('surface')) {\n if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat surface');\n } else if (lowerTokenName.includes('floating')) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('raised')) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('state')) {\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default state');\n }\n }\n }\n\n // Extract background types\n if (lowerTokenName.includes('background')) {\n if (lowerTokenName.includes('alternative')) {\n descriptor.keywords.push('alternative background');\n if (lowerTokenName.includes('strong')) {\n descriptor.keywords.push('strong background');\n }\n } else if (lowerTokenName.includes('brand')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('brand background');\n }\n }\n\n // Extract border radius from rounded values\n if (lowerTokenName.includes('rounded') || lowerTokenName.includes('radius')) {\n descriptor.layout.push('rounded corners');\n }\n\n // Extract action colors (for buttons, CTAs)\n if (lowerTokenName.includes('action')) {\n if (lowerTokenName.includes('main') || lowerTokenName.includes('primary')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('primary action');\n } else if (lowerTokenName.includes('alternative')) {\n descriptor.colors.push('secondary');\n descriptor.keywords.push('alternative action');\n }\n if (lowerTokenName.includes('selected')) {\n descriptor.keywords.push('selected');\n }\n if (lowerTokenName.includes('on main') || lowerTokenName.includes('on-main')) {\n descriptor.keywords.push('on primary');\n }\n }\n }\n\n // Additional pattern matching for complex token formats\n // Match patterns like \"Background/warning: #FFFAEB\"\n const colorPattern = /(?:Background|Icon|Text|Action|Border)\\/([^:,\\s]+)/gi;\n let colorMatch;\n while ((colorMatch = colorPattern.exec(tokens)) !== null) {\n const semanticName = colorMatch[1].toLowerCase();\n if (semanticName && !descriptor.colors.includes(semanticName)) {\n descriptor.colors.push(semanticName);\n }\n }\n\n // Match elevation patterns\n if (/Elevation\\s+(?:raised|floating|flat)/i.test(tokens)) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n }\n\n // Detect Effect types (DROP_SHADOW, etc.)\n if (/Effect\\(.*DROP_SHADOW/i.test(tokens)) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n }\n\n // Component specific exceptions (e.g., \"Component specific exceptions/Placeholder\")\n if (/Component\\s+specific\\s+exceptions/i.test(tokens)) {\n if (/placeholder/i.test(tokens)) {\n descriptor.keywords.push('placeholder');\n }\n if (/header.*icon/i.test(tokens)) {\n descriptor.keywords.push('header icon');\n }\n if (/button/i.test(tokens)) {\n descriptor.keywords.push('button');\n }\n }\n\n // Helper text detection\n if (/helper.*text|typescale.*helper/i.test(tokens)) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n }\n\n // Token-based keywords\n if (/Action\\/main|action.*main/i.test(tokens) && /#EC0000|#e00|red|danger/i.test(tokens)) {\n descriptor.keywords.push('destructive');\n descriptor.keywords.push('primary action');\n }\n if (/Elevation\\s+floating|elevation.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating');\n }\n if (/Background\\/warning|Icon\\/warning|warning/i.test(tokens)) {\n descriptor.keywords.push('warning');\n }\n if (/Headline|headline|typescale/i.test(tokens)) {\n descriptor.keywords.push('headline');\n }\n if (/Body\\/Body|body.*default/i.test(tokens)) {\n descriptor.keywords.push('body text');\n }\n if (/Button Large|button\\/large|Button Large/i.test(tokens)) {\n descriptor.keywords.push('large button');\n }\n if (/Surface\\/floating|surface.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n }\n if (/Surface\\/raised|surface.*raised/i.test(tokens)) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n }\n\n // Extract more color patterns (Text/info, Icon/soft, etc.)\n if (/Text\\/info|text.*info/i.test(tokens)) {\n descriptor.colors.push('info');\n descriptor.keywords.push('info text');\n }\n if (/Text\\/soft|text.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft text');\n }\n if (/Icon\\/soft|icon.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft icon');\n }\n if (/Icon\\/default|icon.*default/i.test(tokens)) {\n descriptor.keywords.push('default icon');\n }\n\n // Extract more typography patterns\n if (/Body.*Medium.*Strong|body.*medium.*strong/i.test(tokens)) {\n descriptor.typography.push('bold');\n descriptor.typography.push('medium body');\n descriptor.keywords.push('strong text');\n }\n if (/Body.*Medium.*Default|body.*medium.*default/i.test(tokens)) {\n descriptor.typography.push('medium body');\n descriptor.keywords.push('default text');\n }\n if (/Headline.*Desktop|headline.*desktop/i.test(tokens)) {\n descriptor.keywords.push('desktop');\n }\n if (/Headline.*Mobile|headline.*mobile/i.test(tokens)) {\n descriptor.keywords.push('mobile');\n }\n\n // Extract Surface/State patterns\n if (/Surface\\/State|surface.*state/i.test(tokens)) {\n descriptor.keywords.push('state surface');\n if (/default/i.test(tokens)) {\n descriptor.keywords.push('default state');\n }\n }\n\n // Extract more background patterns\n if (/Background\\/alternative|background.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative background');\n }\n if (/Background\\/alternative.*strong|background.*alternative.*strong/i.test(tokens)) {\n descriptor.keywords.push('strong alternative background');\n }\n\n // Extract more border patterns\n if (/Border\\/default|border.*default/i.test(tokens)) {\n descriptor.keywords.push('default border');\n }\n if (/Border\\/alternative|border.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative border');\n }\n\n // Extract Font family patterns\n if (/Font\\(family:|font.*family/i.test(tokens)) {\n descriptor.keywords.push('custom font');\n if (/Santander/i.test(tokens)) {\n descriptor.keywords.push('santander font');\n }\n }\n\n // Extract letter spacing and line height from Font() patterns\n if (/letterSpacing|letter-spacing/i.test(tokens)) {\n descriptor.keywords.push('letter spacing');\n }\n if (/lineHeight|line-height/i.test(tokens)) {\n descriptor.keywords.push('line height');\n }\n\n // Extract size from Font() patterns\n if (/size:\\s*(\\d+)/i.test(tokens)) {\n const sizeMatches = tokens.matchAll(/size:\\s*(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 24) {\n descriptor.keywords.push('large text');\n } else if (size >= 16) {\n descriptor.keywords.push('medium text');\n } else {\n descriptor.keywords.push('small text');\n }\n }\n }\n }\n}\n","/**\n * Query Builder\n * Builds semantic queries from component descriptors\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\n/**\n * Build a natural language query from extracted descriptor\n * Prioritizes semantic richness for embedding-based search\n * Includes hierarchy and enhanced design token information\n */\nexport function buildSemanticQuery(descriptor: ComponentDescriptor, fallback: string): string {\n const queryParts: string[] = [];\n\n // 1. Add primary components (most important for matching)\n // Prioritize complex/specific components over generic ones\n const componentArray = Array.from(descriptor.components);\n const priorityComponents = prioritizeComponents(componentArray);\n \n if (priorityComponents.length > 0) {\n // For complex frames: include top 5-7 components\n // For simple frames: this will naturally be fewer\n queryParts.push(...priorityComponents.slice(0, 7));\n }\n\n // 2. Add hierarchy information (structural parts)\n if (descriptor.hierarchy.length > 0) {\n // Build hierarchy description\n const hierarchyParts = descriptor.hierarchy.slice(0, 4); // Limit to avoid too long\n if (hierarchyParts.length > 0) {\n // Create natural hierarchy description\n if (hierarchyParts.includes('header') && hierarchyParts.includes('body')) {\n queryParts.push('with header and body');\n } else if (hierarchyParts.includes('header') && hierarchyParts.includes('footer')) {\n queryParts.push('with header and footer');\n } else if (hierarchyParts.length === 1) {\n queryParts.push(`with ${hierarchyParts[0]}`);\n } else {\n // Add individual hierarchy parts\n queryParts.push(...hierarchyParts.slice(0, 3));\n }\n }\n }\n\n // 3. Add purpose if present (provides semantic context)\n if (descriptor.purpose) {\n queryParts.push(descriptor.purpose);\n }\n\n // 4. Add key interactions (helps match use cases)\n // Filter out interactions that are already covered by purpose\n if (descriptor.interactions.size > 0) {\n const interactions = Array.from(descriptor.interactions)\n .filter(interaction => {\n // Don't add \"confirmation\" if purpose already contains it\n if (interaction === \"confirmation\" && descriptor.purpose?.includes(\"confirmation\")) {\n return false;\n }\n return true;\n })\n .slice(0, 2);\n queryParts.push(...interactions);\n }\n\n // 5. Add semantic colors from design tokens\n if (descriptor.colors.length > 0) {\n queryParts.push(...descriptor.colors.slice(0, 3));\n }\n\n // 6. Add visual characteristics (helps with visual similarity)\n if (descriptor.visual.length > 0) {\n queryParts.push(...descriptor.visual.slice(0, 4));\n }\n\n // 7. Add typography information (if relevant)\n if (descriptor.typography.length > 0) {\n // Only add most distinctive typography features\n const distinctiveTypography = descriptor.typography.filter(t => \n t.includes('headline') || t.includes('bold') || t.includes('large')\n );\n if (distinctiveTypography.length > 0) {\n queryParts.push(...distinctiveTypography.slice(0, 2));\n }\n }\n\n // 8. Add effects (elevation, shadows)\n if (descriptor.effects.length > 0) {\n queryParts.push(...descriptor.effects.slice(0, 2));\n }\n\n // 9. Add layout traits (secondary importance)\n if (descriptor.layout.length > 0) {\n queryParts.push(...descriptor.layout.slice(0, 3));\n }\n\n // 10. Add additional keywords\n if (descriptor.keywords.length > 0) {\n queryParts.push(...descriptor.keywords.slice(0, 8));\n }\n\n // 11. Deduplicate terms (case-insensitive)\n const seen = new Set<string>();\n const uniqueParts = queryParts.filter(part => {\n const lower = part.toLowerCase();\n if (seen.has(lower)) {\n return false;\n }\n seen.add(lower);\n return true;\n });\n\n // Build final query\n if (uniqueParts.length > 0) {\n return uniqueParts.join(\" \");\n }\n\n return fallback;\n}\n\n/**\n * Prioritize components by specificity and importance\n * More specific components rank higher\n */\nexport function prioritizeComponents(components: string[]): string[] {\n const priority: { [key: string]: number } = {\n // High specificity - these are most valuable for matching\n \"segmented control\": 10,\n \"icon button\": 9,\n \"stepper\": 9,\n \"breadcrumb\": 9,\n \"calendar\": 9,\n \"carousel\": 9,\n \"accordion\": 9,\n \"datepicker\": 9,\n \"chart\": 8,\n \"table\": 8,\n \"navbar\": 8,\n \"sidebar\": 8,\n \"modal\": 8,\n \"tabs\": 8,\n \n // Medium specificity\n \"dropdown\": 7,\n \"slider\": 7,\n \"switch\": 7,\n \"checkbox\": 7,\n \"radio\": 7,\n \"textarea\": 7,\n \"pagination\": 7,\n \"card\": 7,\n \"menu\": 7,\n \"badge\": 6,\n \"tooltip\": 6,\n \"alert\": 6,\n \"progress\": 6,\n \"toast\": 6,\n \"avatar\": 6,\n \n // Lower specificity - common components\n \"button\": 5,\n \"input\": 5,\n \"list\": 4,\n \"grid\": 4,\n \"header\": 3,\n \"footer\": 3,\n \"icon\": 2,\n \"image\": 2,\n };\n\n return components.sort((a, b) => {\n const priorityA = priority[a] || 0;\n const priorityB = priority[b] || 0;\n return priorityB - priorityA;\n });\n}\n","/**\n * Design Query Extractor\n * \n * Main entry point for extracting semantic queries from Figma designs\n * optimized for Pinecone semantic/embedding-based search.\n */\n\nimport type { FigmaDesignContextResult } from \"../../clients/figma-client.js\";\nimport type { ComponentDescriptor } from \"./types.js\";\nimport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\nimport { DesignContextExtractor } from \"./design-context-extractor.js\";\nimport { buildSemanticQuery } from \"./query-builder.js\";\n\n/**\n * Extracts semantic descriptions from Figma design context for Pinecone search\n */\nexport class DesignQueryExtractor {\n private metadataExtractor: MetadataExtractorSimpler;\n private designContextExtractor: DesignContextExtractor;\n\n constructor() {\n this.metadataExtractor = new MetadataExtractorSimpler();\n this.designContextExtractor = new DesignContextExtractor();\n }\n\n /**\n * Extracts a semantic query optimized for embedding-based search from design context\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n if (!designContext.content || designContext.content.length === 0) {\n return fallbackQuery;\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item\n for (const item of designContext.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text;\n\n // Separate code from design tokens\n const parts = text.split(/These styles are contained in the design:/i);\n const codeSection = parts[0] || \"\";\n const tokensSection = parts[1] || \"\";\n\n // Extract from code and tokens\n this.designContextExtractor.extractFromCodeAndTokens(codeSection, tokensSection, descriptor);\n }\n }\n\n // Build semantic query from descriptor\n return buildSemanticQuery(descriptor, fallbackQuery);\n }\n\n /**\n * Extracts a semantic query from Figma metadata (XML-like structure)\n * Parses instance names and frame names to identify components\n */\n extractQueryFromMetadata(\n metadata: FigmaDesignContextResult,\n ): string {\n if (!metadata.content || metadata.content.length === 0) {\n return \"\";\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item (metadata is typically in text format with XML-like structure)\n for (const item of metadata.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const metadataText = item.text;\n // Extract all names from metadata and use them as keywords\n const names = this.metadataExtractor.extractNames(metadataText);\n descriptor.keywords.push(...names);\n }\n }\n\n // Build semantic query from descriptor (use empty string as fallback if no names found)\n return buildSemanticQuery(descriptor, \"\");\n }\n}\n\n// Re-export types and utilities\nexport type { ComponentDescriptor } from \"./types.js\";\nexport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\n","/**\n * Pinecone Search Service\n * Reusable service for semantic search of design system components\n * Uses Frida Pinecone Proxy API for secure access\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface ComponentMatch {\n id: string; // From match.id\n tag: string; // From metadata.tag\n score: number; // From match.score\n name: string; // From metadata.name\n framework: string; // From metadata.framework\n category: string; // From metadata.category\n overview: string; // From metadata.overview\n visual: string; // From metadata.visual\n technical: string; // From metadata.technical\n keywords: string[]; // From metadata.keywords\n}\n\nexport interface SearchOptions {\n minScore?: number;\n topK?: number;\n namespace?: string;\n}\n\nexport interface SearchResults {\n query: string;\n totalMatches: number;\n relevantMatches: number;\n matches: ComponentMatch[];\n searchMetadata: {\n minScore: number;\n topK: number;\n indexName: string;\n namespace?: string;\n };\n}\n\nexport interface PineconeSearchServiceOptions {\n namespace?: string;\n}\n\nexport class PineconeSearchService {\n private indexName: string;\n private namespace?: string;\n private minScore: number;\n private topK: number;\n private fridaEmbeddingUrl: string;\n private fridaApiKey: string;\n private fridaPineconeProxyUrl: string;\n private fridaEmbeddingModel: string;\n\n constructor(options: PineconeSearchServiceOptions = {}) {\n this.indexName = process.env.PINECONE_INDEX!;\n this.namespace = options.namespace;\n this.minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n this.topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n this.fridaEmbeddingUrl = process.env.FRIDA_EMBEDDING_URL!;\n this.fridaApiKey = process.env.FRIDA_BEARER_TOKEN!;\n this.fridaPineconeProxyUrl = process.env.FRIDA_PINECONE_PROXY_URL!;\n this.fridaEmbeddingModel = process.env.FRIDA_EMBEDDING_MODEL!;\n }\n\n /**\n * Generates embedding for a text using Frida API\n * @param text - Text to embed\n * @returns Promise<number[]> Embedding vector (1536 dimensions)\n */\n async generateEmbedding(text: string): Promise<number[]> {\n try {\n logger.debug(\"Calling Frida Embedding API...\");\n const startTime = Date.now();\n\n const response = await fetch(this.fridaEmbeddingUrl, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n Authorization: `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input: text,\n model: this.fridaEmbeddingModel,\n user_id: \"pinecone-search\",\n email: \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n\n logger.debug(`API response status: ${response.status}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"API Error response:\", errorText);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n logger.debug(\"Parsing API response...\");\n const data = (await response.json()) as {\n data?: Array<{ embedding?: number[] }>;\n };\n\n if (!data.data || !data.data[0] || !data.data[0].embedding) {\n logger.error(\"Invalid response format:\", JSON.stringify(data).substring(0, 200));\n throw new Error(\"Invalid API response format\");\n }\n\n const embedding = data.data[0].embedding;\n const elapsed = Date.now() - startTime;\n logger.debug(`✓ Embedding generated (${embedding.length} dims) in ${elapsed}ms`);\n\n return embedding; // Returns 1536-dimensional array\n } catch (error) {\n logger.error(\"Error generating embedding:\", error);\n throw new Error(`Failed to generate embedding: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Parses a Pinecone match to structured format\n * New simplified schema: tag, name, framework, category, overview, visual, technical, keywords\n */\n private parseMatch(match: {\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }): ComponentMatch {\n const metadata = match.metadata || {};\n\n return {\n id: match.id || \"unknown\",\n tag: (metadata.tag as string) || match.id || \"unknown\",\n score: match.score || 0,\n name: (metadata.name as string) || \"\",\n framework: (metadata.framework as string) || \"\",\n category: (metadata.category as string) || \"General\",\n overview: (metadata.overview as string) || \"\",\n visual: (metadata.visual as string) || \"\",\n technical: (metadata.technical as string) || \"\",\n keywords: Array.isArray(metadata.keywords) ? (metadata.keywords as string[]) : [],\n };\n }\n\n /**\n * Queries Pinecone via Frida Proxy API\n * @param embedding - Embedding vector\n * @param topK - Number of results to return\n * @param namespace - Optional namespace\n * @returns Query response from Pinecone\n */\n private async queryPineconeProxy(\n embedding: number[],\n topK: number,\n namespace?: string,\n ): Promise<{\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n }> {\n const url = `${this.fridaPineconeProxyUrl}/pinecone/data/${this.indexName}/query`;\n\n logger.debug(`Querying Frida Pinecone Proxy: ${url}${namespace ? ` (namespace: \"${namespace}\")` : \"\"}`);\n\n const requestBody: {\n vector: number[];\n topK: number;\n includeMetadata: boolean;\n namespace?: string;\n } = {\n vector: embedding,\n topK,\n includeMetadata: true,\n };\n\n // Add namespace to request body if provided\n if (namespace) {\n requestBody.namespace = namespace;\n }\n\n const startTime = Date.now();\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n const queryTime = Date.now() - startTime;\n logger.debug(`Proxy API response status: ${response.status} (${queryTime}ms)`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"Proxy API Error response:\", errorText);\n throw new Error(`Pinecone Proxy API Error: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json() as {\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n };\n\n return data;\n }\n\n /**\n * Searches for components in Pinecone via Frida Proxy\n * @param query - Search query\n * @param options - Search options\n * @returns Structured results\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResults> {\n if (!query || typeof query !== \"string\") {\n throw new Error(\"Query must be a non-empty string\");\n }\n logger.debug(`[DEBUG] options object: ${JSON.stringify(options)}`);\n logger.debug(`[DEBUG] options.topK: ${options.topK}, type: ${typeof options.topK}`);\n logger.debug(`[DEBUG] options.topK !== undefined: ${options.topK !== undefined}`);\n logger.debug(`[DEBUG] this.topK (instance): ${this.topK}`);\n\n const minScore =\n options.minScore !== undefined ? options.minScore : this.minScore;\n const topK = options.topK !== undefined ? options.topK : this.topK;\n // Namespace: prioritize options.namespace, then this.namespace\n const namespace = options.namespace !== undefined ? options.namespace : this.namespace;\n\n logger.debug(`Starting search - Query: \"${query}\", topK: ${topK}, minScore: ${minScore}${namespace ? `, namespace: \"${namespace}\"` : \"\"}`);\n\n // Generate embedding for the query\n const embedding = await this.generateEmbedding(query);\n\n // Query Pinecone via Frida Proxy\n logger.debug(`Querying Pinecone index \"${this.indexName}\" via Frida Proxy${namespace ? ` namespace \"${namespace}\"` : \"\"}...`);\n const startTime = Date.now();\n\n const queryResponse = await this.queryPineconeProxy(embedding, topK, namespace);\n const queryTime = Date.now() - startTime;\n logger.debug(`Query completed in ${queryTime}ms - Found ${queryResponse.matches?.length || 0} matches`);\n\n // Process results\n const allMatches = queryResponse.matches || [];\n const relevantMatches = allMatches.filter((m) => (m.score || 0) >= minScore);\n\n logger.debug(`Filtered results: ${relevantMatches.length} relevant (score >= ${minScore}) out of ${allMatches.length} total`);\n\n return {\n query,\n totalMatches: allMatches.length,\n relevantMatches: relevantMatches.length,\n matches: relevantMatches.map((match) => this.parseMatch(match)),\n searchMetadata: {\n minScore,\n topK,\n indexName: this.indexName,\n namespace: namespace,\n },\n };\n }\n\n /**\n * Gets details of a specific component by tag or id\n * @param tag - Component tag or id (e.g.: 'wtw-button-split', 'my-badge')\n * @returns Component details or null if it doesn't exist\n */\n async getComponentDetails(tag: string): Promise<ComponentMatch | null> {\n if (!tag || typeof tag !== \"string\") {\n throw new Error(\"Tag must be a non-empty string\");\n }\n\n // Search for the specific component\n const results = await this.search(tag, { topK: 10, minScore: 0 });\n\n // Find exact match by tag or id\n const exactMatch = results.matches.find(\n (m) => m.tag === tag || m.id === tag\n );\n\n if (exactMatch) {\n return exactMatch;\n }\n\n // If no exact match, return the closest one\n if (results.matches.length > 0) {\n return results.matches[0];\n }\n\n return null;\n }\n\n /**\n * Searches for multiple components by tags\n * @param tags - Array of component tags\n * @returns Array of component details\n */\n async getMultipleComponents(tags: string[]): Promise<ComponentMatch[]> {\n if (!Array.isArray(tags)) {\n throw new Error(\"Tags must be an array\");\n }\n\n const results = await Promise.all(\n tags.map((tag) => this.getComponentDetails(tag)),\n );\n\n return results.filter(\n (r): r is ComponentMatch => r !== null,\n );\n }\n}\n\n","/**\n * Formatters\n * Utilities to format search results in different formats\n */\n\nimport type {\n ComponentMatch,\n SearchResults,\n} from \"../services/pinecone/pinecone-service.js\";\n\nexport class Formatters {\n /**\n * Formats results in structured format (JSON-friendly)\n */\n static toStructured(searchResults: SearchResults): {\n query: string;\n summary: {\n totalMatches: number;\n relevantMatches: number;\n minScore: number;\n };\n components: Array<{\n id: string;\n tag: string;\n score: number;\n name: string;\n framework: string;\n category: string;\n overview: string;\n visual: string;\n technical: string;\n keywords: string[];\n }>;\n } {\n return {\n query: searchResults.query,\n summary: {\n totalMatches: searchResults.totalMatches,\n relevantMatches: searchResults.relevantMatches,\n minScore: searchResults.searchMetadata.minScore,\n },\n components: searchResults.matches.map((match) => ({\n id: match.id,\n tag: match.tag,\n score: match.score,\n name: match.name,\n framework: match.framework,\n category: match.category,\n overview: match.overview,\n visual: match.visual,\n technical: match.technical,\n keywords: match.keywords,\n })),\n };\n }\n\n /**\n * Formats results in readable markdown format\n */\n static toMarkdown(searchResults: SearchResults): string {\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return `## No similar components found\n\n**Query:** \"${searchResults.query}\"\n\nSuggestion: Try more general terms or verify that components are indexed.`;\n }\n\n //Verify to add or hide to show what was queried // **Query:** \"${searchResults.query}\"\n let markdown = `## Search Results\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n---\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag}\n\n**Technical Documentation:**\n${match.technical || \"No technical documentation available\"}\n\n---\n\n`;\n });\n\n return markdown;\n }\n\n /**\n * Formats multiple components for context in prompts\n * Uses JSON format for better LLM understanding\n */\n static matchesToContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Use JSON format for component documentation which works well with LLMs\n // This provides structured data that LLMs can parse better than plain text\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score, // Pinecone ranking\n overview: match.overview,\n visual: match.visual,\n keywords: match.keywords,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n /**\n * Formats components with only essential fields (tag, score, overview) for lightweight filtering\n * Used when sending to Frida for tag-only filtering\n */\n static matchesToLightweightContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Only include tag, score, and overview for lightweight filtering\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score,\n overview: match.overview,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n}\n\n","/**\n * Frida API Token Validator\n * \n * Validates a Frida API token against the stored configuration in Firebase.\n * \n * Retrieves the access configuration from Firestore and compares the provided\n * llmopsApiKey with the stored key. Uses secure comparison to prevent timing\n * attacks. Includes rate limiting to prevent brute-force attempts.\n */\n\nimport { logger } from \"../../utils/logger.js\";\n\nconst VALIDATION_URL = \"https://us-central1-figma2frida-mcp.cloudfunctions.net/validateFridaApiToken\";\n\nexport interface ValidationResult {\n valid: boolean;\n message: string;\n}\n\nexport interface ValidationError {\n message: string;\n status: string;\n}\n\n/**\n * Validates a Frida API token against the stored configuration.\n * \n * @param apiToken - The API token to validate\n * @returns Promise that resolves if token is valid, rejects if invalid\n * \n * @example Input:\n * await validateFridaApiToken(\"api-key-12345\");\n * \n * @example Success Response:\n * { result: { valid: true, message: \"API token is valid\" } }\n * \n * @example Error Response (Invalid token):\n * { error: { message: \"Invalid API token\", status: \"PERMISSION_DENIED\" } }\n * \n * @example Error Response (Rate limit):\n * { error: { message: \"Too many attempts. Please try again later.\", status: \"RESOURCE_EXHAUSTED\" } }\n * \n * @example Error Response (Config not found):\n * { error: { message: \"Access config document not found\", status: \"NOT_FOUND\" } }\n */\nexport async function validateFridaApiToken(apiToken: string): Promise<void> {\n logger.info(\"🔐 Validating Frida API token...\");\n \n try {\n const response = await fetch(VALIDATION_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n data: {\n llmopsApiKey: apiToken,\n },\n }),\n });\n\n const responseData = await response.json() as \n | { result: ValidationResult }\n | { error: ValidationError };\n\n // Check for success response\n if (response.ok && \"result\" in responseData && responseData.result?.valid === true) {\n logger.info(`✅ ${responseData.result.message || \"API token is valid\"}`);\n return;\n }\n\n // Handle error responses\n if (\"error\" in responseData) {\n const error = responseData.error;\n const errorMessage = error.message || \"Unknown error\";\n const errorStatus = error.status || \"UNKNOWN\";\n \n logger.error(`❌ Token validation failed: ${errorMessage}`);\n logger.error(` Status: ${errorStatus}`);\n \n if (errorStatus === \"RESOURCE_EXHAUSTED\") {\n logger.error(\" Rate limit exceeded. Please try again later.\");\n } else if (errorStatus === \"NOT_FOUND\") {\n logger.error(\" Access config not found. Please contact support.\");\n } else if (errorStatus === \"PERMISSION_DENIED\") {\n logger.error(\" Invalid API token. Please check your token and try again.\");\n }\n \n throw new Error(`Token validation failed: ${errorMessage} (${errorStatus})`);\n }\n\n // Handle unexpected response format\n logger.error(`❌ Unexpected validation response format: ${JSON.stringify(responseData)}`);\n throw new Error(\"Unexpected validation response format\");\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Token validation failed:\")) {\n // Re-throw validation errors as-is\n throw error;\n }\n \n // Handle network/request errors\n logger.error(\"❌ Failed to validate API token:\", error instanceof Error ? error.message : String(error));\n \n if (error instanceof Error) {\n // Check for network errors\n if (error.message.includes(\"fetch failed\") || error.message.includes(\"ECONNREFUSED\")) {\n logger.error(\" Network error: Could not reach validation service.\");\n logger.error(\" Please check your internet connection and try again.\");\n throw new Error(\"Network error: Could not reach validation service\");\n } else if (error.message.includes(\"timeout\")) {\n logger.error(\" Request timeout: Validation service did not respond in time.\");\n logger.error(\" Please try again later.\");\n throw new Error(\"Request timeout: Validation service did not respond in time\");\n }\n }\n \n throw new Error(`Token validation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n","/**\n * Frida AI Client\n * Optional client for Frida AI integration\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface FridaClientOptions {\n apiKey?: string;\n apiUrl?: string;\n model?: string;\n maxTokens?: number;\n}\n\nexport interface FridaResponse {\n success: boolean;\n error: string | null;\n response: string | null;\n metadata?: {\n model: string;\n tokensUsed: number | null;\n };\n}\n\nexport class FridaClient {\n private apiKey: string | undefined;\n private apiUrl: string | undefined;\n private model: string;\n private maxTokens: number;\n private enabled: boolean;\n\n constructor(options: FridaClientOptions = {}) {\n this.apiKey = options.apiKey || process.env.FRIDA_BEARER_TOKEN;\n this.apiUrl = options.apiUrl || process.env.FRIDA_API_URL;\n this.model = options.model || process.env.FRIDA_MODEL || \"gpt-5.1-codex\";\n this.maxTokens = options.maxTokens || (process.env.FRIDA_MAX_TOKENS ? parseInt(process.env.FRIDA_MAX_TOKENS, 10) : 4096);\n this.enabled = !!(this.apiKey && this.apiUrl);\n }\n\n /**\n * Checks if Frida is configured\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Generates the unified prompt for component recommendation\n * Optimized for Approach B: lightweight context for selection, technical docs handled separately\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert design system specialist.\nYour goal is to analyze the Figma design context and recommend the mostly suitable component(s) from the design system.\n\n**CONTEXT:**\nThe user has a Figma design element and needs to know which component from the library to use.\nBelow is a list of available components with their visual descriptions and overviews.\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**INSTRUCTIONS:**\n1. Analyze the user's design description (Question).\n2. Compare it against the **Visual** and **Overview** of the available components.\n3. Select the best matching component(s).\n4. Provide a brief reasoning for your selection.\n\n**RESPONSE FORMAT:**\nYour response must be concise and follow this format:\n\n🎯 **Recommended Component:** [Tag]\n**Confidence:** [High/Medium/Low]\n**Reasoning:** [1-2 sentences explaining why this visual/functional description matches the design]\n\nUSER QUESTION:\n${question}`;\n }\n\n /**\n * Generates a prompt specifically for filtering components by tags only\n * Returns only component tags that match the query description\n */\n buildFilterPrompt(query: string, context: string): string {\n return `You are a design system expert. Analyze the query and component list below.\n\n**QUERY:** ${query}\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**TASK:** \nAnalyze the query description and compare it against the component overviews and scores.\nReturn ONLY the component tags (comma-separated) that best match the query description.\n\n**RESPONSE FORMAT:**\nReturn only the tags separated by commas. Do not include explanations, reasoning, or any other text.\nExample format: tag1, tag2, tag3\n\n**IMPORTANT:** Only return tags that are in the available components list above.`;\n }\n\n /**\n * Asks a question to Frida AI\n * @param question - User question\n * @param context - Context with component information\n * @returns Frida response\n */\n async ask(question: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!question || typeof question !== \"string\") {\n return {\n success: false,\n error: \"Question must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI\");\n\n const prompt = this.buildPrompt(question, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Question length: ${question.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: \"figma_2frida_mcp@softtek.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n logger.debug(\"Response received successfully\");\n\n // Try to extract the response from different possible formats\n const answer =\n (data.response as string) ||\n (data.output as string) ||\n ((data.choices as Array<{ message?: { content?: string } }>)?.[0]\n ?.message?.content as string) ||\n (data.content as string) ||\n JSON.stringify(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerLength = typeof answer === \"string\" ? answer.length : String(answer).length;\n\n logger.debug(\"FRIDA AI RESPONSE RECEIVED\");\n logger.debug(`TOKENS USED: ${tokensUsed || 'N/A'}`);\n logger.debug(`Answer length: ${answerLength} chars`);\n logger.debug(`Total time: ${fetchTime}ms`);\n\n return {\n success: true,\n error: null,\n response: typeof answer === \"string\" ? answer : String(answer),\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n\n /**\n * Asks Frida AI to filter components and return only matching tags\n * Uses buildFilterPrompt instead of buildPrompt for tag-only responses\n * @param query - Search query description\n * @param context - Lightweight component context (tag, score, overview)\n * @returns Frida response with component tags\n */\n async askForFilter(query: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!query || typeof query !== \"string\") {\n return {\n success: false,\n error: \"Query must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI FOR FILTERING\");\n\n // Use buildFilterPrompt instead of buildPrompt\n const prompt = this.buildFilterPrompt(query, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Query length: ${query.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: \"figma_2frida_mcp@softtek.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n logger.debug(\"Response received successfully\");\n\n // Try to extract the response from different possible formats\n const answer =\n (data.response as string) ||\n (data.output as string) ||\n ((data.choices as Array<{ message?: { content?: string } }>)?.[0]\n ?.message?.content as string) ||\n (data.content as string) ||\n JSON.stringify(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerLength = typeof answer === \"string\" ? answer.length : String(answer).length;\n\n logger.debug(\"FRIDA AI FILTER RESPONSE RECEIVED\");\n logger.debug(`TOKENS USED: ${tokensUsed || 'N/A'}`);\n logger.debug(`Answer length: ${answerLength} chars`);\n logger.debug(`Total time: ${fetchTime}ms`);\n\n return {\n success: true,\n error: null,\n response: typeof answer === \"string\" ? answer : String(answer),\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI for filtering:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n}\n","/**\n * Library Filter Handler\n * Handles Frida AI filtering of component search results from Pinecone\n */\n\nimport type { ComponentMatch, SearchResults } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { logger } from \"../utils/logger.js\";\n\n/**\n * Parses component tags from Frida's response\n * Handles various formats: comma-separated, newline-separated, or list format\n */\nfunction parseTagsFromFridaResponse(response: string, availableTags: string[]): string[] {\n if (!response || typeof response !== \"string\") {\n return [];\n }\n\n // Normalize the response: remove markdown formatting, extra whitespace\n let normalized = response.trim();\n \n // Remove common markdown formatting\n normalized = normalized.replace(/\\*\\*/g, \"\"); // Remove bold\n normalized = normalized.replace(/#+/g, \"\"); // Remove headers\n normalized = normalized.replace(/```[\\s\\S]*?```/g, \"\"); // Remove code blocks\n \n // Try to extract tags from various formats\n // Format 1: Comma-separated (tag1, tag2, tag3)\n let tags: string[] = [];\n \n // Split by comma first\n const commaSplit = normalized.split(\",\").map(t => t.trim());\n \n // Also try splitting by newline\n const newlineSplit = normalized.split(/\\n+/).map(t => t.trim());\n \n // Combine both approaches and filter\n const allCandidates = [...commaSplit, ...newlineSplit]\n .map(tag => {\n // Remove common prefixes/suffixes\n tag = tag.replace(/^[-•*]\\s*/, \"\"); // Remove list markers\n tag = tag.replace(/^tag:\\s*/i, \"\"); // Remove \"tag:\" prefix\n tag = tag.replace(/^tags?:\\s*/i, \"\"); // Remove \"tags:\" prefix\n tag = tag.replace(/[.,;]$/, \"\"); // Remove trailing punctuation\n return tag.trim();\n })\n .filter(tag => tag.length > 0);\n\n // Match against available tags (case-insensitive)\n for (const candidate of allCandidates) {\n const candidateLower = candidate.toLowerCase();\n // Find exact match or partial match\n const matchedTag = availableTags.find(t => \n t.toLowerCase() === candidateLower || \n t.toLowerCase().includes(candidateLower) ||\n candidateLower.includes(t.toLowerCase())\n );\n \n if (matchedTag && !tags.includes(matchedTag)) {\n tags.push(matchedTag);\n }\n }\n\n logger.debug(`Parsed ${tags.length} tags from Frida response: ${tags.join(\", \")}`);\n return tags;\n}\n\nexport interface FilterComponentsOptions {\n query: string;\n searchResults: SearchResults;\n}\n\nexport interface FilterComponentsResult {\n filteredResults: SearchResults;\n wasFiltered: boolean;\n fridaResponseTime?: number;\n}\n\n/**\n * Filters component search results using Frida AI\n * If Frida is enabled, it will analyze the query and component overviews\n * to return only the most relevant component tags\n */\nexport async function filterComponentsWithFrida(\n options: FilterComponentsOptions\n): Promise<FilterComponentsResult> {\n const { query, searchResults } = options;\n\n // If no results, return early\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return {\n filteredResults: searchResults,\n wasFiltered: false,\n };\n }\n\n // Create FridaClient instance for filtering\n const fridaClient = new FridaClient();\n \n let filteredMatches: ComponentMatch[] = searchResults.matches;\n let wasFiltered = false;\n let fridaResponseTime: number | undefined;\n \n // If Frida is enabled, use it to filter components\n if (fridaClient.isEnabled()) {\n try {\n logger.debug(\"Using Frida AI to filter components...\");\n \n // Create lightweight context with only (tag, score, overview)\n const lightweightContext = Formatters.matchesToLightweightContext(searchResults.matches);\n \n // Call Frida with askForFilter method (uses buildFilterPrompt internally)\n const fridaStartTime = Date.now();\n const fridaResponse = await fridaClient.askForFilter(query, lightweightContext);\n fridaResponseTime = Date.now() - fridaStartTime;\n \n logger.debug(`Frida AI filtering completed in ${fridaResponseTime}ms - Success: ${fridaResponse.success}`);\n \n if (fridaResponse.success && fridaResponse.response) {\n // Parse tags from Frida response\n const availableTags = searchResults.matches.map(m => m.tag);\n const selectedTags = parseTagsFromFridaResponse(fridaResponse.response, availableTags);\n \n if (selectedTags.length > 0) {\n // Filter matches to only include selected tags\n filteredMatches = searchResults.matches.filter(match => \n selectedTags.includes(match.tag)\n );\n \n wasFiltered = true;\n logger.debug(`Frida filtered ${filteredMatches.length} components from ${searchResults.matches.length} total matches`);\n } else {\n logger.warn(\"Frida returned no valid tags, using all Pinecone results\");\n }\n } else {\n logger.warn(`Frida filtering failed: ${fridaResponse.error || \"Unknown error\"}, using all Pinecone results`);\n }\n } catch (fridaError) {\n logger.warn(`Frida filtering error: ${fridaError instanceof Error ? fridaError.message : String(fridaError)}, using all Pinecone results`);\n // Continue with all results if Frida fails\n }\n } else {\n logger.debug(\"Frida AI not configured, skipping filtering step\");\n }\n\n // Create filtered search results\n const filteredSearchResults: SearchResults = {\n ...searchResults,\n matches: filteredMatches,\n relevantMatches: filteredMatches.length,\n };\n\n return {\n filteredResults: filteredSearchResults,\n wasFiltered,\n fridaResponseTime,\n };\n}\n"],"mappings":"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","names":["require"]}
|
|
1
|
+
{"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/utils/design-query-extractor/metadata-extractor-simpler.ts","../src/figma2frida/utils/design-query-extractor/design-context-extractor.ts","../src/figma2frida/utils/design-query-extractor/query-builder.ts","../src/figma2frida/utils/design-query-extractor/index.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/services/auth/token-validator.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/handlers/library-filter-handler.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Figma MCP Proxy Server\n *\n * Bridge between Figma Desktop MCP and your design system (Pinecone + Frida AI).\n *\n * Tools:\n * 1. analyze_design - Get design context and generated code from Figma (main entry)\n * 2. analyze_frame - Screenshot of current selection for visual reference\n * 3. analyze_frame_extraction - Screenshot + metadata + design context; then get_components_from_library\n * 4. get_components_from_library - Search design system by query (Pinecone + Frida)\n */\n\n// ============================================================================\n// IMPORTS (before environment setup)\n// ============================================================================\nimport { z } from \"zod\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { FastMCP, type ContentResult, type Content } from \"fastmcp\";\nimport { createRequire } from \"module\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// ENVIRONMENT CONFIGURATION (set before logger import)\n// ============================================================================\nconst ENVIRONMENT = \"production\"; // Change mode to \"production\" / \"development\"\nprocess.env.NODE_ENV = ENVIRONMENT; // Set BEFORE importing logger\n\n// Now import logger (it will read NODE_ENV correctly)\nimport { logger } from \"./utils/logger.js\";\nimport { FigmaClient } from \"./clients/figma-client.js\";\n// import { FigmaDesignContextResult } from \"./clients/figma-client.js\";\n// import { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\n// import { ComponentExtractor } from \"./utils/component-extractor.js\";\n// import { ComponentLookupService } from \"./services/component-lookup.js\";\n// import type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor/index.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.js\";\nimport { authenticateMcpLogin } from \"./services/auth/token-validator.js\";\nimport { filterComponentsWithFrida } from \"./handlers/library-filter-handler.js\";\n\n// ============================================================================\n// VERSION INFO\n// ============================================================================\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst require = createRequire(import.meta.url);\n// When running from dist/figma2frida.js, __dirname is dist/, so go up one level to find package.json\nconst packageJson = require(join(__dirname, \"../package.json\"));\nconst MCP_VERSION = packageJson.version;\nconst LOCAL_VERSION = \"1.0.1\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${LOCAL_VERSION}) [${ENVIRONMENT}]`);\nlogger.info(`Transport: ${process.env.HTTP_STREAM === \"true\" ? \"HTTP Stream\" : \"stdio\"}`);\nlogger.info(`Node.js: ${process.version}`);\n\n// ============================================================================\n// HARDCODED CONFIGURATION - Set process.env variables\n// ============================================================================\nlogger.debug(\"Loading hardcoded configuration...\");\n\n// Pinecone Configuration\nprocess.env.PINECONE_INDEX = \"figma2frida\";\nprocess.env.PINECONE_MIN_SCORE = \"0.4\";\nprocess.env.PINECONE_TOP_K = \"12\";\nprocess.env.FRIDA_PINECONE_PROXY_URL = \"https://azf-frida-pinecone-proxy.azurewebsites.net\";\n\n// Frida AI Configuration\n// FRIDA_BEARER_TOKEN is now set from CLI argument (see below)\nprocess.env.FRIDA_API_URL = \"https://frida-llm-api.azurewebsites.net/v1/responses\";\nprocess.env.FRIDA_EMBEDDING_URL = \"https://frida-llm-api.azurewebsites.net/v1/embeddings\";\nprocess.env.FRIDA_EMBEDDING_MODEL = \"text-embedding-ada-002\";\nprocess.env.FRIDA_MODEL = \"gpt-5.1-codex\";\nprocess.env.FRIDA_MAX_TOKENS = \"9000\";\n\n// Server Configuration\nprocess.env.HTTP_STREAM = \"false\"; // Set to \"true\" for HTTP mode, \"false\" for stdio\nprocess.env.PORT = \"8080\";\n\n// Log configuration (only in debug mode - hide sensitive values in production)\nlogger.debug(`PINECONE_INDEX: ${process.env.PINECONE_INDEX}`);\nlogger.debug(`PINECONE_MIN_SCORE: ${process.env.PINECONE_MIN_SCORE}`);\nlogger.debug(`PINECONE_TOP_K: ${process.env.PINECONE_TOP_K}`);\nlogger.debug(`FRIDA_PINECONE_PROXY_URL: ${process.env.FRIDA_PINECONE_PROXY_URL}`);\nlogger.debug(`FRIDA_API_URL: ${process.env.FRIDA_API_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_URL: ${process.env.FRIDA_EMBEDDING_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_MODEL: ${process.env.FRIDA_EMBEDDING_MODEL}`);\nlogger.debug(`FRIDA_MODEL: ${process.env.FRIDA_MODEL}`);\nlogger.debug(`FRIDA_MAX_TOKENS: ${process.env.FRIDA_MAX_TOKENS}`);\nlogger.debug(`HTTP_STREAM: ${process.env.HTTP_STREAM}`);\nlogger.debug(`PORT: ${process.env.PORT}`);\nlogger.info(\"Configuration loaded\");\n\n// Parse command-line arguments - PINECONE_NAMESPACE and FRIDA_API_TOKEN as parameters\nconst argv = yargs(hideBin(process.argv))\n .option(\"project-id\", {\n type: \"string\",\n description: \"Pinecone namespace (required for component search)\",\n demandOption: true,\n })\n .option(\"frida-api-token\", {\n type: \"string\",\n description: \"Frida API token for authentication\",\n demandOption: true,\n })\n .parseSync();\n\n// Store and validate namespace from CLI\nconst PINECONE_NAMESPACE = argv.projectId?.trim();\nif (!PINECONE_NAMESPACE || PINECONE_NAMESPACE === \"\" || PINECONE_NAMESPACE === \"your_namespace_here\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --project-id. This argument is required for Pinecone search.\");\n process.exit(1);\n}\nlogger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE} (from CLI)`);\n\n// Validate and set FRIDA_BEARER_TOKEN from CLI argument\nconst FRIDA_TOKEN = argv.fridaApiToken?.trim();\nif (!FRIDA_TOKEN || FRIDA_TOKEN === \"\" || FRIDA_TOKEN === \"your_api_token_here\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --frida-api-token. This token is required for authentication.\");\n process.exit(1);\n}\n\nprocess.env.FRIDA_BEARER_TOKEN = FRIDA_TOKEN;\nlogger.debug(`FRIDA_API_TOKEN: ${FRIDA_TOKEN.substring(0, 8)}... (hidden)`);\n\n// ============================================================================\n// MCP LOGIN AUTHENTICATION\n// ============================================================================\n// Authenticate with llmopsApiKey + projectId before proceeding\ntry {\n await authenticateMcpLogin(FRIDA_TOKEN, argv.projectId);\n} catch (error) {\n logger.error(\"❌ SHUTDOWN: Authentication failed. MCP server cannot start without valid token.\");\n logger.public(\n `❌ ${error instanceof Error ? error.message : String(error)}`,\n );\n process.exit(1);\n}\n\n// Read HTTP_STREAM and PORT from environment variables (.env file)\nconst HTTP_STREAM = process.env.HTTP_STREAM === \"true\" || process.env.HTTP_STREAM === \"1\";\nconst PORT = parseInt(process.env.PORT || \"8080\", 10);\n\n\nconst server = new FastMCP({\n instructions: `You are a Figma design developer. Use the available tools to analyze Figma designs.`,\n name: \"figma2frida_mcp\",\n version: MCP_VERSION,\n});\n\n// Initialize Figma MCP client\nlogger.debug(\"Initializing Figma Client...\");\nconst figmaClient = new FigmaClient(\"http://127.0.0.1:3845/sse\");\nlogger.debug(\"Figma Client object created\");\n\n// Connect to Figma MCP on startup\nlet figmaConnected = false;\nlogger.debug(\"Starting initial connection attempt to Figma MCP (non-blocking)...\");\n\nconst connectionStartTime = Date.now();\nfigmaClient\n .connect()\n .then(() => {\n const connectionTime = Date.now() - connectionStartTime;\n figmaConnected = true;\n logger.debug(`Connected to Figma MCP (${connectionTime}ms)`);\n })\n .catch((error) => {\n const connectionTime = Date.now() - connectionStartTime;\n logger.warn(`Failed to connect to Figma MCP (${connectionTime}ms)`);\n logger.debug(\"Error type:\", error?.constructor?.name || typeof error);\n logger.debug(\"Error message:\", error instanceof Error ? error.message : String(error));\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(\"Error code:\", errorObj.code);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n logger.warn(\"Make sure Figma Desktop is running with MCP enabled at http://127.0.0.1:3845/sse\");\n logger.debug(\"Tools will attempt to reconnect when called\");\n });\n\n\n// TOOL 1: Get Design Context (Design Data and Generated Code)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_design\",\n description: `Get design context from a Figma node including design data and generated code.\n\n**What this does:**\n- Fetches design data and generated code from Figma\n- Returns React/TypeScript code based on the Figma design\n- Includes design tokens and styling information\n\n**Output:**\n- Generated React/TypeScript code\n- Design tokens and styles\n- Design structure information\n\n**Usage:**\n- Set withLibrarySearch to enable component library search flow (default: false)\n\n**Input:**\njson\n{\n \"withLibrarySearch\": false\n}`,\n annotations: {\n title: \"Analyze Design\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n withLibrarySearch: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Enable component library search flow (default: false). When true will trigger analyze_frame_extraction, when false call analyze_frame.\"),\n }),\n execute: async (args, _context) => {\n try {\n const withLibrarySearch = args.withLibrarySearch ?? false;\n logger.debug(`withLibrarySearch: ${withLibrarySearch}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const designContext = await figmaClient.getDesignContext();\n\n if (!designContext.content || designContext.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No design context returned\" }],\n };\n return result;\n }\n\n // Add mandatory workflow instruction - conditionally based on withLibrarySearch\n const workflowInstruction: Content = {\n type: \"text\" as const,\n text: `**MANDATORY NEXT STEP - YOU MUST COMPLETE:**\n\nAfter receiving this design context, you **MUST** call the tool ${withLibrarySearch ? '`analyze_frame_extraction`' : '`analyze_frame`'} to get the visual reference and keywords.\n`,\n };\n\n return {\n content: [...(designContext.content as Content[]), workflowInstruction],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get design context:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get design context: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n// TOOL 2: Get Screenshot (Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame\",\n description: `Get a screenshot of a Figma node for visual reference with UI element analysis.`,\n annotations: {\n title: \"Analyze Frame\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async (_context) => {\n try {\n // logger.debug(`Tool called with nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot();\n\n if (!screenshot.content || screenshot.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n };\n return result;\n }\n\n // Add instruction for AI to analyze the image and provide UI elements list\n const analysisInstruction: Content = {\n type: \"text\" as const,\n text: `**Screenshot Retrieved**\n\nYou **MUST** analyze the screenshot image above and generate pixel perfect code to the Figma design.\n\n**Output:**\nGenerate complete, pixel perfect code that visually matches the screenshot with pixel-perfect accuracy. The generated code should be indistinguishable from the design when rendered.\n\n**What to Identify:**\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars\n`,\n };\n\n return {\n content: [analysisInstruction, ...(screenshot.content as Content[])],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get screenshot:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get screenshot: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 2: FIGMA SUGGEST COMPONENTS\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL 3: Figma Extract Components: Analyze All Extracted (Frame + Metadata + Design) and get components from library\n// From already having a screen I want to suggest components from the library that fit. Will call get_components_from_library.\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame_extraction\",\n description: `Analyze all data from frame and extract to identify components and UI elements in parallel and return all results combined.\n\n**What this does:**\n- Executes tools 1 (screenshot), 2 (metadata), and 3 (design context) concurrently\n- Returns everything in one response: visual reference, structure, and generated code\n\n**Output:**\n- Keywords extracted from figma metadata and design context.\n\n**Input:**\njson\n{\n}\n`,\n annotations: {\n title: \"Analyze All Extracted\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async ( _context) => {\n try {\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n } as ContentResult;\n }\n\n\n const [screenshot, metadata, designContext] = await Promise.all([\n figmaClient.getScreenshot(),\n figmaClient.getMetadata(),\n figmaClient.getDesignContext(),\n ]);\n\n // Extract queries from metadata and design context\n const queryExtractor = new DesignQueryExtractor();\n\n // Extract query from metadata (using metadata-specific extraction)\n let metadataQuery = \"UI component\";\n try {\n // Use metadata-specific extraction method\n const metadataAsDesignContext = {\n content: metadata.content || []\n };\n metadataQuery = queryExtractor.extractQueryFromMetadata(metadataAsDesignContext);\n } catch (error) {\n logger.warn(\"Failed to extract query from metadata:\", error instanceof Error ? error.message : String(error));\n }\n\n // Extract query from design context\n let designContextQuery = \"UI component\";\n try {\n designContextQuery = queryExtractor.extractQuery(designContext, \"UI component\");\n } catch (error) {\n logger.warn(\"Failed to extract query from design context:\", error instanceof Error ? error.message : String(error));\n }\n\n const combined: Content[] = [];\n\n // Add screenshot first (needed for analysis)\n if (screenshot.content?.length) {\n combined.push(...(screenshot.content as Content[]));\n }\n\n // Add instruction to analyze screenshot and create description\n combined.push({\n type: \"text\" as const,\n text: `## 2. Frame Description\\n\\nYou **MUST** analyze the screenshot image above and identify all components and UI elements visible in the Figma frame.\\n\\n**What to Identify:**\\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars.`,\n });\n\n combined.push({\n type: \"text\" as const,\n text: `\n**MANDATORY NEXT STEP — YOU MUST COMPLETE:**\n\nAfter receiving this analyze_frame_extraction output, you **MUST** call the tool \\`get_components_from_library\\` with a \\`query\\` that describes the UI elements, components, or patterns from the design above (a description of the components found in the UI\").\n\n**Required call:**\n\\`\\`\\`json\n{\n \"query\": \"your description query of the components and UI elements found in the UI. MANDATORY: MUST Include '${metadataQuery}' and '${designContextQuery}' \"\n}\n`,\n });\n\n return { content: combined } as ContentResult;\n } catch (error) {\n logger.error(\"analyze_frame_extraction failed:\", error instanceof Error ? error.message : String(error));\n return {\n content: [{\n type: \"text\" as const,\n text: `❌ analyze_frame_extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n }],\n } as ContentResult;\n }\n },\n});\n\n// ============================================================================\n// TOOL 4: Get Components From Library BY Query\n// ============================================================================\n\nserver.addTool({\n name: \"get_components_from_library\",\n description: `Get components from library.`,\n annotations: {\n title: \"Get Components From Library\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n query: z\n .string()\n .describe(\"User query text to search for components in the library.\"),\n }),\n execute: async (args, _context) => {\n try {\n logger.debug(\"get_components_from_library called\");\n logger.debug(`query: ${args.query}`);\n\n // Create PineconeSearchService instance with namespace\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n\n // Search for components\n const searchResults = await searchService.search(args.query);\n\n // Filter components using Frida AI (if enabled)\n const { filteredResults } = await filterComponentsWithFrida({\n query: args.query,\n searchResults,\n });\n\n // Format results using Formatters\n const formattedResults = Formatters.toMarkdown(filteredResults);\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: formattedResults,\n },\n ],\n };\n } catch (error) {\n logger.error(\"get_components_from_library error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n };\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 3: IMPROVE LAYOUT AND DESIGN\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL: Improve Layout — Screenshot + refine generated code to match frame UI\n// ============================================================================\n\n// server.addTool({\n// name: \"improve_layout\",\n// description: `Get a screenshot of the Figma frame and improve the already generated code to look more like the frame UI.\n\n// **What this does:**\n// - Returns the screenshot image of the selected Figma node\n// - Instructs you to refine the existing generated code so it visually matches the frame better (spacing, alignment, typography, colors, etc.)\n\n// **When to use:**\n// - After you have generated code from \\`analyze_design\\` or \\`analyze_frame_extraction\\`\n// - When the output doesn't quite match the Figma design and you want to improve it\n\n// **Output:**\n// - Screenshot image\n// - Instruction to improve the code to match the frame UI\n\n// **Usage:**\n// - Provide a nodeId (e.g., \"315-2920\") or leave empty for current Figma selection\n\n// **Example:**\n// \\`\\`\\`json\n// {\n// \"nodeId\": \"315-2920\"\n// }\n// \\`\\`\\``,\n// annotations: {\n// title: \"Improve Layout\",\n// readOnlyHint: true,\n// openWorldHint: false,\n// },\n// parameters: z.object({\n// nodeId: z\n// .string()\n// .optional()\n// .describe('Figma node ID (e.g., \"315-2920\"). Leave empty for current selection.'),\n// }),\n// execute: async (args, _context) => {\n// try {\n// logger.debug(`improve_layout called with nodeId: ${args.nodeId ?? \"current selection\"}`);\n// logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n// if (!figmaConnected) {\n// logger.warn(\"Early return: figmaConnected is false\");\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n// }],\n// } as ContentResult;\n// }\n\n// logger.debug(\"Calling figmaClient.getScreenshot() for improve_layout...\");\n// const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n// if (!screenshot.content || screenshot.content.length === 0) {\n// return {\n// content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n// } as ContentResult;\n// }\n\n// const instruction: Content = {\n// type: \"text\" as const,\n// text: `**Improve Layout**\n\n// You **MUST** use the screenshot image above as the visual reference. Improve the already generated code so it looks more like the frame UI.\n\n// **What to refine:**\n// - Spacing, padding, and margins\n// - Alignment and layout\n// - Typography (font sizes, weights, line height)\n// - Colors and contrast\n// - Border radius, shadows, and other visual details\n// - Any mismatch between the code output and the Figma design\n\n// Output the improved code.`,\n// };\n\n// return {\n// content: [instruction, ...(screenshot.content as Content[])],\n// } as ContentResult;\n// } catch (error) {\n// logger.error(\"improve_layout failed:\", error instanceof Error ? error.message : String(error));\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: `❌ improve_layout failed: ${error instanceof Error ? error.message : String(error)}`,\n// }],\n// } as ContentResult;\n// }\n// },\n// });\n\n\n\n// ============================================================================\n// Start Server\n// ============================================================================\n\nif (HTTP_STREAM) {\n server.start({\n httpStream: {\n port: PORT,\n },\n transportType: \"httpStream\",\n });\n\n logger.info(\"Figma Proxy MCP Server running on HTTP Stream!\");\n logger.info(`Endpoint: http://localhost:${PORT}/mcp`);\n logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE || \"not set (use --project-id)\"}`);\n logger.debug(`\nTest with curl:\ncurl -X POST http://localhost:${PORT}/mcp \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'\n`);\n} else {\n server.start({ transportType: \"stdio\" });\n logger.info(\"Started with stdio transport (for MCP clients)\");\n}\n","/**\n * Structured Logger Utility\n * Provides leveled logging with environment-based filtering.\n *\n * IMPORTANT: In stdio mode, all logs must go to stderr to avoid interfering\n * with MCP's JSON-RPC protocol on stdout.\n *\n * public: User-facing messages (e.g. auth failure reason). Always written to\n * stderr with a FIGMA2FRIDA: prefix so MCP hosts can surface them to the user.\n */\n\nenum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n SILENT = 4,\n}\n\n/**\n * Gets the current log level dynamically.\n * This ensures it picks up changes to process.env.NODE_ENV made after import\n * (solving ESM hoisting issues).\n */\nfunction getLogLevel(): LogLevel {\n const isVerbose = process.argv.includes(\"--verbose\") || process.env.DEBUG === \"true\";\n const isProduction = process.env.NODE_ENV === \"production\";\n\n if (isProduction && !isVerbose) {\n return LogLevel.SILENT; // Production: No logs at all\n }\n \n // Development or Verbose: Show everything\n return LogLevel.DEBUG; \n}\n\n// Detect if we're in stdio mode (MCP uses stdout for JSON-RPC)\n// HTTP_STREAM is set in process.env before this module loads\nconst isStdioMode = process.env.HTTP_STREAM !== \"true\" && process.env.HTTP_STREAM !== \"1\";\n\n// Helper to write to stderr in stdio mode, stdout otherwise\nconst writeToLog = (level: string, message: string, ...args: any[]) => {\n const fullMessage = args.length > 0 \n ? `[${level}] ${message} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`\n : `[${level}] ${message}`;\n \n if (isStdioMode) {\n process.stderr.write(`${fullMessage}\\n`);\n } else {\n console.log(fullMessage);\n }\n};\n\nconst PUBLIC_PREFIX = \"FIGMA2FRIDA:\";\n\n/** Writes a single user-facing line to stderr (always, no level filter). */\nconst writePublic = (message: string) => {\n const line = `${PUBLIC_PREFIX} ${message}\\n`;\n if (isStdioMode) {\n process.stderr.write(line);\n } else {\n console.error(line);\n }\n};\n\nexport const logger = {\n debug: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.DEBUG) {\n writeToLog(\"DEBUG\", message, ...args);\n }\n },\n info: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.INFO) {\n writeToLog(\"INFO\", message, ...args);\n }\n },\n warn: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.WARN) {\n writeToLog(\"WARN\", message, ...args);\n }\n },\n error: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.ERROR) {\n writeToLog(\"ERROR\", message, ...args);\n }\n },\n /** User-facing message; always written to stderr with FIGMA2FRIDA: prefix. */\n public: (message: string) => {\n writePublic(message);\n },\n};\n\n","/**\n * Figma MCP Client Wrapper\n * Connects to official Figma Desktop MCP via SSE\n */\n\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FigmaDesignContextResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaScreenshotResult {\n content: Array<{\n type: string;\n data?: string;\n mimeType?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaMetadataResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\n/**\n * Client for communicating with official Figma Desktop MCP\n */\nexport class FigmaClient {\n private client: Client | null = null;\n private connected: boolean = false;\n private figmaUrl: string;\n\n constructor(figmaUrl: string = \"http://127.0.0.1:3845/sse\") {\n this.figmaUrl = figmaUrl;\n }\n\n /**\n * Connect to Figma MCP server\n */\n async connect(retries: number = 3): Promise<void> {\n if (this.connected && this.client) {\n logger.debug(\"Already connected, skipping connection attempt\");\n return;\n }\n\n logger.debug(\"Starting connection attempt\");\n logger.debug(`URL: ${this.figmaUrl}`);\n logger.debug(`Max retries: ${retries}`);\n logger.debug(`Current status: connected=${this.connected}, client=${!!this.client}`);\n\n for (let attempt = 0; attempt < retries; attempt++) {\n const attemptStartTime = Date.now();\n logger.debug(`Attempt ${attempt + 1}/${retries} starting...`);\n\n try {\n logger.debug(\"Creating MCP Client object...\");\n this.client = new Client(\n {\n name: \"figma-proxy-client\",\n version: \"1.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n );\n logger.debug(\"Client object created\");\n\n logger.debug(`Creating SSE Transport for: ${this.figmaUrl}`);\n const transport = new SSEClientTransport(new URL(this.figmaUrl));\n logger.debug(\"Transport object created\");\n\n logger.debug(\"Attempting to connect...\");\n const connectStartTime = Date.now();\n await this.client.connect(transport);\n const connectTime = Date.now() - connectStartTime;\n logger.debug(`Connection established in ${connectTime}ms`);\n\n this.connected = true;\n const totalTime = Date.now() - attemptStartTime;\n\n logger.debug(`Connected to Figma MCP (${totalTime}ms)`);\n return;\n } catch (error) {\n const attemptTime = Date.now() - attemptStartTime;\n logger.debug(`Connection attempt ${attempt + 1}/${retries} FAILED (${attemptTime}ms)`);\n logger.debug(`Error type: ${error?.constructor?.name || typeof error}`);\n logger.debug(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n\n // Log additional error properties if available\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(`Error code: ${errorObj.code}`);\n }\n if ('cause' in errorObj) {\n logger.debug(\"Error cause:\", errorObj.cause);\n }\n if ('status' in errorObj) {\n logger.debug(`HTTP status: ${errorObj.status}`);\n }\n if ('statusText' in errorObj) {\n logger.debug(`HTTP status text: ${errorObj.statusText}`);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n if (attempt === retries - 1) {\n logger.error(`All connection attempts failed (${retries} attempts)`);\n logger.error(`URL: ${this.figmaUrl}`);\n throw new Error(\n `Failed to connect to Figma MCP at ${this.figmaUrl} after ${retries} attempts. Make sure Figma Desktop is running with MCP enabled.`,\n );\n }\n\n const waitTime = 1000 * (attempt + 1);\n logger.debug(`Waiting ${waitTime}ms before retry...`);\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, waitTime),\n );\n logger.debug(\"Wait complete, retrying...\");\n }\n }\n }\n\n /**\n * Ensure connection is established\n */\n private async ensureConnected(): Promise<void> {\n if (!this.connected || !this.client) {\n logger.debug(\"ensureConnected() called - not connected, attempting connection...\");\n await this.connect();\n } else {\n logger.debug(\"ensureConnected() called - already connected, skipping\");\n }\n }\n\n /**\n * Normalize nodeId format: convert \"XXXX-XXXX\" to \"XXXX:XXXX\" for Figma MCP compatibility\n */\n private normalizeNodeId(nodeId?: string): string | undefined {\n if (!nodeId) return undefined;\n // Convert dash format to colon format (e.g., \"315-2920\" -> \"315:2920\")\n return nodeId.replace(/-/g, \":\");\n }\n\n /**\n * Call Figma's get_design_context tool\n */\n async getDesignContext(\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_design_context with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (code) , 1 (rules to use and ignore) and 3 (design tokens)\n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Generated React code\n parsedResult.content[1], // Item 1: Rules to Use and Ignore\n parsedResult.content[3], // Item 3: Design tokens/styles\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_design_context, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args\n });\n\n return result as FigmaDesignContextResult;\n }\n }\n\n /**\n * Call Figma's get_metadata tool to get actual node structure\n */\n async getMetadata(\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_metadata with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (raw metadata) \n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Metadata Raw\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_metadata, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n return result as FigmaMetadataResult;\n }\n }\n\n /**\n * Call Figma's get_screenshot tool\n * Note: clientLanguages and clientFrameworks are not needed for screenshots\n * (only required for get_design_context which generates code)\n */\n async getScreenshot(\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n // Normalize nodeId format for Figma MCP compatibility\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined to use frame current selection,\n },\n });\n\n return result as FigmaScreenshotResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_screenshot, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined,\n },\n });\n\n return result as FigmaScreenshotResult;\n }\n }\n\n /**\n * Close connection\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.connected = false;\n this.client = null;\n logger.debug(\"Disconnected from Figma MCP\");\n }\n }\n}\n\n","/**\n * Metadata Extractor (Simpler)\n *\n * Extracts ALL `name=\"...\"` / `name='...'` attribute values from the Figma\n * metadata XML-like text and returns them as a list.\n *\n * This is intentionally minimal (no heuristics, no categorization).\n */\nexport class MetadataExtractorSimpler {\n /**\n * Returns every `name=` attribute value in appearance order.\n * Automatically removes exact duplicates (case-sensitive) while preserving first-seen order.\n *\n * Example match:\n * `<frame id=\"28:2524\" name=\"Referral/New 1.1\" ...>`\n * ^^^^^^^^^^^^^^^\n */\n extractNames(metadataText: string): string[] {\n if (!metadataText) return [];\n\n const names: string[] = [];\n const seen = new Set<string>();\n const matches = metadataText.matchAll(/\\bname\\s*=\\s*([\"'])(.*?)\\1/gi);\n\n for (const match of matches) {\n const raw = match[2];\n const name = typeof raw === \"string\" ? raw.trim() : \"\";\n \n // Only add if not empty and not already seen (exact duplicate check)\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n\n return names;\n }\n}\n\n","/**\n * Design Context Extractor\n * Extracts component information from Figma design context (code + tokens)\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\nexport class DesignContextExtractor {\n /**\n * Extract semantic information from JSX/HTML code and design tokens\n */\n extractFromCodeAndTokens(code: string, tokens: string, descriptor: ComponentDescriptor): void {\n // Extract from code section\n this.extractFromCode(code, descriptor);\n\n // Extract from design tokens\n this.extractFromTokens(tokens, descriptor);\n }\n\n /**\n * Extract semantic information from JSX/HTML code\n */\n private extractFromCode(code: string, descriptor: ComponentDescriptor): void {\n // Extract all data-name attributes to understand component structure\n const dataNameMatches = code.matchAll(/data-name=[\"']([^\"']+)[\"']/gi);\n const dataNames: string[] = [];\n \n for (const match of dataNameMatches) {\n const name = match[1].trim();\n if (name && name.length > 0) {\n dataNames.push(name.toLowerCase());\n }\n }\n\n // Track primary component (usually the first/root data-name)\n const primaryDataName = dataNames[0] || \"\";\n\n // 1. EXTRACT HIERARCHY from data-name structure\n this.extractHierarchy(dataNames, descriptor);\n\n // 2. IDENTIFY ALL COMPONENT TYPES from data-names and elements\n this.identifyComponents(code, dataNames, descriptor);\n\n // 3. DETERMINE PURPOSE from primary component and text content\n this.determinePurpose(code, primaryDataName, descriptor);\n\n // 4. EXTRACT VISUAL CHARACTERISTICS\n this.extractVisualTraits(code, dataNames, descriptor);\n\n // 5. EXTRACT LAYOUT PATTERNS\n this.extractLayoutPatterns(code, descriptor);\n\n // 6. DETECT INTERACTIONS\n this.detectInteractions(code, descriptor);\n\n // 7. EXTRACT REACT PROPS AND STATE\n this.extractReactPropsAndState(code, descriptor);\n\n // 8. EXTRACT SIZE AND SPACING PATTERNS\n this.extractSizeAndSpacing(code, descriptor);\n\n // 9. EXTRACT BORDER AND STYLING PATTERNS\n this.extractBorderAndStyling(code, descriptor);\n\n // 10. EXTRACT ADDITIONAL KEYWORDS\n this.extractKeywords(code, dataNames, descriptor);\n }\n\n /**\n * Extract hierarchy structure from data-name attributes\n * Identifies structural parts like Header, Body, Footer, Container, etc.\n */\n private extractHierarchy(dataNames: string[], descriptor: ComponentDescriptor): void {\n const hierarchyKeywords = [\n 'header', 'footer', 'body', 'container', 'content', 'wrapper',\n 'main', 'sidebar', 'nav', 'navigation', 'section', 'panel',\n 'card', 'tile', 'box', 'frame', 'group', 'stack', 'row', 'column',\n 'top'\n ];\n\n for (const name of dataNames) {\n const lowerName = name.toLowerCase();\n \n // Check if this data-name represents a structural part\n for (const keyword of hierarchyKeywords) {\n if (lowerName.includes(keyword)) {\n // Normalize to common terms\n if (keyword === 'nav' || keyword === 'navigation') {\n if (!descriptor.hierarchy.includes('navigation')) {\n descriptor.hierarchy.push('navigation');\n }\n } else if (keyword === 'content' || keyword === 'wrapper' || keyword === 'container') {\n if (!descriptor.hierarchy.includes('container')) {\n descriptor.hierarchy.push('container');\n }\n } else if (keyword === 'section' || keyword === 'panel') {\n if (!descriptor.hierarchy.includes('section')) {\n descriptor.hierarchy.push('section');\n }\n } else if (!descriptor.hierarchy.includes(keyword)) {\n descriptor.hierarchy.push(keyword);\n }\n break;\n }\n }\n }\n }\n\n /**\n * Identify all component types in the design\n */\n private identifyComponents(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Extract React component/function names (e.g., \"function SearchInput\", \"const Button =\")\n const functionMatches = code.matchAll(/(?:function|const|export\\s+(?:default\\s+)?function)\\s+([A-Z][a-zA-Z0-9]*)/g);\n const componentNames: string[] = [];\n for (const match of functionMatches) {\n if (match[1]) componentNames.push(match[1].toLowerCase());\n }\n const componentNamesText = componentNames.join(\" \");\n\n // Combine all text for analysis\n const combinedText = allText + \" \" + componentNamesText;\n\n // Modal/Dialog/Overlay\n if (/modal|dialog|popup|overlay|sheet|drawer/i.test(combinedText)) {\n descriptor.components.add(\"modal\");\n }\n\n // Buttons - check component names, HTML tags, and data-names\n if (/<button/i.test(code) || /button|btn/i.test(combinedText)) {\n // Check for icon button first (more specific)\n if (/icon.*button|button.*icon|<button[^>]*>.*<img|<button[^>]*>.*<svg|<button[^>]*>.*icon/i.test(code) ||\n /showicon|iconbutton/i.test(combinedText)) {\n descriptor.components.add(\"icon button\");\n } else {\n descriptor.components.add(\"button\");\n }\n }\n\n // Form Inputs - check component names (e.g., SearchInput, TextInput), HTML tags, and data-names\n if (/<input/i.test(code) || /input|textfield|text.?field|searchinput|textinput/i.test(combinedText)) {\n descriptor.components.add(\"input\");\n // Check if it's a search input\n if (/search/i.test(combinedText) || /data-name.*search/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n if (/<textarea/i.test(code) || /textarea|text.?area/i.test(allText)) {\n descriptor.components.add(\"textarea\");\n }\n if (/<select/i.test(code) || /dropdown|select|picker|combobox/i.test(allText)) {\n descriptor.components.add(\"dropdown\");\n }\n if (/type=[\"']checkbox/i.test(code) || /checkbox|check.?box/i.test(allText)) {\n descriptor.components.add(\"checkbox\");\n }\n if (/type=[\"']radio/i.test(code) || /radio|radio.?button/i.test(allText)) {\n descriptor.components.add(\"radio\");\n }\n if (/switch|toggle/i.test(allText)) {\n descriptor.components.add(\"switch\");\n }\n if (/slider|range/i.test(allText)) {\n descriptor.components.add(\"slider\");\n }\n\n // Navigation - only detect if actual navbar/navigation element exists\n if (/<nav|<Navbar|navbar|nav.?bar|navigation.?bar|app.?bar/i.test(code)) {\n descriptor.components.add(\"navbar\");\n }\n if (/sidebar|side.?bar|side.?nav|drawer/i.test(allText)) {\n descriptor.components.add(\"sidebar\");\n }\n if (/breadcrumb|breadcrumbs|bread.?crumb/i.test(allText)) {\n descriptor.components.add(\"breadcrumb\");\n }\n if (/tab|tabs|tab.?bar|tab.?navigation/i.test(allText)) {\n descriptor.components.add(\"tabs\");\n }\n if (/menu|dropdown.?menu|context.?menu/i.test(allText)) {\n descriptor.components.add(\"menu\");\n }\n if (/pagination|pager|page.?navigation/i.test(allText)) {\n descriptor.components.add(\"pagination\");\n }\n\n // Data Display\n if (/<table|<tr|<td|<th/i.test(code) || /table|data.?table|grid.?table/i.test(allText)) {\n descriptor.components.add(\"table\");\n }\n if (/card|panel|tile/i.test(allText)) {\n descriptor.components.add(\"card\");\n }\n if (/list|list.?item/i.test(allText)) {\n descriptor.components.add(\"list\");\n }\n if (/grid|grid.?layout/i.test(allText)) {\n descriptor.components.add(\"grid\");\n }\n if (/calendar|date.?picker|date.?calendar/i.test(allText)) {\n descriptor.components.add(\"calendar\");\n }\n if (/chart|graph|visualization/i.test(allText)) {\n descriptor.components.add(\"chart\");\n }\n\n // Feedback\n if (/alert|notification|banner|message/i.test(allText)) {\n descriptor.components.add(\"alert\");\n }\n if (/badge|label|tag|chip/i.test(allText)) {\n descriptor.components.add(\"badge\");\n }\n if (/tooltip|popover|tip/i.test(allText)) {\n descriptor.components.add(\"tooltip\");\n }\n if (/progress|loader|spinner|loading/i.test(allText)) {\n descriptor.components.add(\"progress\");\n }\n if (/toast|snackbar/i.test(allText)) {\n descriptor.components.add(\"toast\");\n }\n\n // Layout - only detect if actual header/footer elements exist (not just data-name labels)\n if (/<header|<Header/i.test(code) || \n (/page.?header|site.?header|main.?header/i.test(allText) && !/data-name.*header/i.test(code))) {\n descriptor.components.add(\"header\");\n }\n if (/<footer|<Footer/i.test(code) || \n (/page.?footer|site.?footer|main.?footer/i.test(allText) && !/data-name.*footer/i.test(code))) {\n descriptor.components.add(\"footer\");\n }\n\n // Specialized\n if (/avatar|profile.?picture|user.?image/i.test(allText)) {\n descriptor.components.add(\"avatar\");\n }\n if (/stepper|steps|wizard/i.test(allText)) {\n descriptor.components.add(\"stepper\");\n }\n if (/accordion|collapsible|expandable/i.test(allText)) {\n descriptor.components.add(\"accordion\");\n }\n if (/carousel|slider|slideshow/i.test(allText)) {\n descriptor.components.add(\"carousel\");\n }\n if (/segmented.?control|segment/i.test(allText)) {\n descriptor.components.add(\"segmented control\");\n }\n }\n\n /**\n * Determine overall purpose of the design\n */\n private determinePurpose(code: string, primaryName: string, descriptor: ComponentDescriptor): void {\n const combinedText = (code + \" \" + primaryName).toLowerCase();\n\n // Action purposes\n if (/delete|remove|borrar/i.test(combinedText)) {\n descriptor.purpose = \"delete confirmation\";\n } else if (/edit|modify|change|update/i.test(combinedText)) {\n descriptor.purpose = \"edit form\";\n } else if (/create|new|add/i.test(combinedText)) {\n descriptor.purpose = \"create form\";\n } else if (/save|submit|apply/i.test(combinedText)) {\n descriptor.purpose = \"submit form\";\n } else if (/search|find|query/i.test(combinedText)) {\n descriptor.purpose = \"search interface\";\n } else if (/filter|sort|organize/i.test(combinedText)) {\n descriptor.purpose = \"data filtering\";\n } else if (/login|signin|sign.in|authenticate/i.test(combinedText)) {\n descriptor.purpose = \"authentication\";\n } else if (/register|signup|sign.up/i.test(combinedText)) {\n descriptor.purpose = \"registration\";\n } else if (/dashboard|overview|summary/i.test(combinedText)) {\n descriptor.purpose = \"dashboard\";\n } else if (/warning|alert|caution/i.test(combinedText)) {\n descriptor.purpose = \"warning\";\n } else if (/error|fail|problem/i.test(combinedText)) {\n descriptor.purpose = \"error\";\n } else if (/success|complete|done/i.test(combinedText)) {\n descriptor.purpose = \"success\";\n }\n }\n\n /**\n * Extract visual characteristics\n */\n private extractVisualTraits(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Check data-names specifically for icon types (e.g., \"Info icon\", \"Search icon\")\n for (const dataName of dataNames) {\n const lowerDataName = dataName.toLowerCase();\n if (/icon/i.test(lowerDataName)) {\n if (/info|information/i.test(lowerDataName)) {\n descriptor.visual.push(\"info icon\");\n descriptor.keywords.push(\"info icon\");\n } else if (/search|magnify/i.test(lowerDataName)) {\n descriptor.visual.push(\"search icon\");\n descriptor.keywords.push(\"search icon\");\n } else if (/warning|alert|caution/i.test(lowerDataName)) {\n descriptor.visual.push(\"warning icon\");\n } else if (/success|check|confirm/i.test(lowerDataName)) {\n descriptor.visual.push(\"success icon\");\n } else if (/error|danger/i.test(lowerDataName)) {\n descriptor.visual.push(\"error icon\");\n } else if (/close|exit|dismiss/i.test(lowerDataName)) {\n descriptor.visual.push(\"close icon\");\n }\n }\n }\n\n // Icons from general patterns\n if (/icon|svg/i.test(allText)) {\n if (/warning|alert|caution/i.test(allText)) {\n descriptor.visual.push(\"warning icon\");\n }\n if (/close|exit|dismiss|×|cancel/i.test(allText)) {\n descriptor.visual.push(\"close icon\");\n }\n if (/success|check|confirm|✓/i.test(allText)) {\n descriptor.visual.push(\"success icon\");\n }\n if (/error|danger|problem|×/i.test(allText)) {\n descriptor.visual.push(\"error icon\");\n }\n if (/info|information|help|\\?/i.test(allText)) {\n descriptor.visual.push(\"info icon\");\n }\n if (/search|magnify|🔍/i.test(allText)) {\n descriptor.visual.push(\"search icon\");\n }\n }\n\n // Images\n if (/<img|<image/i.test(code) || /image|picture|photo|imgDash|imgAvatar/i.test(allText)) {\n descriptor.visual.push(\"image\");\n }\n\n // Check for field/container patterns (indicates form input structure)\n if (/field.*container|input.*container|search.*text/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n }\n }\n\n /**\n * Extract layout patterns from styling\n */\n private extractLayoutPatterns(code: string, descriptor: ComponentDescriptor): void {\n // Flex layouts\n if (/flex-col|flex.col/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered vertical\");\n } else if (/flex-row/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered horizontal\");\n } else if (/flex/i.test(code)) {\n descriptor.layout.push(\"flex layout\");\n }\n\n // Grid layouts\n if (/grid-cols|grid.cols/i.test(code)) {\n descriptor.layout.push(\"grid layout\");\n }\n\n // Visual effects\n if (/rounded-\\[?[0-9]/i.test(code) || /rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n descriptor.layout.push(\"rounded\");\n }\n \n if (/shadow-\\[/i.test(code) || /shadow-(?:sm|md|lg|xl|2xl)/i.test(code)) {\n descriptor.layout.push(\"elevated\");\n }\n\n // Responsive indicators\n if (/responsive|mobile|desktop|tablet/i.test(code)) {\n descriptor.layout.push(\"responsive\");\n }\n }\n\n /**\n * Detect interaction patterns\n */\n private detectInteractions(code: string, descriptor: ComponentDescriptor): void {\n const lowerCode = code.toLowerCase();\n\n // Dialog interactions\n if (descriptor.components.has(\"modal\")) {\n if (/confirm|yes|no|ok|cancel/i.test(code)) {\n descriptor.interactions.add(\"confirmation\");\n }\n if (/dismiss|close|exit/i.test(code)) {\n descriptor.interactions.add(\"dismissible\");\n }\n }\n\n // Form interactions\n if (descriptor.components.has(\"input\") || descriptor.components.has(\"button\")) {\n if (/submit|save|send|apply/i.test(lowerCode)) {\n descriptor.interactions.add(\"form submission\");\n }\n if (/validate|validation|error|required/i.test(lowerCode)) {\n descriptor.interactions.add(\"validation\");\n }\n }\n\n // Navigation interactions\n if (descriptor.components.has(\"tabs\") || descriptor.components.has(\"menu\")) {\n descriptor.interactions.add(\"navigation\");\n }\n\n // Data interactions\n if (descriptor.components.has(\"table\") || descriptor.components.has(\"list\")) {\n if (/sort|filter|search/i.test(lowerCode)) {\n descriptor.interactions.add(\"data manipulation\");\n }\n if (/select|checkbox|radio/i.test(lowerCode)) {\n descriptor.interactions.add(\"selection\");\n }\n }\n }\n\n /**\n * Extract React props and TypeScript state types\n */\n private extractReactPropsAndState(code: string, descriptor: ComponentDescriptor): void {\n // Extract TypeScript interface/type definitions\n const interfaceMatches = code.matchAll(/(?:interface|type)\\s+(\\w+Props)\\s*\\{/gi);\n for (const match of interfaceMatches) {\n const interfaceName = match[1].toLowerCase();\n if (/input|search|field/i.test(interfaceName)) {\n descriptor.components.add(\"input\");\n }\n if (/button/i.test(interfaceName)) {\n descriptor.components.add(\"button\");\n }\n if (/modal|dialog/i.test(interfaceName)) {\n descriptor.components.add(\"modal\");\n }\n }\n\n // Extract props that indicate features\n if (/showLabel|showlabel/i.test(code)) {\n descriptor.keywords.push(\"label\");\n }\n if (/showInfoIcon|showinfoicon|showInfo|showinfo/i.test(code)) {\n descriptor.keywords.push(\"info icon\");\n descriptor.visual.push(\"info icon\");\n }\n if (/showHelper|showhelper|helperText|helpertext/i.test(code)) {\n descriptor.keywords.push(\"helper\");\n descriptor.keywords.push(\"helper text\");\n }\n if (/showIcon|showicon/i.test(code)) {\n descriptor.keywords.push(\"icon\");\n }\n if (/showSearch|showsearch/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.keywords.push(\"search icon\");\n }\n if (/filledText|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/className/i.test(code)) {\n descriptor.keywords.push(\"customizable\");\n }\n\n // Extract state types from TypeScript (e.g., state?: \"enabled\" | \"hover\" | \"error\")\n const stateMatches = code.matchAll(/state[?:].*[\"']([^\"']+)[\"']/gi);\n const states: string[] = [];\n for (const match of stateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n \n // Also extract from union types: \"enabled\" | \"hover\" | \"pressed\" | \"error\"\n const unionStateMatches = code.matchAll(/[\"'](enabled|hover|pressed|active-focus|read-only|error|success|disabled|loading|empty|filled)[\"']/gi);\n for (const match of unionStateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n\n // Process states\n for (const state of states) {\n if (state === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.visual.push(\"error state\");\n } else if (state === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.visual.push(\"success state\");\n } else if (state === \"disabled\") {\n descriptor.keywords.push(\"disabled\");\n } else if (state === \"loading\") {\n descriptor.components.add(\"progress\");\n } else if (state === \"hover\") {\n descriptor.keywords.push(\"hover\");\n descriptor.interactions.add(\"hover\");\n } else if (state === \"pressed\") {\n descriptor.keywords.push(\"pressed\");\n descriptor.interactions.add(\"press\");\n } else if (state === \"active-focus\") {\n descriptor.keywords.push(\"focus\");\n descriptor.keywords.push(\"active\");\n descriptor.interactions.add(\"focus\");\n } else if (state === \"read-only\") {\n descriptor.keywords.push(\"read only\");\n }\n }\n\n // Extract content types (e.g., content?: \"placeholder\" | \"filled text\")\n const contentMatches = code.matchAll(/content[?:].*[\"']([^\"']+)[\"']/gi);\n for (const match of contentMatches) {\n if (match[1]) {\n const content = match[1].toLowerCase();\n if (content.includes(\"placeholder\")) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (content.includes(\"filled\")) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (content.includes(\"empty\")) {\n descriptor.keywords.push(\"empty\");\n }\n }\n }\n \n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/filled.*text|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n }\n\n // Extract from data-name patterns that indicate search\n if (/data-name.*search|search.*text|search.*input/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n\n /**\n * Extract size and spacing patterns from className and styles\n */\n private extractSizeAndSpacing(code: string, descriptor: ComponentDescriptor): void {\n // Size patterns (e.g., size-[24px], h-[48px], w-[1440px])\n if (/size-\\[(\\d+)|h-\\[(\\d+)|w-\\[(\\d+)|height:\\s*(\\d+)|width:\\s*(\\d+)/i.test(code)) {\n const sizeMatches = code.matchAll(/(?:size|h|w|height|width)[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 64) {\n descriptor.keywords.push(\"large\");\n } else if (size >= 48) {\n descriptor.keywords.push(\"medium\");\n } else if (size >= 24) {\n descriptor.keywords.push(\"small\");\n }\n // Icon sizes\n if (size === 24 || size === 48 || size === 64) {\n descriptor.keywords.push(`${size}px icon`);\n }\n }\n }\n\n // Gap/spacing patterns (e.g., gap-[4px], gap-[12px], gap-[16px])\n if (/gap-\\[(\\d+)|gap:\\s*(\\d+)/i.test(code)) {\n const gapMatches = code.matchAll(/gap[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of gapMatches) {\n const gap = parseInt(match[1], 10);\n if (gap >= 16) {\n descriptor.keywords.push(\"spaced\");\n descriptor.layout.push(\"spaced layout\");\n } else if (gap >= 8) {\n descriptor.keywords.push(\"compact\");\n }\n }\n }\n\n // Padding patterns (e.g., p-[12px])\n if (/p-\\[(\\d+)|padding:\\s*(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"padded\");\n }\n\n // Max/min height/width patterns\n if (/max-h-\\[(\\d+)|min-h-\\[(\\d+)|max-w-\\[(\\d+)|min-w-\\[(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n }\n\n /**\n * Extract border and styling patterns\n */\n private extractBorderAndStyling(code: string, descriptor: ComponentDescriptor): void {\n // Border patterns\n if (/border\\s+border-\\[|border:\\s*1px|border-solid/i.test(code)) {\n descriptor.keywords.push(\"bordered\");\n // Check border color\n if (/border-\\[var\\(--color\\/border/i.test(code)) {\n descriptor.keywords.push(\"default border\");\n }\n if (/border-\\[var\\(--color\\/border\\/default/i.test(code)) {\n descriptor.keywords.push(\"border\");\n }\n }\n\n // Rounded corners (e.g., rounded-[8px], rounded-lg)\n if (/rounded-\\[(\\d+)|rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n const roundedMatches = code.matchAll(/rounded-\\[(\\d+)|rounded-(sm|md|lg|xl|full)/gi);\n for (const match of roundedMatches) {\n const value = match[1] || match[2];\n if (value === \"full\" || value === \"xl\") {\n descriptor.keywords.push(\"fully rounded\");\n } else {\n descriptor.keywords.push(\"rounded\");\n }\n }\n }\n\n // Background patterns\n if (/bg-\\[var\\(--color\\/surface|background:\\s*var\\(--color/i.test(code)) {\n descriptor.keywords.push(\"background\");\n if (/surface\\/flat|surface.*flat/i.test(code)) {\n descriptor.keywords.push(\"flat surface\");\n }\n if (/surface\\/floating|surface.*floating/i.test(code)) {\n descriptor.keywords.push(\"floating surface\");\n }\n }\n\n // Shadow patterns (already in layout, but add keywords)\n if (/shadow-\\[0px_0px_0px_0px/i.test(code)) {\n descriptor.keywords.push(\"no shadow\");\n } else if (/shadow-\\[|drop-shadow/i.test(code)) {\n descriptor.keywords.push(\"shadow\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden/i.test(code)) {\n descriptor.keywords.push(\"clipped\");\n }\n\n // Flex patterns (more detailed)\n if (/flex\\s+flex-\\[1_0_0\\]|flex-1/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n descriptor.layout.push(\"flexible layout\");\n }\n\n // Content stretch pattern\n if (/content-stretch/i.test(code)) {\n descriptor.keywords.push(\"stretched\");\n descriptor.layout.push(\"stretched layout\");\n }\n }\n\n /**\n * Extract additional keywords from code and data-names for Pinecone search\n */\n private extractKeywords(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = (code + \" \" + dataNames.join(\" \")).toLowerCase();\n\n // Dialog/modal keywords\n if (/modal|dialog|popup|overlay/i.test(allText)) {\n descriptor.keywords.push(\"dialog\");\n descriptor.keywords.push(\"overlay\");\n }\n\n // Destructive / irreversible action\n if (/delete|remove|borrar|irreversible|undo|destructive/i.test(allText)) {\n descriptor.keywords.push(\"destructive\");\n if (/irreversible|undo|no way to undo/i.test(allText)) {\n descriptor.keywords.push(\"irreversible\");\n }\n }\n\n // Button / action labels (common CTA words)\n if (/cancel|dismiss|close/i.test(allText)) {\n descriptor.keywords.push(\"cancel\");\n descriptor.keywords.push(\"dismissible\");\n }\n if (/\\bdelete\\b|remove|borrar/i.test(allText)) descriptor.keywords.push(\"delete\");\n if (/confirm|ok|submit|save|apply/i.test(allText)) descriptor.keywords.push(\"confirm\");\n\n // Support / hero icon (large centered icon)\n if (/support\\s*icon|hero|lead\\s*icon|centered\\s*icon|large\\s*icon/i.test(allText)) {\n descriptor.keywords.push(\"support icon\");\n descriptor.keywords.push(\"centered icon\");\n }\n\n // Structure keywords\n if (/header|body|footer|container/i.test(allText)) {\n if (/header.*body|body.*header/i.test(allText)) descriptor.keywords.push(\"header body\");\n }\n\n // Navigation / navbar keywords (e.g. NAV/Header, NAV/Top, Header/MenuPral)\n if (/data-name=[\"'][^\"']*\\bnav\\b|data-name=[\"'][^\"']*\\/nav\\b/i.test(allText) ||\n /\\bnav\\/|nav\\s*\\/|\\/nav\\b/i.test(allText)) {\n descriptor.keywords.push(\"navbar\");\n descriptor.keywords.push(\"navigation\");\n descriptor.keywords.push(\"top nav\");\n }\n if (/data-name=[\"'][^\"']*\\bmenu\\b|data-name=[\"'][^\"']*menu\\w*/i.test(allText)) {\n descriptor.keywords.push(\"menu\");\n }\n if (/data-name=[\"'][^\"']*\\btop\\b/i.test(allText) && /nav|header/i.test(allText)) {\n descriptor.keywords.push(\"top nav\");\n descriptor.keywords.push(\"header nav\");\n }\n // Nav links: multiple <p> inside nav-like structure\n const pCount = (code.match(/<p\\b|<\\/p>/gi) || []).length;\n if (pCount >= 3 && /nav|NAV|header|menu/i.test(allText)) {\n descriptor.keywords.push(\"nav links\");\n descriptor.keywords.push(\"navigation links\");\n }\n\n // Text / label / heading elements (<p>, <h1>-<h6>, <label>, <span>, etc.)\n if (/<p\\b|<\\/p>/i.test(code)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/<h[1-6]\\b|<\\/h[1-6]>/i.test(code)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/<label\\b|<\\/label>/i.test(code)) descriptor.keywords.push(\"label\");\n if (/<span\\b|<\\/span>/i.test(code)) {\n descriptor.keywords.push(\"text\");\n descriptor.keywords.push(\"label\");\n }\n if (/<figcaption\\b|<caption\\b/i.test(code)) descriptor.keywords.push(\"caption\");\n if (/<blockquote\\b/i.test(code)) descriptor.keywords.push(\"quote\");\n\n // Data-name hints for text roles (e.g. data-name=\"Title\", data-name=\"Description\")\n if (/data-name=[\"'][^\"']*\\btext\\b/i.test(allText)) descriptor.keywords.push(\"text\");\n if (/data-name=[\"'][^\"']*\\blabel\\b/i.test(allText)) {\n descriptor.keywords.push(\"label\");\n // Check for \"Label container\" pattern\n if (/data-name=[\"'][^\"']*label.*container/i.test(allText)) {\n descriptor.keywords.push(\"label container\");\n }\n }\n if (/data-name=[\"'][^\"']*\\btitle\\b/i.test(allText)) {\n descriptor.keywords.push(\"title\");\n descriptor.keywords.push(\"heading\");\n }\n if (/data-name=[\"'][^\"']*\\bheading\\b/i.test(allText)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/data-name=[\"'][^\"']*\\b(paragraph|description)\\b/i.test(allText)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/data-name=[\"'][^\"']*\\bsubtitle\\b/i.test(allText)) descriptor.keywords.push(\"subtitle\");\n if (/data-name=[\"'][^\"']*\\bbody\\b/i.test(allText)) descriptor.keywords.push(\"body text\");\n \n // Field/Container patterns\n if (/data-name=[\"'][^\"']*field.*container|data-name=[\"'][^\"']*input.*container/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n descriptor.keywords.push(\"field container\");\n }\n if (/data-name=[\"'][^\"']*search/i.test(allText)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n if (/data-name=[\"'][^\"']*search.*text|data-name=[\"'][^\"']*search.*input|data-name=[\"'][^\"']*search\\s*\\+/i.test(allText)) {\n descriptor.keywords.push(\"search input\");\n descriptor.keywords.push(\"search\");\n }\n\n // State combinations in data-names (e.g., \"State=enabled, Content=filled text\")\n const stateContentMatches = code.matchAll(/data-name=[\"']([^\"']*state[^\"']*)[\"']/gi);\n for (const match of stateContentMatches) {\n const stateContent = match[1].toLowerCase();\n if (/state.*enabled/i.test(stateContent)) {\n descriptor.keywords.push(\"enabled\");\n }\n if (/state.*disabled/i.test(stateContent)) {\n descriptor.keywords.push(\"disabled\");\n }\n if (/state.*error/i.test(stateContent)) {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (/state.*success/i.test(stateContent)) {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n if (/content.*filled|content.*filled.*text/i.test(stateContent)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/content.*placeholder/i.test(stateContent)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/content.*empty/i.test(stateContent)) {\n descriptor.keywords.push(\"empty\");\n }\n }\n\n // Vector/Icon patterns in data-names\n if (/data-name=[\"'][^\"']*\\bvector\\b/i.test(allText)) {\n descriptor.keywords.push(\"vector\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Import patterns (images, SVGs)\n if (/import\\s+img|import.*from.*svg|import.*from.*asset/i.test(code)) {\n descriptor.visual.push(\"image\");\n descriptor.keywords.push(\"image import\");\n }\n if (/import.*svg/i.test(code)) {\n descriptor.keywords.push(\"svg\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Size/layout hints from code\n if (/size-\\[64|h-\\[64|w-\\[64|64px|size-\\[48|h-\\[48/i.test(code)) descriptor.keywords.push(\"large icon\");\n if (/gap-\\[16\\]|gap-\\[24\\]|gap-\\[32\\]/i.test(code)) descriptor.keywords.push(\"spaced\");\n if (/rounded-\\[8\\]|rounded-\\[12\\]|rounded-lg/i.test(code)) descriptor.keywords.push(\"rounded\");\n\n // Shadow / elevation from code\n if (/shadow-\\[|drop-shadow|elevation/i.test(allText)) descriptor.keywords.push(\"shadow\");\n\n // Conditional rendering patterns (e.g., if (state === \"enabled\" && content === \"filled text\"))\n if (/if\\s*\\(.*state.*===|if\\s*\\(.*content.*===/i.test(code)) {\n descriptor.keywords.push(\"conditional\");\n descriptor.keywords.push(\"stateful\");\n }\n\n // CSS class patterns (e.g., css-ew64yg, css-4hzbpn)\n if (/css-[a-z0-9]+/i.test(code)) {\n descriptor.keywords.push(\"styled\");\n }\n\n // Relative/absolute positioning\n if (/relative|absolute/i.test(code)) {\n descriptor.keywords.push(\"positioned\");\n }\n\n // Shrink/grow patterns\n if (/shrink-0|grow|flex-\\[1_0_0\\]/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n }\n\n // Min/max width/height patterns\n if (/min-w-|max-w-|min-h-|max-h-/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden|overflow-scroll/i.test(code)) {\n descriptor.keywords.push(\"overflow\");\n }\n\n // Inset patterns (e.g., inset-[8.33%])\n if (/inset-\\[/i.test(code)) {\n descriptor.keywords.push(\"inset\");\n }\n\n // Var() CSS variable patterns\n if (/var\\(--color|var\\(--typescale/i.test(code)) {\n descriptor.keywords.push(\"design tokens\");\n descriptor.keywords.push(\"themed\");\n }\n\n // Extract className values for additional patterns\n const classNameMatches = code.matchAll(/className=[\"']([^\"']+)[\"']/gi);\n for (const match of classNameMatches) {\n const className = match[1].toLowerCase();\n // Extract meaningful class patterns\n if (/flex|grid/i.test(className)) {\n descriptor.layout.push(\"flex layout\");\n }\n if (/items-center|justify-center/i.test(className)) {\n descriptor.layout.push(\"centered\");\n }\n if (/gap-/i.test(className)) {\n descriptor.keywords.push(\"spaced\");\n }\n if (/rounded/i.test(className)) {\n descriptor.keywords.push(\"rounded\");\n }\n if (/shadow/i.test(className)) {\n descriptor.keywords.push(\"shadow\");\n }\n }\n\n // Extract default prop values (e.g., showLabel = true, state = \"enabled\")\n const defaultPropMatches = code.matchAll(/(\\w+)\\s*=\\s*[\"']?([^\"',\\s\\)]+)[\"']?/gi);\n for (const match of defaultPropMatches) {\n const propName = match[1].toLowerCase();\n const propValue = match[2].toLowerCase();\n if (propName === \"state\" && propValue) {\n if (propValue === \"enabled\") descriptor.keywords.push(\"enabled\");\n if (propValue === \"disabled\") descriptor.keywords.push(\"disabled\");\n if (propValue === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (propValue === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n }\n if (propName === \"content\" && propValue) {\n if (propValue.includes(\"placeholder\")) descriptor.keywords.push(\"placeholder\");\n if (propValue.includes(\"filled\")) descriptor.keywords.push(\"filled\");\n }\n }\n }\n\n /**\n * Extract visual characteristics from design tokens\n * Parses Figma design token format: \"TokenName: Value\" or \"TokenName/SubToken: Value\"\n */\n private extractFromTokens(tokens: string, descriptor: ComponentDescriptor): void {\n if (!tokens || tokens.trim().length === 0) return;\n\n if (!descriptor.visual) descriptor.visual = [];\n if (!descriptor.colors) descriptor.colors = [];\n if (!descriptor.typography) descriptor.typography = [];\n if (!descriptor.effects) descriptor.effects = [];\n if (!descriptor.layout) descriptor.layout = [];\n if (!descriptor.keywords) descriptor.keywords = [];\n\n // Parse tokens - they're comma-separated: \"Token: Value, Token2: Value\"\n const tokenEntries = tokens.split(',').map(t => t.trim());\n\n for (const entry of tokenEntries) {\n // Extract token name and value\n // Format: \"TokenName/SubToken: Value\" or \"TokenName: Value\"\n const match = entry.match(/^([^:]+):\\s*(.+)$/);\n if (!match) continue;\n\n const tokenName = match[1].trim();\n const tokenValue = match[2].trim();\n const lowerTokenName = tokenName.toLowerCase();\n\n // Extract semantic color names\n if (lowerTokenName.includes('color') || lowerTokenName.includes('background') || \n lowerTokenName.includes('icon') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('action') || lowerTokenName.includes('border')) {\n \n // Extract semantic color category\n if (lowerTokenName.includes('warning')) {\n if (!descriptor.colors.includes('warning')) {\n descriptor.colors.push('warning');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('warning background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('warning icon');\n }\n } else if (lowerTokenName.includes('error') || lowerTokenName.includes('danger')) {\n if (!descriptor.colors.includes('error')) {\n descriptor.colors.push('error');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('error background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('error icon');\n }\n } else if (lowerTokenName.includes('success')) {\n if (!descriptor.colors.includes('success')) {\n descriptor.colors.push('success');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('success background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('success icon');\n }\n } else if (lowerTokenName.includes('primary') || lowerTokenName.includes('main') || lowerTokenName.includes('brand')) {\n if (!descriptor.colors.includes('primary')) {\n descriptor.colors.push('primary');\n }\n if (lowerTokenName.includes('brand')) {\n descriptor.keywords.push('brand color');\n }\n } else if (lowerTokenName.includes('secondary') || lowerTokenName.includes('alternative')) {\n if (!descriptor.colors.includes('secondary')) {\n descriptor.colors.push('secondary');\n }\n } else if (lowerTokenName.includes('default') || lowerTokenName.includes('neutral')) {\n if (!descriptor.colors.includes('neutral')) {\n descriptor.colors.push('neutral');\n }\n } else if (lowerTokenName.includes('info')) {\n if (!descriptor.colors.includes('info')) {\n descriptor.colors.push('info');\n }\n descriptor.visual.push('info color');\n }\n }\n\n // Extract typography information\n if (lowerTokenName.includes('font') || lowerTokenName.includes('typescale') || \n lowerTokenName.includes('headline') || lowerTokenName.includes('body') ||\n lowerTokenName.includes('button') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('label') || lowerTokenName.includes('helper') ||\n lowerTokenName.includes('placeholder')) {\n \n if (lowerTokenName.includes('headline')) {\n if (!descriptor.typography.includes('headline')) {\n descriptor.typography.push('headline');\n }\n // Extract size if available\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large headline');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium headline');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small headline');\n }\n // Desktop/Mobile variants\n if (lowerTokenName.includes('desktop')) {\n descriptor.keywords.push('desktop');\n }\n if (lowerTokenName.includes('mobile')) {\n descriptor.keywords.push('mobile');\n }\n } else if (lowerTokenName.includes('body')) {\n if (!descriptor.typography.includes('body')) {\n descriptor.typography.push('body text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large body');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium body');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small body');\n }\n // Strong/default variations\n if (lowerTokenName.includes('strong')) {\n descriptor.typography.push('bold');\n descriptor.keywords.push('strong text');\n }\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default text');\n }\n } else if (lowerTokenName.includes('button')) {\n if (!descriptor.typography.includes('button')) {\n descriptor.typography.push('button text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large button');\n descriptor.keywords.push('large button');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium button');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small button');\n }\n } else if (lowerTokenName.includes('label')) {\n descriptor.keywords.push('label');\n if (lowerTokenName.includes('large')) {\n descriptor.keywords.push('large label');\n }\n } else if (lowerTokenName.includes('helper')) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n } else if (lowerTokenName.includes('placeholder')) {\n descriptor.keywords.push('placeholder');\n }\n\n // Extract font weight if mentioned\n if (tokenValue.includes('weight') || tokenValue.includes('700') || tokenValue.includes('bold')) {\n descriptor.typography.push('bold');\n } else if (tokenValue.includes('400') || tokenValue.includes('regular')) {\n descriptor.typography.push('regular');\n } else if (tokenValue.includes('600') || tokenValue.includes('semibold')) {\n descriptor.typography.push('semibold');\n }\n\n // Extract line height and letter spacing\n if (tokenValue.includes('lineHeight') || tokenValue.includes('line-height')) {\n descriptor.keywords.push('line height');\n }\n if (tokenValue.includes('letterSpacing') || tokenValue.includes('letter-spacing')) {\n descriptor.keywords.push('letter spacing');\n }\n }\n\n // Extract elevation and shadow effects\n if (lowerTokenName.includes('elevation') || lowerTokenName.includes('shadow') || \n lowerTokenName.includes('effect')) {\n \n if (lowerTokenName.includes('floating') || lowerTokenName.includes('raised')) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n } else if (lowerTokenName.includes('drop') || lowerTokenName.includes('shadow')) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n } else if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat');\n descriptor.keywords.push('no elevation');\n }\n }\n\n // Extract surface types\n if (lowerTokenName.includes('surface')) {\n if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat surface');\n } else if (lowerTokenName.includes('floating')) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('raised')) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('state')) {\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default state');\n }\n }\n }\n\n // Extract background types\n if (lowerTokenName.includes('background')) {\n if (lowerTokenName.includes('alternative')) {\n descriptor.keywords.push('alternative background');\n if (lowerTokenName.includes('strong')) {\n descriptor.keywords.push('strong background');\n }\n } else if (lowerTokenName.includes('brand')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('brand background');\n }\n }\n\n // Extract border radius from rounded values\n if (lowerTokenName.includes('rounded') || lowerTokenName.includes('radius')) {\n descriptor.layout.push('rounded corners');\n }\n\n // Extract action colors (for buttons, CTAs)\n if (lowerTokenName.includes('action')) {\n if (lowerTokenName.includes('main') || lowerTokenName.includes('primary')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('primary action');\n } else if (lowerTokenName.includes('alternative')) {\n descriptor.colors.push('secondary');\n descriptor.keywords.push('alternative action');\n }\n if (lowerTokenName.includes('selected')) {\n descriptor.keywords.push('selected');\n }\n if (lowerTokenName.includes('on main') || lowerTokenName.includes('on-main')) {\n descriptor.keywords.push('on primary');\n }\n }\n }\n\n // Additional pattern matching for complex token formats\n // Match patterns like \"Background/warning: #FFFAEB\"\n const colorPattern = /(?:Background|Icon|Text|Action|Border)\\/([^:,\\s]+)/gi;\n let colorMatch;\n while ((colorMatch = colorPattern.exec(tokens)) !== null) {\n const semanticName = colorMatch[1].toLowerCase();\n if (semanticName && !descriptor.colors.includes(semanticName)) {\n descriptor.colors.push(semanticName);\n }\n }\n\n // Match elevation patterns\n if (/Elevation\\s+(?:raised|floating|flat)/i.test(tokens)) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n }\n\n // Detect Effect types (DROP_SHADOW, etc.)\n if (/Effect\\(.*DROP_SHADOW/i.test(tokens)) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n }\n\n // Component specific exceptions (e.g., \"Component specific exceptions/Placeholder\")\n if (/Component\\s+specific\\s+exceptions/i.test(tokens)) {\n if (/placeholder/i.test(tokens)) {\n descriptor.keywords.push('placeholder');\n }\n if (/header.*icon/i.test(tokens)) {\n descriptor.keywords.push('header icon');\n }\n if (/button/i.test(tokens)) {\n descriptor.keywords.push('button');\n }\n }\n\n // Helper text detection\n if (/helper.*text|typescale.*helper/i.test(tokens)) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n }\n\n // Token-based keywords\n if (/Action\\/main|action.*main/i.test(tokens) && /#EC0000|#e00|red|danger/i.test(tokens)) {\n descriptor.keywords.push('destructive');\n descriptor.keywords.push('primary action');\n }\n if (/Elevation\\s+floating|elevation.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating');\n }\n if (/Background\\/warning|Icon\\/warning|warning/i.test(tokens)) {\n descriptor.keywords.push('warning');\n }\n if (/Headline|headline|typescale/i.test(tokens)) {\n descriptor.keywords.push('headline');\n }\n if (/Body\\/Body|body.*default/i.test(tokens)) {\n descriptor.keywords.push('body text');\n }\n if (/Button Large|button\\/large|Button Large/i.test(tokens)) {\n descriptor.keywords.push('large button');\n }\n if (/Surface\\/floating|surface.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n }\n if (/Surface\\/raised|surface.*raised/i.test(tokens)) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n }\n\n // Extract more color patterns (Text/info, Icon/soft, etc.)\n if (/Text\\/info|text.*info/i.test(tokens)) {\n descriptor.colors.push('info');\n descriptor.keywords.push('info text');\n }\n if (/Text\\/soft|text.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft text');\n }\n if (/Icon\\/soft|icon.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft icon');\n }\n if (/Icon\\/default|icon.*default/i.test(tokens)) {\n descriptor.keywords.push('default icon');\n }\n\n // Extract more typography patterns\n if (/Body.*Medium.*Strong|body.*medium.*strong/i.test(tokens)) {\n descriptor.typography.push('bold');\n descriptor.typography.push('medium body');\n descriptor.keywords.push('strong text');\n }\n if (/Body.*Medium.*Default|body.*medium.*default/i.test(tokens)) {\n descriptor.typography.push('medium body');\n descriptor.keywords.push('default text');\n }\n if (/Headline.*Desktop|headline.*desktop/i.test(tokens)) {\n descriptor.keywords.push('desktop');\n }\n if (/Headline.*Mobile|headline.*mobile/i.test(tokens)) {\n descriptor.keywords.push('mobile');\n }\n\n // Extract Surface/State patterns\n if (/Surface\\/State|surface.*state/i.test(tokens)) {\n descriptor.keywords.push('state surface');\n if (/default/i.test(tokens)) {\n descriptor.keywords.push('default state');\n }\n }\n\n // Extract more background patterns\n if (/Background\\/alternative|background.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative background');\n }\n if (/Background\\/alternative.*strong|background.*alternative.*strong/i.test(tokens)) {\n descriptor.keywords.push('strong alternative background');\n }\n\n // Extract more border patterns\n if (/Border\\/default|border.*default/i.test(tokens)) {\n descriptor.keywords.push('default border');\n }\n if (/Border\\/alternative|border.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative border');\n }\n\n // Extract Font family patterns\n if (/Font\\(family:|font.*family/i.test(tokens)) {\n descriptor.keywords.push('custom font');\n if (/Santander/i.test(tokens)) {\n descriptor.keywords.push('santander font');\n }\n }\n\n // Extract letter spacing and line height from Font() patterns\n if (/letterSpacing|letter-spacing/i.test(tokens)) {\n descriptor.keywords.push('letter spacing');\n }\n if (/lineHeight|line-height/i.test(tokens)) {\n descriptor.keywords.push('line height');\n }\n\n // Extract size from Font() patterns\n if (/size:\\s*(\\d+)/i.test(tokens)) {\n const sizeMatches = tokens.matchAll(/size:\\s*(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 24) {\n descriptor.keywords.push('large text');\n } else if (size >= 16) {\n descriptor.keywords.push('medium text');\n } else {\n descriptor.keywords.push('small text');\n }\n }\n }\n }\n}\n","/**\n * Query Builder\n * Builds semantic queries from component descriptors\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\n/**\n * Build a natural language query from extracted descriptor\n * Prioritizes semantic richness for embedding-based search\n * Includes hierarchy and enhanced design token information\n */\nexport function buildSemanticQuery(descriptor: ComponentDescriptor, fallback: string): string {\n const queryParts: string[] = [];\n\n // 1. Add primary components (most important for matching)\n // Prioritize complex/specific components over generic ones\n const componentArray = Array.from(descriptor.components);\n const priorityComponents = prioritizeComponents(componentArray);\n \n if (priorityComponents.length > 0) {\n // For complex frames: include top 5-7 components\n // For simple frames: this will naturally be fewer\n queryParts.push(...priorityComponents.slice(0, 7));\n }\n\n // 2. Add hierarchy information (structural parts)\n if (descriptor.hierarchy.length > 0) {\n // Build hierarchy description\n const hierarchyParts = descriptor.hierarchy.slice(0, 4); // Limit to avoid too long\n if (hierarchyParts.length > 0) {\n // Create natural hierarchy description\n if (hierarchyParts.includes('header') && hierarchyParts.includes('body')) {\n queryParts.push('with header and body');\n } else if (hierarchyParts.includes('header') && hierarchyParts.includes('footer')) {\n queryParts.push('with header and footer');\n } else if (hierarchyParts.length === 1) {\n queryParts.push(`with ${hierarchyParts[0]}`);\n } else {\n // Add individual hierarchy parts\n queryParts.push(...hierarchyParts.slice(0, 3));\n }\n }\n }\n\n // 3. Add purpose if present (provides semantic context)\n if (descriptor.purpose) {\n queryParts.push(descriptor.purpose);\n }\n\n // 4. Add key interactions (helps match use cases)\n // Filter out interactions that are already covered by purpose\n if (descriptor.interactions.size > 0) {\n const interactions = Array.from(descriptor.interactions)\n .filter(interaction => {\n // Don't add \"confirmation\" if purpose already contains it\n if (interaction === \"confirmation\" && descriptor.purpose?.includes(\"confirmation\")) {\n return false;\n }\n return true;\n })\n .slice(0, 2);\n queryParts.push(...interactions);\n }\n\n // 5. Add semantic colors from design tokens\n if (descriptor.colors.length > 0) {\n queryParts.push(...descriptor.colors.slice(0, 3));\n }\n\n // 6. Add visual characteristics (helps with visual similarity)\n if (descriptor.visual.length > 0) {\n queryParts.push(...descriptor.visual.slice(0, 4));\n }\n\n // 7. Add typography information (if relevant)\n if (descriptor.typography.length > 0) {\n // Only add most distinctive typography features\n const distinctiveTypography = descriptor.typography.filter(t => \n t.includes('headline') || t.includes('bold') || t.includes('large')\n );\n if (distinctiveTypography.length > 0) {\n queryParts.push(...distinctiveTypography.slice(0, 2));\n }\n }\n\n // 8. Add effects (elevation, shadows)\n if (descriptor.effects.length > 0) {\n queryParts.push(...descriptor.effects.slice(0, 2));\n }\n\n // 9. Add layout traits (secondary importance)\n if (descriptor.layout.length > 0) {\n queryParts.push(...descriptor.layout.slice(0, 3));\n }\n\n // 10. Add additional keywords\n if (descriptor.keywords.length > 0) {\n queryParts.push(...descriptor.keywords.slice(0, 8));\n }\n\n // 11. Deduplicate terms (case-insensitive)\n const seen = new Set<string>();\n const uniqueParts = queryParts.filter(part => {\n const lower = part.toLowerCase();\n if (seen.has(lower)) {\n return false;\n }\n seen.add(lower);\n return true;\n });\n\n // Build final query\n if (uniqueParts.length > 0) {\n return uniqueParts.join(\" \");\n }\n\n return fallback;\n}\n\n/**\n * Prioritize components by specificity and importance\n * More specific components rank higher\n */\nexport function prioritizeComponents(components: string[]): string[] {\n const priority: { [key: string]: number } = {\n // High specificity - these are most valuable for matching\n \"segmented control\": 10,\n \"icon button\": 9,\n \"stepper\": 9,\n \"breadcrumb\": 9,\n \"calendar\": 9,\n \"carousel\": 9,\n \"accordion\": 9,\n \"datepicker\": 9,\n \"chart\": 8,\n \"table\": 8,\n \"navbar\": 8,\n \"sidebar\": 8,\n \"modal\": 8,\n \"tabs\": 8,\n \n // Medium specificity\n \"dropdown\": 7,\n \"slider\": 7,\n \"switch\": 7,\n \"checkbox\": 7,\n \"radio\": 7,\n \"textarea\": 7,\n \"pagination\": 7,\n \"card\": 7,\n \"menu\": 7,\n \"badge\": 6,\n \"tooltip\": 6,\n \"alert\": 6,\n \"progress\": 6,\n \"toast\": 6,\n \"avatar\": 6,\n \n // Lower specificity - common components\n \"button\": 5,\n \"input\": 5,\n \"list\": 4,\n \"grid\": 4,\n \"header\": 3,\n \"footer\": 3,\n \"icon\": 2,\n \"image\": 2,\n };\n\n return components.sort((a, b) => {\n const priorityA = priority[a] || 0;\n const priorityB = priority[b] || 0;\n return priorityB - priorityA;\n });\n}\n","/**\n * Design Query Extractor\n * \n * Main entry point for extracting semantic queries from Figma designs\n * optimized for Pinecone semantic/embedding-based search.\n */\n\nimport type { FigmaDesignContextResult } from \"../../clients/figma-client.js\";\nimport type { ComponentDescriptor } from \"./types.js\";\nimport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\nimport { DesignContextExtractor } from \"./design-context-extractor.js\";\nimport { buildSemanticQuery } from \"./query-builder.js\";\n\n/**\n * Extracts semantic descriptions from Figma design context for Pinecone search\n */\nexport class DesignQueryExtractor {\n private metadataExtractor: MetadataExtractorSimpler;\n private designContextExtractor: DesignContextExtractor;\n\n constructor() {\n this.metadataExtractor = new MetadataExtractorSimpler();\n this.designContextExtractor = new DesignContextExtractor();\n }\n\n /**\n * Extracts a semantic query optimized for embedding-based search from design context\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n if (!designContext.content || designContext.content.length === 0) {\n return fallbackQuery;\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item\n for (const item of designContext.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text;\n\n // Separate code from design tokens\n const parts = text.split(/These styles are contained in the design:/i);\n const codeSection = parts[0] || \"\";\n const tokensSection = parts[1] || \"\";\n\n // Extract from code and tokens\n this.designContextExtractor.extractFromCodeAndTokens(codeSection, tokensSection, descriptor);\n }\n }\n\n // Build semantic query from descriptor\n return buildSemanticQuery(descriptor, fallbackQuery);\n }\n\n /**\n * Extracts a semantic query from Figma metadata (XML-like structure)\n * Parses instance names and frame names to identify components\n */\n extractQueryFromMetadata(\n metadata: FigmaDesignContextResult,\n ): string {\n if (!metadata.content || metadata.content.length === 0) {\n return \"\";\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item (metadata is typically in text format with XML-like structure)\n for (const item of metadata.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const metadataText = item.text;\n // Extract all names from metadata and use them as keywords\n const names = this.metadataExtractor.extractNames(metadataText);\n descriptor.keywords.push(...names);\n }\n }\n\n // Build semantic query from descriptor (use empty string as fallback if no names found)\n return buildSemanticQuery(descriptor, \"\");\n }\n}\n\n// Re-export types and utilities\nexport type { ComponentDescriptor } from \"./types.js\";\nexport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\n","/**\n * Pinecone Search Service\n * Reusable service for semantic search of design system components\n * Uses Frida Pinecone Proxy API for secure access\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface ComponentMatch {\n id: string; // From match.id\n tag: string; // From metadata.tag\n score: number; // From match.score\n name: string; // From metadata.name\n framework: string; // From metadata.framework\n category: string; // From metadata.category\n overview: string; // From metadata.overview\n visual: string; // From metadata.visual\n technical: string; // From metadata.technical\n keywords: string[]; // From metadata.keywords\n}\n\nexport interface SearchOptions {\n minScore?: number;\n topK?: number;\n namespace?: string;\n}\n\nexport interface SearchResults {\n query: string;\n totalMatches: number;\n relevantMatches: number;\n matches: ComponentMatch[];\n searchMetadata: {\n minScore: number;\n topK: number;\n indexName: string;\n namespace?: string;\n };\n}\n\nexport interface PineconeSearchServiceOptions {\n namespace?: string;\n}\n\nexport class PineconeSearchService {\n private indexName: string;\n private namespace?: string;\n private minScore: number;\n private topK: number;\n private fridaEmbeddingUrl: string;\n private fridaApiKey: string;\n private fridaPineconeProxyUrl: string;\n private fridaEmbeddingModel: string;\n\n constructor(options: PineconeSearchServiceOptions = {}) {\n this.indexName = process.env.PINECONE_INDEX!;\n this.namespace = options.namespace;\n this.minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n this.topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n this.fridaEmbeddingUrl = process.env.FRIDA_EMBEDDING_URL!;\n this.fridaApiKey = process.env.FRIDA_BEARER_TOKEN!;\n this.fridaPineconeProxyUrl = process.env.FRIDA_PINECONE_PROXY_URL!;\n this.fridaEmbeddingModel = process.env.FRIDA_EMBEDDING_MODEL!;\n }\n\n /**\n * Generates embedding for a text using Frida API\n * @param text - Text to embed\n * @returns Promise<number[]> Embedding vector (1536 dimensions)\n */\n async generateEmbedding(text: string): Promise<number[]> {\n try {\n logger.debug(\"Calling Frida Embedding API...\");\n const startTime = Date.now();\n\n const response = await fetch(this.fridaEmbeddingUrl, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n Authorization: `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input: text,\n model: this.fridaEmbeddingModel,\n user_id: \"pinecone-search\",\n email: \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n\n logger.debug(`API response status: ${response.status}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"API Error response:\", errorText);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n logger.debug(\"Parsing API response...\");\n const data = (await response.json()) as {\n data?: Array<{ embedding?: number[] }>;\n };\n\n if (!data.data || !data.data[0] || !data.data[0].embedding) {\n logger.error(\"Invalid response format:\", JSON.stringify(data).substring(0, 200));\n throw new Error(\"Invalid API response format\");\n }\n\n const embedding = data.data[0].embedding;\n const elapsed = Date.now() - startTime;\n logger.debug(`✓ Embedding generated (${embedding.length} dims) in ${elapsed}ms`);\n\n return embedding; // Returns 1536-dimensional array\n } catch (error) {\n logger.error(\"Error generating embedding:\", error);\n throw new Error(`Failed to generate embedding: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Parses a Pinecone match to structured format\n * New simplified schema: tag, name, framework, category, overview, visual, technical, keywords\n */\n private parseMatch(match: {\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }): ComponentMatch {\n const metadata = match.metadata || {};\n\n return {\n id: match.id || \"unknown\",\n tag: (metadata.tag as string) || match.id || \"unknown\",\n score: match.score || 0,\n name: (metadata.name as string) || \"\",\n framework: (metadata.framework as string) || \"\",\n category: (metadata.category as string) || \"General\",\n overview: (metadata.overview as string) || \"\",\n visual: (metadata.visual as string) || \"\",\n technical: (metadata.technical as string) || \"\",\n keywords: Array.isArray(metadata.keywords) ? (metadata.keywords as string[]) : [],\n };\n }\n\n /**\n * Queries Pinecone via Frida Proxy API\n * @param embedding - Embedding vector\n * @param topK - Number of results to return\n * @param namespace - Optional namespace\n * @returns Query response from Pinecone\n */\n private async queryPineconeProxy(\n embedding: number[],\n topK: number,\n namespace?: string,\n ): Promise<{\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n }> {\n const url = `${this.fridaPineconeProxyUrl}/pinecone/data/${this.indexName}/query`;\n\n logger.debug(`Querying Frida Pinecone Proxy: ${url}${namespace ? ` (namespace: \"${namespace}\")` : \"\"}`);\n\n const requestBody: {\n vector: number[];\n topK: number;\n includeMetadata: boolean;\n namespace?: string;\n } = {\n vector: embedding,\n topK,\n includeMetadata: true,\n };\n\n // Add namespace to request body if provided\n if (namespace) {\n requestBody.namespace = namespace;\n }\n\n const startTime = Date.now();\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n const queryTime = Date.now() - startTime;\n logger.debug(`Proxy API response status: ${response.status} (${queryTime}ms)`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"Proxy API Error response:\", errorText);\n throw new Error(`Pinecone Proxy API Error: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json() as {\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n };\n\n return data;\n }\n\n /**\n * Searches for components in Pinecone via Frida Proxy\n * @param query - Search query\n * @param options - Search options\n * @returns Structured results\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResults> {\n if (!query || typeof query !== \"string\") {\n throw new Error(\"Query must be a non-empty string\");\n }\n logger.debug(`[DEBUG] options object: ${JSON.stringify(options)}`);\n logger.debug(`[DEBUG] options.topK: ${options.topK}, type: ${typeof options.topK}`);\n logger.debug(`[DEBUG] options.topK !== undefined: ${options.topK !== undefined}`);\n logger.debug(`[DEBUG] this.topK (instance): ${this.topK}`);\n\n const minScore =\n options.minScore !== undefined ? options.minScore : this.minScore;\n const topK = options.topK !== undefined ? options.topK : this.topK;\n // Namespace: prioritize options.namespace, then this.namespace\n const namespace = options.namespace !== undefined ? options.namespace : this.namespace;\n\n logger.debug(`Starting search - Query: \"${query}\", topK: ${topK}, minScore: ${minScore}${namespace ? `, namespace: \"${namespace}\"` : \"\"}`);\n\n // Generate embedding for the query\n const embedding = await this.generateEmbedding(query);\n\n // Query Pinecone via Frida Proxy\n logger.debug(`Querying Pinecone index \"${this.indexName}\" via Frida Proxy${namespace ? ` namespace \"${namespace}\"` : \"\"}...`);\n const startTime = Date.now();\n\n const queryResponse = await this.queryPineconeProxy(embedding, topK, namespace);\n const queryTime = Date.now() - startTime;\n logger.debug(`Query completed in ${queryTime}ms - Found ${queryResponse.matches?.length || 0} matches`);\n\n // Process results\n const allMatches = queryResponse.matches || [];\n const relevantMatches = allMatches.filter((m) => (m.score || 0) >= minScore);\n\n logger.debug(`Filtered results: ${relevantMatches.length} relevant (score >= ${minScore}) out of ${allMatches.length} total`);\n\n return {\n query,\n totalMatches: allMatches.length,\n relevantMatches: relevantMatches.length,\n matches: relevantMatches.map((match) => this.parseMatch(match)),\n searchMetadata: {\n minScore,\n topK,\n indexName: this.indexName,\n namespace: namespace,\n },\n };\n }\n\n /**\n * Gets details of a specific component by tag or id\n * @param tag - Component tag or id (e.g.: 'wtw-button-split', 'my-badge')\n * @returns Component details or null if it doesn't exist\n */\n async getComponentDetails(tag: string): Promise<ComponentMatch | null> {\n if (!tag || typeof tag !== \"string\") {\n throw new Error(\"Tag must be a non-empty string\");\n }\n\n // Search for the specific component\n const results = await this.search(tag, { topK: 10, minScore: 0 });\n\n // Find exact match by tag or id\n const exactMatch = results.matches.find(\n (m) => m.tag === tag || m.id === tag\n );\n\n if (exactMatch) {\n return exactMatch;\n }\n\n // If no exact match, return the closest one\n if (results.matches.length > 0) {\n return results.matches[0];\n }\n\n return null;\n }\n\n /**\n * Searches for multiple components by tags\n * @param tags - Array of component tags\n * @returns Array of component details\n */\n async getMultipleComponents(tags: string[]): Promise<ComponentMatch[]> {\n if (!Array.isArray(tags)) {\n throw new Error(\"Tags must be an array\");\n }\n\n const results = await Promise.all(\n tags.map((tag) => this.getComponentDetails(tag)),\n );\n\n return results.filter(\n (r): r is ComponentMatch => r !== null,\n );\n }\n}\n\n","/**\n * Formatters\n * Utilities to format search results in different formats\n */\n\nimport type {\n ComponentMatch,\n SearchResults,\n} from \"../services/pinecone/pinecone-service.js\";\n\nexport class Formatters {\n /**\n * Formats results in structured format (JSON-friendly)\n */\n static toStructured(searchResults: SearchResults): {\n query: string;\n summary: {\n totalMatches: number;\n relevantMatches: number;\n minScore: number;\n };\n components: Array<{\n id: string;\n tag: string;\n score: number;\n name: string;\n framework: string;\n category: string;\n overview: string;\n visual: string;\n technical: string;\n keywords: string[];\n }>;\n } {\n return {\n query: searchResults.query,\n summary: {\n totalMatches: searchResults.totalMatches,\n relevantMatches: searchResults.relevantMatches,\n minScore: searchResults.searchMetadata.minScore,\n },\n components: searchResults.matches.map((match) => ({\n id: match.id,\n tag: match.tag,\n score: match.score,\n name: match.name,\n framework: match.framework,\n category: match.category,\n overview: match.overview,\n visual: match.visual,\n technical: match.technical,\n keywords: match.keywords,\n })),\n };\n }\n\n /**\n * Formats results in readable markdown format\n */\n static toMarkdown(searchResults: SearchResults): string {\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return `## No similar components found\n\n**Query:** \"${searchResults.query}\"\n\nSuggestion: Try more general terms or verify that components are indexed.`;\n }\n\n //Verify to add or hide to show what was queried // **Query:** \"${searchResults.query}\"\n let markdown = `## Search Results\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n---\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag}\n\n**Technical Documentation:**\n${match.technical || \"No technical documentation available\"}\n\n---\n\n`;\n });\n\n return markdown;\n }\n\n /**\n * Formats multiple components for context in prompts\n * Uses JSON format for better LLM understanding\n */\n static matchesToContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Use JSON format for component documentation which works well with LLMs\n // This provides structured data that LLMs can parse better than plain text\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score, // Pinecone ranking\n overview: match.overview,\n visual: match.visual,\n keywords: match.keywords,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n /**\n * Formats components with only essential fields (tag, score, overview) for lightweight filtering\n * Used when sending to Frida for tag-only filtering\n */\n static matchesToLightweightContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Only include tag, score, and overview for lightweight filtering\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score,\n overview: match.overview,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n}\n\n","/**\n * MCP Login Authentication\n *\n * Authenticates MCP login using llmopsApiKey and projectId. Looks up the\n * project by projectId, gets its organizationId, fetches the organization,\n * and verifies the provided llmopsApiKey matches the organization's\n * llmopsApiKey. Uses constant-time comparison to prevent timing attacks.\n * Includes rate limiting to prevent brute-force attempts.\n */\n\nimport { logger } from \"../../utils/logger.js\";\n\nconst VALIDATION_URL =\n \"https://us-central1-figma2frida-mcp.cloudfunctions.net/authenticateMcpLogin\";\n\nexport interface ValidationResult {\n valid: boolean;\n message: string;\n}\n\nexport interface ValidationError {\n message: string;\n status: string;\n}\n\n/**\n * Authenticates MCP login using llmopsApiKey and projectId.\n *\n * Looks up the project by projectId, gets its organizationId, fetches the\n * organization, and verifies the provided llmopsApiKey matches the\n * organization's llmopsApiKey. Uses constant-time comparison to prevent\n * timing attacks. Includes rate limiting to prevent brute-force attempts.\n *\n * @example Input (HTTP Request Body):\n * {\n * \"data\": {\n * \"llmopsApiKey\": \"api-key-12345\",\n * \"projectId\": \"abc123xyz\"\n * }\n * }\n *\n * @example Output (HTTP Response - Success):\n * {\n * \"result\": {\n * \"valid\": true,\n * \"message\": \"API token is valid\"\n * }\n * }\n *\n * @example Output (HTTP Response - Error: Invalid token):\n * {\n * \"error\": {\n * \"message\": \"Invalid API token\",\n * \"status\": \"PERMISSION_DENIED\"\n * }\n * }\n *\n * @example Output (HTTP Response - Error: Rate limit exceeded):\n * {\n * \"error\": {\n * \"message\": \"Too many attempts. Please try again later.\",\n * \"status\": \"RESOURCE_EXHAUSTED\"\n * }\n * }\n *\n * @example Output (HTTP Response - Error: Project or organization not found):\n * {\n * \"error\": {\n * \"message\": \"Project not found\",\n * \"status\": \"NOT_FOUND\"\n * }\n * }\n */\nexport async function authenticateMcpLogin(\n llmopsApiKey: string,\n projectId: string,\n): Promise<void> {\n logger.info(\"🔐 Authenticating MCP login...\");\n\n try {\n const response = await fetch(VALIDATION_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n data: {\n llmopsApiKey,\n projectId,\n },\n }),\n });\n\n const responseData = (await response.json()) as\n | { result: ValidationResult }\n | { error: ValidationError };\n\n // Check for success response\n if (\n response.ok &&\n \"result\" in responseData &&\n responseData.result?.valid === true\n ) {\n logger.info(\n `✅ ${responseData.result.message || \"API token is valid\"}`,\n );\n return;\n }\n\n // Handle error responses\n if (\"error\" in responseData) {\n const error = responseData.error;\n const errorMessage = error.message || \"Unknown error\";\n const errorStatus = error.status || \"UNKNOWN\";\n\n logger.error(`❌ MCP login authentication failed: ${errorMessage}`);\n logger.error(` Status: ${errorStatus}`);\n\n if (errorStatus === \"RESOURCE_EXHAUSTED\") {\n logger.error(\" Rate limit exceeded. Please try again later.\");\n } else if (errorStatus === \"NOT_FOUND\") {\n logger.error(\" Project not found. Please check your project ID.\");\n } else if (errorStatus === \"PERMISSION_DENIED\") {\n logger.error(\n \" Invalid API token. Please check your token and try again.\",\n );\n }\n\n throw new Error(\n `Authentication failed: ${errorMessage} (${errorStatus})`,\n );\n }\n\n // Handle unexpected response format\n logger.error(\n `❌ Unexpected authentication response format: ${JSON.stringify(responseData)}`,\n );\n throw new Error(\"Unexpected authentication response format\");\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.startsWith(\"Authentication failed:\")\n ) {\n throw error;\n }\n\n // Handle network/request errors\n logger.error(\n \"❌ Failed to authenticate MCP login:\",\n error instanceof Error ? error.message : String(error),\n );\n\n if (error instanceof Error) {\n if (\n error.message.includes(\"fetch failed\") ||\n error.message.includes(\"ECONNREFUSED\")\n ) {\n logger.error(\" Network error: Could not reach validation service.\");\n logger.error(\" Please check your internet connection and try again.\");\n throw new Error(\"Network error: Could not reach validation service\");\n } else if (error.message.includes(\"timeout\")) {\n logger.error(\n \" Request timeout: Validation service did not respond in time.\",\n );\n logger.error(\" Please try again later.\");\n throw new Error(\n \"Request timeout: Validation service did not respond in time\",\n );\n }\n }\n\n throw new Error(\n `Authentication failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * Frida AI Client\n * Optional client for Frida AI integration\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface FridaClientOptions {\n apiKey?: string;\n apiUrl?: string;\n model?: string;\n maxTokens?: number;\n}\n\nexport interface FridaResponse {\n success: boolean;\n error: string | null;\n response: string | null;\n metadata?: {\n model: string;\n tokensUsed: number | null;\n };\n}\n\nexport class FridaClient {\n private apiKey: string | undefined;\n private apiUrl: string | undefined;\n private model: string;\n private maxTokens: number;\n private enabled: boolean;\n\n constructor(options: FridaClientOptions = {}) {\n this.apiKey = options.apiKey || process.env.FRIDA_BEARER_TOKEN;\n this.apiUrl = options.apiUrl || process.env.FRIDA_API_URL;\n this.model = options.model || process.env.FRIDA_MODEL || \"gpt-5.1-codex\";\n this.maxTokens = options.maxTokens || (process.env.FRIDA_MAX_TOKENS ? parseInt(process.env.FRIDA_MAX_TOKENS, 10) : 4096);\n this.enabled = !!(this.apiKey && this.apiUrl);\n }\n\n /**\n * Checks if Frida is configured\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Generates the unified prompt for component recommendation\n * Optimized for Approach B: lightweight context for selection, technical docs handled separately\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert design system specialist.\nYour goal is to analyze the Figma design context and recommend the mostly suitable component(s) from the design system.\n\n**CONTEXT:**\nThe user has a Figma design element and needs to know which component from the library to use.\nBelow is a list of available components with their visual descriptions and overviews.\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**INSTRUCTIONS:**\n1. Analyze the user's design description (Question).\n2. Compare it against the **Visual** and **Overview** of the available components.\n3. Select the best matching component(s).\n4. Provide a brief reasoning for your selection.\n\n**RESPONSE FORMAT:**\nYour response must be concise and follow this format:\n\n🎯 **Recommended Component:** [Tag]\n**Confidence:** [High/Medium/Low]\n**Reasoning:** [1-2 sentences explaining why this visual/functional description matches the design]\n\nUSER QUESTION:\n${question}`;\n }\n\n /**\n * Generates a prompt specifically for filtering components by tags only\n * Returns only component tags that match the query description\n */\n buildFilterPrompt(query: string, context: string): string {\n return `You are a design system expert. Analyze the query and component list below.\n\n**QUERY:** ${query}\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**TASK:** \nAnalyze the query description and compare it against the component overviews and scores.\nReturn ONLY the component tags (comma-separated) that best match the query description.\n\n**RESPONSE FORMAT:**\nReturn only the tags separated by commas. Do not include explanations, reasoning, or any other text.\nExample format: tag1, tag2, tag3\n\n**IMPORTANT:** Only return tags that are in the available components list above.`;\n }\n\n /**\n * Asks a question to Frida AI\n * @param question - User question\n * @param context - Context with component information\n * @returns Frida response\n */\n async ask(question: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!question || typeof question !== \"string\") {\n return {\n success: false,\n error: \"Question must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI\");\n\n const prompt = this.buildPrompt(question, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Question length: ${question.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: \"figma_2frida_mcp@softtek.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n logger.debug(\"Response received successfully\");\n\n // Try to extract the response from different possible formats\n const answer =\n (data.response as string) ||\n (data.output as string) ||\n ((data.choices as Array<{ message?: { content?: string } }>)?.[0]\n ?.message?.content as string) ||\n (data.content as string) ||\n JSON.stringify(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerLength = typeof answer === \"string\" ? answer.length : String(answer).length;\n\n logger.debug(\"FRIDA AI RESPONSE RECEIVED\");\n logger.debug(`TOKENS USED: ${tokensUsed || 'N/A'}`);\n logger.debug(`Answer length: ${answerLength} chars`);\n logger.debug(`Total time: ${fetchTime}ms`);\n\n return {\n success: true,\n error: null,\n response: typeof answer === \"string\" ? answer : String(answer),\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n\n /**\n * Asks Frida AI to filter components and return only matching tags\n * Uses buildFilterPrompt instead of buildPrompt for tag-only responses\n * @param query - Search query description\n * @param context - Lightweight component context (tag, score, overview)\n * @returns Frida response with component tags\n */\n async askForFilter(query: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!query || typeof query !== \"string\") {\n return {\n success: false,\n error: \"Query must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI FOR FILTERING\");\n\n // Use buildFilterPrompt instead of buildPrompt\n const prompt = this.buildFilterPrompt(query, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Query length: ${query.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: \"figma_2frida_mcp@softtek.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n logger.debug(\"Response received successfully\");\n\n // Try to extract the response from different possible formats\n const answer =\n (data.response as string) ||\n (data.output as string) ||\n ((data.choices as Array<{ message?: { content?: string } }>)?.[0]\n ?.message?.content as string) ||\n (data.content as string) ||\n JSON.stringify(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerLength = typeof answer === \"string\" ? answer.length : String(answer).length;\n\n logger.debug(\"FRIDA AI FILTER RESPONSE RECEIVED\");\n logger.debug(`TOKENS USED: ${tokensUsed || 'N/A'}`);\n logger.debug(`Answer length: ${answerLength} chars`);\n logger.debug(`Total time: ${fetchTime}ms`);\n\n return {\n success: true,\n error: null,\n response: typeof answer === \"string\" ? answer : String(answer),\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI for filtering:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n}\n","/**\n * Library Filter Handler\n * Handles Frida AI filtering of component search results from Pinecone\n */\n\nimport type { ComponentMatch, SearchResults } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { logger } from \"../utils/logger.js\";\n\n/**\n * Parses component tags from Frida's response\n * Handles various formats: comma-separated, newline-separated, or list format\n */\nfunction parseTagsFromFridaResponse(response: string, availableTags: string[]): string[] {\n if (!response || typeof response !== \"string\") {\n return [];\n }\n\n // Normalize the response: remove markdown formatting, extra whitespace\n let normalized = response.trim();\n \n // Remove common markdown formatting\n normalized = normalized.replace(/\\*\\*/g, \"\"); // Remove bold\n normalized = normalized.replace(/#+/g, \"\"); // Remove headers\n normalized = normalized.replace(/```[\\s\\S]*?```/g, \"\"); // Remove code blocks\n \n // Try to extract tags from various formats\n // Format 1: Comma-separated (tag1, tag2, tag3)\n let tags: string[] = [];\n \n // Split by comma first\n const commaSplit = normalized.split(\",\").map(t => t.trim());\n \n // Also try splitting by newline\n const newlineSplit = normalized.split(/\\n+/).map(t => t.trim());\n \n // Combine both approaches and filter\n const allCandidates = [...commaSplit, ...newlineSplit]\n .map(tag => {\n // Remove common prefixes/suffixes\n tag = tag.replace(/^[-•*]\\s*/, \"\"); // Remove list markers\n tag = tag.replace(/^tag:\\s*/i, \"\"); // Remove \"tag:\" prefix\n tag = tag.replace(/^tags?:\\s*/i, \"\"); // Remove \"tags:\" prefix\n tag = tag.replace(/[.,;]$/, \"\"); // Remove trailing punctuation\n return tag.trim();\n })\n .filter(tag => tag.length > 0);\n\n // Match against available tags (case-insensitive)\n for (const candidate of allCandidates) {\n const candidateLower = candidate.toLowerCase();\n // Find exact match or partial match\n const matchedTag = availableTags.find(t => \n t.toLowerCase() === candidateLower || \n t.toLowerCase().includes(candidateLower) ||\n candidateLower.includes(t.toLowerCase())\n );\n \n if (matchedTag && !tags.includes(matchedTag)) {\n tags.push(matchedTag);\n }\n }\n\n logger.debug(`Parsed ${tags.length} tags from Frida response: ${tags.join(\", \")}`);\n return tags;\n}\n\nexport interface FilterComponentsOptions {\n query: string;\n searchResults: SearchResults;\n}\n\nexport interface FilterComponentsResult {\n filteredResults: SearchResults;\n wasFiltered: boolean;\n fridaResponseTime?: number;\n}\n\n/**\n * Filters component search results using Frida AI\n * If Frida is enabled, it will analyze the query and component overviews\n * to return only the most relevant component tags\n */\nexport async function filterComponentsWithFrida(\n options: FilterComponentsOptions\n): Promise<FilterComponentsResult> {\n const { query, searchResults } = options;\n\n // If no results, return early\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return {\n filteredResults: searchResults,\n wasFiltered: false,\n };\n }\n\n // Create FridaClient instance for filtering\n const fridaClient = new FridaClient();\n \n let filteredMatches: ComponentMatch[] = searchResults.matches;\n let wasFiltered = false;\n let fridaResponseTime: number | undefined;\n \n // If Frida is enabled, use it to filter components\n if (fridaClient.isEnabled()) {\n try {\n logger.debug(\"Using Frida AI to filter components...\");\n \n // Create lightweight context with only (tag, score, overview)\n const lightweightContext = Formatters.matchesToLightweightContext(searchResults.matches);\n \n // Call Frida with askForFilter method (uses buildFilterPrompt internally)\n const fridaStartTime = Date.now();\n const fridaResponse = await fridaClient.askForFilter(query, lightweightContext);\n fridaResponseTime = Date.now() - fridaStartTime;\n \n logger.debug(`Frida AI filtering completed in ${fridaResponseTime}ms - Success: ${fridaResponse.success}`);\n \n if (fridaResponse.success && fridaResponse.response) {\n // Parse tags from Frida response\n const availableTags = searchResults.matches.map(m => m.tag);\n const selectedTags = parseTagsFromFridaResponse(fridaResponse.response, availableTags);\n \n if (selectedTags.length > 0) {\n // Filter matches to only include selected tags\n filteredMatches = searchResults.matches.filter(match => \n selectedTags.includes(match.tag)\n );\n \n wasFiltered = true;\n logger.debug(`Frida filtered ${filteredMatches.length} components from ${searchResults.matches.length} total matches`);\n } else {\n logger.warn(\"Frida returned no valid tags, using all Pinecone results\");\n }\n } else {\n logger.warn(`Frida filtering failed: ${fridaResponse.error || \"Unknown error\"}, using all Pinecone results`);\n }\n } catch (fridaError) {\n logger.warn(`Frida filtering error: ${fridaError instanceof Error ? fridaError.message : String(fridaError)}, using all Pinecone results`);\n // Continue with all results if Frida fails\n }\n } else {\n logger.debug(\"Frida AI not configured, skipping filtering step\");\n }\n\n // Create filtered search results\n const filteredSearchResults: SearchResults = {\n ...searchResults,\n matches: filteredMatches,\n relevantMatches: filteredMatches.length,\n };\n\n return {\n filteredResults: filteredSearchResults,\n wasFiltered,\n fridaResponseTime,\n };\n}\n"],"mappings":"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","names":["require"]}
|