@fridaplatform-stk/figma2frida-mcp 1.0.2 → 1.0.3

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 CHANGED
@@ -1,121 +1,76 @@
1
1
  # Figma2Frida MCP Server
2
2
 
3
- Figma to Frida MCP Server - Bridge between Figma Desktop MCP and design system components with Pinecone search.
3
+ > AI-powered bridge between Figma designs and your organization's design system components
4
4
 
5
- ## Overview
5
+ ## 🎯 What Is Figma2Frida?
6
6
 
7
- This MCP server connects Figma Desktop MCP to your design system components stored in Pinecone, enabling intelligent component suggestions based on Figma designs.
7
+ **Figma2Frida MCP Server** is a bridge that connects your AI coding assistant (Claude, Cursor, GitHub Copilot) with Figma designs and your organization's design system. It enables you to:
8
8
 
9
- ## Features
9
+ - **Generate production-ready code** directly from Figma designs
10
+ - **Automatically use components** from your design system library
11
+ - **Match components intelligently** using AI-powered semantic search
12
+ - **Preserve exact layouts** - spacing, alignment, and visual hierarchy from Figma
13
+ - **Get component documentation** - props, types, and usage examples included
10
14
 
11
- - 🔗 **Figma Integration**: Connects to Figma Desktop MCP
12
- - 🔍 **Pinecone Search**: Semantic search for design system components
13
- - 🤖 **Frida AI**: Intelligent component recommendations
14
- - 🎨 **Component Suggestions**: Suggests matching components based on Figma designs
15
- - 📸 **Screenshot Support**: Get visual screenshots from Figma
16
- - 🚀 **Fast Code Generation**: Optimized for rapid code generation
15
+ ### Available Tools
17
16
 
18
- ## Prerequisites
17
+ Your AI assistant gets four specialized tools:
19
18
 
20
- - Node.js 18+
21
- - Figma Desktop with MCP enabled (running at `http://127.0.0.1:3845/sse`)
22
- - API token for authentication
19
+ 1. **`figma_get_design_context`** - Generate code from Figma with automatic component matching *(main tool)*
20
+ 2. **`figma_suggest_components`** - Browse and discover design system components
21
+ 3. **`figma_get_screenshot`** - Quick visual reference from Figma
22
+ 4. **`figma_improve_layout`** - Fine-tune generated code to match Figma exactly
23
23
 
24
- ## Installation
24
+ ## 🔄 How It Works
25
25
 
26
- ### From npm (Recommended)
27
-
28
- ```bash
29
- npm install -g @fridaplatform-stk/figma2frida-mcp
30
26
  ```
31
-
32
- ### From Source
33
-
34
- ```bash
35
- # Clone the repository
36
- git clone <your-repo-url>
37
- cd figma2frida_mcp
38
-
39
- # Install dependencies
40
- npm install
41
-
42
- # Build the project
43
- npm run build
27
+ 1. Select design in Figma
28
+
29
+ 2. Ask your AI: "Generate code for this design"
30
+
31
+ 3. MCP fetches design → Searches your component library → Uses Frida AI
32
+
33
+ 4. Get production-ready code with your design system components
44
34
  ```
45
35
 
46
- ## Configuration
36
+ **Behind the scenes:**
37
+ - Connects to Figma Desktop (local MCP server)
38
+ - Searches your component library in Pinecone
39
+ - Uses Frida AI for intelligent component matching
40
+ - Validates your API token via Firebase
47
41
 
48
- ### Environment Variables
42
+ ## 📦 Installation
49
43
 
50
- **Note**: Most configuration is built into the package. The following are passed as command-line arguments:
51
- - `--pinecone-namespace`: Your namespace identifier (required)
52
- - `--frida-api-token`: Your API token for authentication (required)
44
+ ### Step 1: Install the Package
53
45
 
54
- Optional environment variables for local development:
55
46
  ```bash
56
- # Server Configuration (optional)
57
- HTTP_STREAM=true # Set to true for HTTP mode, false for stdio
58
- PORT=8080 # Port for HTTP stream mode
59
- ```
60
-
61
- ## Local Development
62
-
63
- ### Running Locally
64
-
65
- Use the `run-local.sh` script for local testing:
66
-
67
- ```bash
68
- # Make sure the script is executable
69
- chmod +x run-local.sh
70
-
71
- # With default namespace (org01_proj01)
72
- ./run-local.sh
73
-
74
- # With custom namespace
75
- ./run-local.sh org02_proj02
76
- ```
77
-
78
- The script will:
79
- - Start the server in HTTP Stream mode
80
- - Use the namespace from the command-line argument
81
- - Make the server available at `http://localhost:8080/mcp`
82
-
83
- **Note**: For local development, you may need to pass the `--frida-api-token` argument as well.
84
-
85
- ### Testing the Server
86
-
87
- Once running, test with curl:
88
-
89
- ```bash
90
- curl -X POST http://localhost:8080/mcp \
91
- -H "Content-Type: application/json" \
92
- -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
47
+ npm install -g @fridaplatform-stk/figma2frida-mcp
93
48
  ```
94
49
 
95
- ## Visual Studio / GitHub Copilot Setup
50
+ ### Step 2: Configure Your AI Assistant
96
51
 
97
- ### Configuration
52
+ Add to your configuration file:
98
53
 
99
- Add this to your MCP configuration file (location depends on your IDE):
54
+ **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
100
55
 
101
56
  ```json
102
57
  {
103
58
  "mcpServers": {
104
59
  "figma2frida": {
105
- "command": "node",
60
+ "command": "npx",
106
61
  "args": [
107
- "/absolute/path/to/figma2frida_mcp/dist/figma2frida.js",
108
- "--pinecone-namespace",
109
- "org01_proj01",
62
+ "@fridaplatform-stk/figma2frida-mcp",
63
+ "--project-id",
64
+ "YOUR_PROJECT_ID",
110
65
  "--frida-api-token",
111
- "your_api_token_here"
66
+ "YOUR_API_TOKEN"
112
67
  ]
113
68
  }
114
69
  }
115
70
  }
116
71
  ```
117
72
 
118
- **Or using npm package:**
73
+ **Cursor** (similar configuration in settings):
119
74
 
120
75
  ```json
121
76
  {
@@ -124,131 +79,98 @@ Add this to your MCP configuration file (location depends on your IDE):
124
79
  "command": "npx",
125
80
  "args": [
126
81
  "@fridaplatform-stk/figma2frida-mcp",
127
- "--pinecone-namespace",
128
- "org01_proj01",
82
+ "--project-id",
83
+ "YOUR_PROJECT_ID",
129
84
  "--frida-api-token",
130
- "your_api_token_here"
85
+ "YOUR_API_TOKEN"
131
86
  ]
132
87
  }
133
88
  }
134
89
  }
135
90
  ```
136
91
 
137
- **Important**:
138
- - Use the **absolute path** to `dist/figma2frida.js` if installing from source
139
- - Replace `org01_proj01` with your namespace
140
- - Replace `your_api_token_here` with your API token
141
- - Both `--pinecone-namespace` and `--frida-api-token` are required arguments
142
- - Make sure you've run `npm run build` first if installing from source
143
-
144
- ### Restart Your IDE
145
-
146
- After adding the configuration, restart Visual Studio / GitHub Copilot to load the MCP server.
147
-
148
- ## Available Tools
149
-
150
- - `figma_get_screenshot` - Get visual screenshot from Figma (fast)
151
- - `figma_get_design_context` - Get design data and generated code (with caching & streaming)
152
- - `figma_suggest_components` - Suggest design system components based on Figma design (with Pinecone & Frida AI)
153
- - `figma_improve_layout` - Trigger layout improvement to match Figma frame reference
154
-
92
+ ### Step 3: Restart Your AI Assistant
155
93
 
156
- ## Development
94
+ Restart Claude Desktop, Cursor, or your IDE to load the MCP server.
157
95
 
158
- ### Build
96
+ ## 🔑 Getting Access Tokens
159
97
 
160
- ```bash
161
- npm run build
162
- ```
98
+ To use Figma2Frida, you need:
99
+ - **Project ID** - Your organization's project identifier
100
+ - **Frida API Token** - Authentication token for Frida services
163
101
 
164
- ### Development Mode
102
+ ### How to Get Tokens
165
103
 
166
- ```bash
167
- npm run dev
168
- ```
104
+ **Contact the Softtek Frida Team:**
169
105
 
170
- ## Publishing to npm
106
+ 📧 Reach out to your organization's Frida team or Softtek Frida support to request access.
171
107
 
172
- ### ⚠️ Permission Required
108
+ You'll need to provide:
109
+ - Your organization name
110
+ - Intended use case
111
+ - Team/project information
173
112
 
174
- **Important:** This package is published under the `@fridaplatform-stk` scope and requires **permission from Fridaplatform** to publish or update.
113
+ The Frida team will provide your credentials securely.
175
114
 
176
- - You must be a member of the `@fridaplatform-stk` npm organization
177
- - You must have publish permissions for the organization
178
- - Contact the Fridaplatform team to request access if needed
115
+ ### 💡 Recommended: Frida Code Copilot Extension
179
116
 
180
- ### First-Time Publishing
117
+ For the best experience, also install the **[Frida Code Copilot VS Code Extension](https://marketplace.visualstudio.com/)**:
181
118
 
182
- ```bash
183
- # 1. Login to npm
184
- npm login
119
+ - Automatically manages your projects and components
120
+ - Visual component browser in VS Code
121
+ - Real-time component library updates
122
+ - Works seamlessly with this MCP server
185
123
 
186
- # 2. Verify you're logged in
187
- npm whoami
124
+ ## 📋 Prerequisites
188
125
 
189
- # 3. Verify organization access
190
- npm access ls-packages @fridaplatform-stk
126
+ - **Node.js 18+**
127
+ - **Figma Desktop** with MCP enabled
128
+ - **Frida API Token** (contact Softtek Frida team)
191
129
 
192
- # 4. Build the package
193
- npm run build
130
+ ## 🚀 Example Usage
194
131
 
195
- # 5. Verify what will be published
196
- npm pack --dry-run
132
+ Once configured, simply ask your AI assistant:
197
133
 
198
- # 6. Publish (requires permission)
199
- npm publish
134
+ ```
135
+ "Generate React code for this Figma button component"
200
136
  ```
201
137
 
202
- ### Updating/Republishing
203
-
204
- To update the package with a new version:
205
-
206
- ```bash
207
- # 1. Update version in package.json (or use npm version)
208
- npm version patch # for bug fixes (1.0.0 -> 1.0.1)
209
- npm version minor # for new features (1.0.0 -> 1.1.0)
210
- npm version major # for breaking changes (1.0.0 -> 2.0.0)
211
-
212
- # 2. Build the package
213
- npm run build
214
-
215
- # 3. Verify changes
216
- npm pack --dry-run
138
+ ```
139
+ "What card components are available in my design system?"
140
+ ```
217
141
 
218
- # 4. Publish the update (requires permission)
219
- npm publish
142
+ ```
143
+ "Update this code to match the Figma spacing exactly"
220
144
  ```
221
145
 
222
- ### Installation
146
+ The AI will automatically use the Figma2Frida tools to help you.
223
147
 
224
- After publishing, users can install globally:
148
+ ## 🐛 Troubleshooting
225
149
 
226
- ```bash
227
- npm install -g @fridaplatform-stk/figma2frida-mcp
228
- figma2frida-mcp --pinecone-namespace org01_proj01 --frida-api-token your_api_token_here
229
- ```
150
+ **"Authentication failed"**
151
+ Verify your Frida API token with the Softtek team
152
+
153
+ **"Not connected to Figma MCP"**
154
+ → Make sure Figma Desktop is running with MCP enabled
230
155
 
231
- ## Troubleshooting
156
+ **"Missing required argument"**
157
+ → Check both `--project-id` and `--frida-api-token` are in your config
232
158
 
233
- ### "Cannot find module 'fastmcp'"
234
- Run `npm install` to install dependencies.
159
+ **"Rate limit exceeded"**
160
+ Wait a few minutes before trying again
235
161
 
236
- ### "Figma MCP connection failed"
237
- Make sure Figma Desktop is running with MCP enabled at `http://127.0.0.1:3845/sse`.
162
+ ## 🤝 Support
238
163
 
239
- ### "Missing required argument"
240
- Make sure you're passing both `--pinecone-namespace` and `--frida-api-token` as arguments.
164
+ - **Softtek Frida Team**: Contact for access tokens and support
241
165
 
242
- ### Visual Studio can't find the MCP server
243
- - Check the absolute path is correct
244
- - Make sure `dist/figma2frida.js` exists (run `npm run build`)
245
- - Check Visual Studio's MCP logs for errors
166
+ ## 📄 License
246
167
 
247
- ## License
168
+ MIT License
248
169
 
249
- MIT
170
+ ## 👥 Author
250
171
 
251
- ## Author
172
+ **Frida Platform STK** - Softtek
252
173
 
253
- Frida Platform STK
174
+ ---
254
175
 
176
+ Made with ❤️ by the Frida team
@@ -1492,6 +1492,64 @@ var ComponentLookupService = class {
1492
1492
  }
1493
1493
  };
1494
1494
 
1495
+ // src/figma2frida/services/auth/token-validator.ts
1496
+ var VALIDATION_URL = "https://us-central1-figma2frida-mcp.cloudfunctions.net/validateFridaApiToken";
1497
+ async function validateFridaApiToken(apiToken) {
1498
+ logger.info("\u{1F510} Validating Frida API token...");
1499
+ try {
1500
+ const response = await fetch(VALIDATION_URL, {
1501
+ method: "POST",
1502
+ headers: {
1503
+ "Content-Type": "application/json"
1504
+ },
1505
+ body: JSON.stringify({
1506
+ data: {
1507
+ llmopsApiKey: apiToken
1508
+ }
1509
+ })
1510
+ });
1511
+ const responseData = await response.json();
1512
+ if (response.ok && "result" in responseData && responseData.result?.valid === true) {
1513
+ logger.info(`\u2705 ${responseData.result.message || "API token is valid"}`);
1514
+ return;
1515
+ }
1516
+ if ("error" in responseData) {
1517
+ const error = responseData.error;
1518
+ const errorMessage = error.message || "Unknown error";
1519
+ const errorStatus = error.status || "UNKNOWN";
1520
+ logger.error(`\u274C Token validation failed: ${errorMessage}`);
1521
+ logger.error(` Status: ${errorStatus}`);
1522
+ if (errorStatus === "RESOURCE_EXHAUSTED") {
1523
+ logger.error(" Rate limit exceeded. Please try again later.");
1524
+ } else if (errorStatus === "NOT_FOUND") {
1525
+ logger.error(" Access config not found. Please contact support.");
1526
+ } else if (errorStatus === "PERMISSION_DENIED") {
1527
+ logger.error(" Invalid API token. Please check your token and try again.");
1528
+ }
1529
+ throw new Error(`Token validation failed: ${errorMessage} (${errorStatus})`);
1530
+ }
1531
+ logger.error(`\u274C Unexpected validation response format: ${JSON.stringify(responseData)}`);
1532
+ throw new Error("Unexpected validation response format");
1533
+ } catch (error) {
1534
+ if (error instanceof Error && error.message.startsWith("Token validation failed:")) {
1535
+ throw error;
1536
+ }
1537
+ logger.error("\u274C Failed to validate API token:", error instanceof Error ? error.message : String(error));
1538
+ if (error instanceof Error) {
1539
+ if (error.message.includes("fetch failed") || error.message.includes("ECONNREFUSED")) {
1540
+ logger.error(" Network error: Could not reach validation service.");
1541
+ logger.error(" Please check your internet connection and try again.");
1542
+ throw new Error("Network error: Could not reach validation service");
1543
+ } else if (error.message.includes("timeout")) {
1544
+ logger.error(" Request timeout: Validation service did not respond in time.");
1545
+ logger.error(" Please try again later.");
1546
+ throw new Error("Request timeout: Validation service did not respond in time");
1547
+ }
1548
+ }
1549
+ throw new Error(`Token validation failed: ${error instanceof Error ? error.message : String(error)}`);
1550
+ }
1551
+ }
1552
+
1495
1553
  // src/figma2frida/figma2frida.ts
1496
1554
  var ENVIRONMENT = "production";
1497
1555
  process.env.NODE_ENV = ENVIRONMENT;
@@ -1550,6 +1608,12 @@ if (!FRIDA_TOKEN || FRIDA_TOKEN === "" || FRIDA_TOKEN === "your_api_token_here")
1550
1608
  }
1551
1609
  process.env.FRIDA_BEARER_TOKEN = FRIDA_TOKEN;
1552
1610
  logger.debug(`FRIDA_API_TOKEN: ${FRIDA_TOKEN.substring(0, 8)}... (hidden)`);
1611
+ try {
1612
+ await validateFridaApiToken(FRIDA_TOKEN);
1613
+ } catch (error) {
1614
+ logger.error("\u274C SHUTDOWN: Authentication failed. MCP server cannot start without valid token.");
1615
+ process.exit(1);
1616
+ }
1553
1617
  var HTTP_STREAM = process.env.HTTP_STREAM === "true" || process.env.HTTP_STREAM === "1";
1554
1618
  var PORT = parseInt(process.env.PORT || "8080", 10);
1555
1619
  var designContextCache = /* @__PURE__ */ new Map();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/handlers/component-suggestion-handler.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/utils/design-query-extractor.ts","../src/figma2frida/utils/component-extractor.ts","../src/figma2frida/services/component-lookup.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 = \"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, FigmaDesignContextResult } from \"./clients/figma-client.js\";\nimport { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\nimport { ComponentExtractor } from \"./utils/component-extractor.js\";\nimport { ComponentLookupService } from \"./services/component-lookup.js\";\nimport type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.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 SERVER_VERSION = \"1.0.2\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${SERVER_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.5\";\nprocess.env.PINECONE_TOP_K = \"10\";\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\";\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// 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// Simple in-memory cache for Figma design contexts\nconst designContextCache = new Map<\n string,\n {\n data: FigmaDesignContextResult;\n timestamp: number;\n forceCode: boolean;\n }\n>();\nconst CACHE_TTL_MS = 60000; // 1 minute cache\n\nconst server = new FastMCP({\n instructions: `You are a Figma design assistant optimized for fast code generation using your organization's design system components.\n\n**PRIMARY WORKFLOW (Most Common):**\n1. User asks for code from Figma design\n2. Call \\`figma_get_design_context\\` with:\n - \\`forceCode: true\\`\n - \\`transformToDesignSystem: true\\` (default)\n - \\`autoSearchComponents: true\\` (default)\n - \\`autoImproveLayout: false\\` (default - set to true if visual check is needed)\n3. This tool automatically:\n - Fetches design from Figma\n - Searches for matching design system components\n - Returns code with component documentation\n - Can include a visual screenshot & layout improvement hints (if requested)\n4. Use the transformed code and component docs provided to generate final code.\n\n**ALTERNATIVE WORKFLOWS:**\n\n**Option A: Component Discovery (before code generation)**\n- Call \\`figma_suggest_components\\` to explore available components.\n- Then use results to inform code generation.\n\n**Option B: Query-Only Component Search**\n- Call \\`figma_suggest_components\\` with the \\`query\\` parameter (omit \\`nodeId\\`).\n- **Figma is OPTIONAL** in this mode - it works even if Figma is closed.\n- Useful for browsing design system components without a design context.\n\n**Available tools:**\n- \\`figma_get_design_context\\`: Main tool for code generation (use this for primary workflow).\n- \\`figma_suggest_components\\`: Component discovery/exploration. Works without Figma if \\`query\\` is provided.\n- \\`figma_get_screenshot\\`: Quick visual reference (fast, ~0.5-1s).\n- \\`figma_improve_layout\\`: Layout refinement (call manually only if you need a fresh screenshot without regenerating code).\n\n**🚨 CRITICAL: Follow Figma Design Exactly**\nWhen generating code, you MUST:\n1. **USE THE TRANSFORMED CODE AS YOUR BASE** - It preserves the EXACT structure and layout from Figma.\n2. **USE ONLY DESIGN SYSTEM COMPONENTS** - Use only components found in search results or suggestions.\n3. **PRESERVE DESIGN STRUCTURE** - Maintain all container divs, spacing, and positioning.\n4. **SHOW ELEMENT ANALYSIS** - Display mapping of HTML elements to design system components.`,\n name: \"figma-proxy\",\n version: \"1.0.0\",\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// ============================================================================\n// TOOL 1: Get Screenshot (Fast Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"figma_get_screenshot\",\n description: `Get a screenshot of a Figma node for visual reference.\n\n**Fast & Simple:**\n- Takes ~0.5-1 second\n- Returns just the image, no code generation\n- Use this when you need to see what the design looks like\n\n**Usage:**\n- Provide a nodeId (e.g., \"315-2920\")\n- Or leave empty to use current Figma selection\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\"\n}\n\\`\\`\\``,\n annotations: {\n title: \"Get Screenshot\",\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(`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(args.nodeId);\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 return { content: screenshot.content as Content[] } 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// TOOL 2: Get Design Context (Direct Figma Proxy) - Main Tool\n// ============================================================================\n\nserver.addTool({\n name: \"figma_get_design_context\",\n description: `The ALL-IN-ONE tool for generating code from Figma Desktop.\n\n**Primary Workflow:**\n- Call this tool when the user wants to generate code from a Figma design.\n- It returns design data, generated code, component suggestions, and visual references in a single turn.\n\n**What this does:**\n- Calls Figma's get_design_context tool\n- Returns design data and optionally generated code (React, HTML, etc.)\n- **Discovery (Semantic)**: Automatically analyzes design to suggest components (Pinecone search)\n- **Validation (Exact)**: If code is generated, verifies that used components exist in the library\n- Automatically includes a screenshot for layout refinement (if requested)\n- Results are cached for 60 seconds for instant subsequent access\n- Streams progress updates for better responsiveness\n\n**Performance Modes:**\n- \\`forceCode: false\\` (default) - Fast metadata-only mode (~1-2s)\n- \\`forceCode: true\\` - Full code generation (~3-15s depending on complexity)\n\n**Component Search:**\n- When \\`forceCode: true\\` and \\`autoSearchComponents: true\\` (default), automatically:\n - Extracts component tags from generated code\n - Searches component information in Pinecone\n - Streams component details while processing\n - Adds summary section with found/not found components\n\n**Code Transformation:**\n- When \\`forceCode: true\\` and \\`transformToDesignSystem: true\\` (default), automatically:\n - **Analyzes** all HTML elements found in Figma design\n - **Shows mapping** of HTML elements → design system components before transformation\n - **Transforms** generic HTML elements (button, input, etc.) to design system components\n - **Preserves** ALL structure, layout, CSS classes, and styling from Figma design\n - **Maintains** all container divs, spacing, positioning, and visual hierarchy\n - **Uses component metadata** including framework type, import statements, and usage examples\n - Returns transformed code as the main output, with original code for reference\n - Shows detailed analysis and transformation summary\n\n**Output includes:**\n1. Element Analysis - What HTML elements were found in Figma\n2. Element Mapping - Which design system components will be used for each element\n3. Transformed Code - Ready-to-use code preserving Figma design structure\n4. Original Code - For reference and comparison\n\n**Usage:**\n- Provide a nodeId (e.g., \"315-2920\")\n- Or leave empty to use current Figma selection\n- Set forceCode to true only when you need the actual React/HTML code\n- Set autoSearchComponents to false to disable automatic component search\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\",\n \"forceCode\": true,\n \"autoSearchComponents\": true\n}\n\\`\\`\\`\n\n**Tip:** Start with \\`forceCode: false\\` to quickly see what's available, then request code if needed.`,\n annotations: {\n title: \"Get Design Context from Figma\",\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\" or \"315:2920\"). Leave empty for current selection.'),\n forceCode: z\n .boolean()\n .optional()\n .describe(\"Force code generation even for large outputs (default: false). Set to true only when you need the actual React/HTML code.\"),\n autoSearchComponents: z\n .boolean()\n .optional()\n .describe(\"Automatically search for design system components in the generated code (default: true). Only works when forceCode is true.\"),\n transformToDesignSystem: z\n .boolean()\n .optional()\n .describe(\"Transform Figma-generated code to use design system components (default: true). Only works when forceCode is true. Replaces generic HTML elements (button, input, etc.) with components from your design system library. Framework and language are determined by component metadata.\"),\n autoImproveLayout: z\n .boolean()\n .optional()\n .describe(\"Automatically include a screenshot and layout improvement reference (default: false). Set to true for visual verification.\"),\n }),\n execute: async (args, context) => {\n try {\n logger.debug(\"Tool called\");\n logger.debug(`nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`forceCode: ${args.forceCode ?? false}`);\n logger.debug(`autoImproveLayout: ${args.autoImproveLayout ?? false}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n \n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n };\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const nodeId = args.nodeId;\n const forceCode = args.forceCode ?? false;\n const autoSearchComponents = args.autoSearchComponents ?? true;\n const transformToDesignSystem = args.transformToDesignSystem ?? true;\n const autoImproveLayout = args.autoImproveLayout ?? false;\n\n logger.debug(`NodeId: ${nodeId || \"current selection\"}`);\n logger.debug(`ForceCode: ${forceCode}`);\n logger.debug(`AutoSearchComponents: ${autoSearchComponents}`);\n logger.debug(`TransformToDesignSystem: ${transformToDesignSystem}`);\n logger.debug(`autoImproveLayout: ${autoImproveLayout}`);\n\n // Create cache key - Include all parameters that affect output\n const cacheKey = `${nodeId || \"current\"}:${forceCode}:${autoSearchComponents}:${transformToDesignSystem}:${autoImproveLayout}`;\n const now = Date.now();\n const cached = designContextCache.get(cacheKey);\n\n // Check if we have a valid cached result\n if (cached && now - cached.timestamp < CACHE_TTL_MS) {\n logger.debug(`Using cached result (age: ${(now - cached.timestamp).toFixed(0)}ms)`);\n await context.streamContent({\n type: \"text\",\n text: `⚡ Using cached design context (${((now - cached.timestamp) / 1000).toFixed(1)}s old)`,\n });\n\n const header = {\n type: \"text\" as const,\n text: `✅ **Design Context from Figma** (Cached)\n\n**Node ID:** ${nodeId || \"current selection\"}\n**Content Items:** ${cached.data.content?.length || 0}\n**Cache Age:** ${((now - cached.timestamp) / 1000).toFixed(1)}s\n**Mode:** ${forceCode ? \"Full code generation\" : \"Metadata only (fast mode)\"}\n\n💾 **Cache hit!** This response was retrieved from cache for instant performance.\n\n---\n\n`,\n };\n\n return {\n content: [header, ...(cached.data.content || [])],\n } as ContentResult;\n }\n\n // Provide immediate feedback to user\n await context.streamContent({\n type: \"text\",\n text: `🔄 Fetching design from Figma${forceCode ? \" (including code generation)\" : \"\"}...`,\n });\n\n // Call Figma's get_design_context directly\n logger.debug(\"Calling Figma MCP get_design_context...\");\n const startTime = performance.now();\n const designResult = await figmaClient.getDesignContext(nodeId, {\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode,\n });\n const endTime = performance.now();\n\n // Cache the result\n designContextCache.set(cacheKey, {\n data: designResult,\n timestamp: now,\n forceCode,\n });\n logger.debug(`Cached result for key: ${cacheKey}`);\n\n logger.debug(`Response received in ${(endTime - startTime).toFixed(0)}ms`);\n logger.debug(`Content items: ${designResult.content?.length || 0}`);\n\n if (!designResult.content || designResult.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ No design context returned from Figma MCP.\n\n**Node ID:** ${nodeId || \"current selection\"}\n\n**Troubleshooting:**\n- Ensure the node exists and is accessible in Figma\n- Try selecting the node in Figma first\n- Check if the node has any visible design elements`,\n },\n ],\n };\n }\n\n // Log what we got\n designResult.content.forEach((item, idx) => {\n logger.debug(`Content[${idx}]:`, {\n type: item.type,\n hasText: item.type === \"text\" && \"text\" in item,\n textLength: item.type === \"text\" && \"text\" in item ? item.text?.length : 0,\n hasData: item.type === \"image\" && \"data\" in item,\n });\n });\n\n // Add a header with timing information\n const header = {\n type: \"text\" as const,\n text: `✅ **Design Context from Figma**\n\n**Node ID:** ${nodeId || \"current selection\"}\n**Content Items:** ${designResult.content.length}\n**Fetch Time:** ${(endTime - startTime).toFixed(0)}ms\n**Mode:** ${forceCode ? \"Full code generation\" : \"Metadata only (fast mode)\"}\n\n${forceCode ? \"\" : \"💡 **Tip:** If you need the actual React/HTML code, call this tool again with `forceCode: true`\\n\\n\"}**What you're seeing:** Raw output from Figma's get_design_context tool.\n\n---\n\n`,\n };\n\n logger.debug(\"Design context retrieved successfully\");\n\n // If transformToDesignSystem is enabled (even without forceCode), search for components\n // This supports Use Case 2: Code + Components (discovery mode)\n let transformedCodeSection: Content | null = null;\n let componentSuggestions: ComponentMatch[] = [];\n\n if (transformToDesignSystem && designResult.content) {\n try {\n if (autoSearchComponents) {\n await context.streamContent({\n type: \"text\",\n text: \"🔍 Discovering design system components from design analysis...\",\n });\n\n try {\n // Extract semantic query from design context\n const queryExtractor = new DesignQueryExtractor();\n const searchQuery = queryExtractor.extractQuery(designResult);\n logger.debug(`Extracted query: \"${searchQuery}\"`);\n\n await context.streamContent({\n type: \"text\",\n text: `🔎 Searching Pinecone for: \"${searchQuery}\"...`,\n });\n\n // Search Pinecone for matching components\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n const searchResults = await searchService.search(searchQuery, {\n // topK and minScore use service defaults (read from PINECONE_TOP_K and PINECONE_MIN_SCORE env vars)\n });\n\n componentSuggestions = searchResults.matches;\n const componentNames = componentSuggestions.map((comp) => comp.tag).join(\", \");\n logger.debug(\n `Found ${componentSuggestions.length} components from Pinecone: ${componentNames}`,\n );\n\n if (componentSuggestions.length > 0) {\n await context.streamContent({\n type: \"text\",\n text: `✅ Discovered ${componentSuggestions.length} design system components:\\n${componentSuggestions\n .map((c) => ` - ${c.tag} (${c.category})`)\n .join(\"\\n\")}`,\n });\n } else {\n await context.streamContent({\n type: \"text\",\n text: `⚠️ No components found in Pinecone. Using default mappings.`,\n });\n }\n } catch (error) {\n logger.warn(\n \"Could not get component suggestions:\",\n error,\n );\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error searching Pinecone: ${error instanceof Error ? error.message : String(error)}\\nFalling back to default mappings.`,\n });\n // Continue without suggestions, will use default mappings\n }\n }\n\n // Return component documentation to agent (regardless of forceCode)\n if (componentSuggestions.length > 0) {\n \n // Extract query for display\n const queryExtractor = new DesignQueryExtractor();\n const searchQuery = queryExtractor.extractQuery(designResult);\n\n // Read environment variables for Pinecone search parameters (validated at startup)\n const minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n const topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n const indexName = process.env.PINECONE_INDEX!;\n\n transformedCodeSection = {\n type: \"text\" as const,\n text: `## 🔍 **Available Design System Components from Pinecone**\n\n**Search Query:** \"${searchQuery}\"\n**Components Found:** ${componentSuggestions.length}\n\nUse the component documentation below to transform the Figma code into design system components. The agent will generate the code using these component specifications.\n\n---\n\n${Formatters.toMarkdown({\n query: searchQuery,\n matches: componentSuggestions,\n relevantMatches: componentSuggestions.length,\n totalMatches: componentSuggestions.length,\n searchMetadata: { minScore, topK, indexName },\n lowScoreMatches: []\n})}\n\n**💡 Instructions:** Use the component documentation above to transform the Figma code. Each component includes:\n- Exact prop names and types\n- Event names and types\n- Full documentation\n- Usage examples\n\nGenerate code that uses these components with the correct props and structure.\n\n---\n\n`,\n } as Content;\n } else if (autoSearchComponents) {\n // Only show \"not found\" if we actually searched\n await context.streamContent({\n type: \"text\",\n text: `⚠️ No components found in Pinecone for this design.`,\n });\n }\n } catch (error) {\n logger.error(\"Code transform error:\", error);\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error transforming code: ${error instanceof Error ? error.message : String(error)}\\n`,\n });\n }\n }\n\n // If forceCode is true and autoSearchComponents is enabled, search for components\n // This is for VALIDATION of generated code (requires code to be present)\n let componentSection: Content | null = null;\n if (forceCode && autoSearchComponents && designResult.content) {\n try {\n await context.streamContent({\n type: \"text\",\n text: \"🔍 Analyzing generated code for design system components...\",\n });\n\n // Extract components from the generated code\n const extractedComponents = ComponentExtractor.extractComponents(\n designResult.content,\n );\n\n if (extractedComponents.length > 0) {\n await context.streamContent({\n type: \"text\",\n text: `📦 Found ${extractedComponents.length} component reference(s): ${extractedComponents.map((c) => c.tag).join(\", \")}`,\n });\n\n // Lookup components in Pinecone\n const lookupService = new ComponentLookupService(undefined, { namespace: PINECONE_NAMESPACE });\n const componentTags = extractedComponents.map((c) => c.tag);\n\n await context.streamContent({\n type: \"text\",\n text: `🔎 Searching component information in Pinecone...`,\n });\n\n const lookupResults = await lookupService.lookupMultipleComponents(\n componentTags,\n );\n\n const summary = ComponentLookupService.getSummary(lookupResults);\n\n // Stream individual component information\n for (const result of lookupResults) {\n if (result.found && result.component) {\n const comp = result.component;\n await context.streamContent({\n type: \"text\",\n text: `✅ **${comp.tag}** - ${comp.category}\\n${comp.name || comp.tag}\\n${comp.documentation ? comp.documentation.substring(0, 200) + \"...\" : \"No documentation available\"}\\n`,\n });\n } else {\n await context.streamContent({\n type: \"text\",\n text: `⚠️ **${result.tag}** - Not found in component library\\n`,\n });\n }\n }\n\n // Create summary section\n let summaryText = `\\n## 📋 **Component Analysis Summary**\n\n**Total components found in code:** ${summary.total}\n**Found in library:** ${summary.found}\n**Not found:** ${summary.notFound}\n\n`;\n\n if (summary.foundComponents.length > 0) {\n summaryText += `### ✅ Components Found:\\n\\n`;\n summary.foundComponents.forEach((comp) => {\n summaryText += `- **${comp.tag}** (${comp.category}) - Score: ${comp.score.toFixed(4)}\\n`;\n if (comp.documentation) {\n summaryText += ` - ${comp.documentation.substring(0, 100)}${comp.documentation.length > 100 ? \"...\" : \"\"}\\n`;\n }\n });\n summaryText += `\\n`;\n }\n\n if (summary.notFoundTags.length > 0) {\n summaryText += `### ⚠️ Components Not Found:\\n\\n`;\n summary.notFoundTags.forEach((tag) => {\n summaryText += `- **${tag}** - This component may not be indexed in Pinecone or may not exist\\n`;\n });\n summaryText += `\\n`;\n }\n\n summaryText += `💡 **Tip:** Use \\`figma_suggest_components\\` tool to get detailed information and usage examples for these components.\\n\\n---\\n\\n`;\n\n componentSection = {\n type: \"text\" as const,\n text: summaryText,\n } as Content;\n } else {\n await context.streamContent({\n type: \"text\",\n text: `ℹ️ No design system components found in the generated code.\\n`,\n });\n }\n } catch (error) {\n logger.error(\"Component search error:\", error);\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error searching for components: ${error instanceof Error ? error.message : String(error)}\\n`,\n });\n }\n }\n\n // Return content with optional sections\n const finalContent: Content[] = [header];\n \n // Always include original Figma code\n finalContent.push(...(designResult.content as Content[]));\n \n // Add component documentation if available (for agent to use)\n if (transformedCodeSection) {\n finalContent.push(transformedCodeSection);\n }\n \n // Add component analysis section if available\n if (componentSection) {\n finalContent.push(componentSection);\n }\n\n // If autoImproveLayout is enabled (default: false), fetch and add screenshot\n // This supports Use Case 4: Refinement Loop (manual or auto)\n if (autoImproveLayout) {\n try {\n logger.debug(\"Fetching integrated screenshot for layout improvement...\");\n await context.streamContent({\n type: \"text\",\n text: \"📸 Fetching Figma screenshot for layout refinement...\",\n });\n const screenshot = await figmaClient.getScreenshot(nodeId);\n if (screenshot.content && screenshot.content.length > 0) {\n finalContent.push({\n type: \"text\" as const,\n text: `\\n## 📐 **Layout Improvement Reference**\\n\\nUse the screenshot below to verify your generated code matches the Figma design exactly.\\n\\n**Key Areas to Verify:**\\n- ✅ **Element spacing and margins**\\n- ✅ **Alignment and positioning**\\n- ✅ **Colors and typography**\\n- ✅ **Border radius and shadows**\\n\\n---\\n\\n`,\n });\n finalContent.push(...(screenshot.content as Content[]));\n }\n } catch (error) {\n logger.error(\"Screenshot fetch failed:\", error);\n finalContent.push({\n type: \"text\" as const,\n text: `\\n⚠️ **Note:** Automated screenshot for layout improvement failed: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n return {\n content: finalContent,\n } as ContentResult;\n } catch (error) {\n logger.error(\"Design context error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Get Design Context**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is the node ID valid?\n3. Is Figma MCP enabled? (Figma → Preferences → Enable MCP)\n4. Try restarting Figma Desktop\n\n${error instanceof Error && error.stack ? `\\n**Stack:**\\n${error.stack}` : \"\"}`,\n },\n ],\n };\n }\n },\n});\n\n// ============================================================================\n// TOOL 3: Suggest Components from Design System\n// ============================================================================\n\nserver.addTool({\n name: \"figma_suggest_components\",\n description: `Search and explore design system components.\n\n**Figma is OPTIONAL:**\n- If you provide a \\`query\\` and omit \\`nodeId\\`, the tool works even if Figma is closed.\n- If you omit \\`query\\`, it extracts the context from the current Figma selection.\n\n**WHEN TO USE:**\n- Use this tool for **DISCOVERY** and **EXPLORATION** of the component library.\n- Use this when you want to know \"What components are available for X?\" without generating full code.\n\n**⚠️ DO NOT USE FOR CODE GENERATION:**\n- If your goal is to generate code from a Figma design, use \\`figma_get_design_context\\` instead. It is faster and integrates component search automatically.`,\n annotations: {\n title: \"Suggest Design System Components\",\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\" or \"315:2920\"). Leave empty for current selection.'),\n minScore: z\n .number()\n .optional()\n .describe(\"Minimum Pinecone relevance score (default: 0.05). Higher values return more relevant results.\"),\n topK: z\n .number()\n .optional()\n .describe(\"Maximum number of components to retrieve (default: 10).\"),\n useFrida: z\n .boolean()\n .optional()\n .describe(\"Enable Frida AI processing for intelligent recommendations (default: true).\"),\n query: z\n .string()\n .optional()\n .describe(\"Custom search query. If provided, Figma connection is optional unless nodeId is also provided.\"),\n }),\n execute: async (args, context) => {\n logger.debug(\"Tool called\");\n logger.debug(`nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`query: ${args.query || 'none'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n \n const requiresFigma = !args.query || args.nodeId;\n if (!figmaConnected && requiresFigma) {\n logger.warn(\"Early return: figmaConnected is false and Figma is required\");\n return {\n content: [\n {\n type: \"text\" as const,\n text: args.query \n ? \"❌ Figma connection required when using nodeId. For query-only mode, omit nodeId.\" \n : \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n };\n }\n\n logger.debug(\"Proceeding with component suggestion...\");\n const nodeId = args.nodeId;\n const minScore = args.minScore ?? 0.05;\n const topK = args.topK ?? 10;\n const useFrida = args.useFrida ?? true;\n const customQuery = args.query;\n\n logger.debug(`NodeId: ${nodeId || \"current selection\"}`);\n logger.debug(`MinScore: ${minScore}`);\n logger.debug(`TopK: ${topK}`);\n logger.debug(`UseFrida: ${useFrida}`);\n\n // Get design context from Figma (only if needed)\n let designResult: FigmaDesignContextResult;\n \n if (customQuery && !nodeId) {\n // Query-only mode: skip Figma\n logger.debug(\"Query-only mode: skipping Figma fetch\");\n designResult = { content: [] };\n } else {\n // Normal mode: fetch from Figma\n await context.streamContent({\n type: \"text\",\n text: \"🎨 Fetching design context from Figma...\",\n });\n\n const designCacheKey = `${nodeId || \"current\"}:false`;\n const now = Date.now();\n const cachedDesign = designContextCache.get(designCacheKey);\n const designCacheAge = cachedDesign\n ? now - cachedDesign.timestamp\n : CACHE_TTL_MS + 1;\n\n if (cachedDesign && designCacheAge < CACHE_TTL_MS) {\n logger.debug(\"Using cached design context\");\n designResult = cachedDesign.data;\n } else {\n designResult = await figmaClient.getDesignContext(nodeId, {\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: false, // Use metadata mode for faster response\n });\n // Cache it\n designContextCache.set(designCacheKey, {\n data: designResult,\n timestamp: now,\n forceCode: false,\n });\n }\n }\n\n // Use the handler for component suggestion logic\n return handleComponentSuggestion({\n nodeId,\n minScore,\n topK,\n useFrida,\n query: customQuery,\n namespace: PINECONE_NAMESPACE,\n designContext: designResult,\n getDesignContext: figmaClient.getDesignContext.bind(figmaClient),\n streamContent: async (content: { type: \"text\"; text: string } | Array<{ type: \"text\"; text: string }>) => {\n if (Array.isArray(content)) {\n for (const item of content) {\n await context.streamContent(item);\n }\n } else {\n await context.streamContent(content);\n }\n },\n });\n },\n});\n\n// ============================================================================\n// TOOL 4: Improve Layout to Match Figma Frame Reference\n// ============================================================================\n\nserver.addTool({\n name: \"figma_improve_layout\",\n description: `Improve the generated layout to visually match the Figma frame reference.\n\n**WHEN TO USE:**\n- Use this tool when the user asks to fix spacing, alignment, or visual issues AFTER code generation.\n- It provides a fresh screenshot and specific layout improvement instructions.\n- This is a refinement tool, typically used in a loop to polish the UI.\n\n**What this does:**\n- Fetches the Figma screenshot (visual reference) for the specified node\n- Provides the screenshot as a visual reference for layout improvement\n- Use this tool after generating code from Figma to refine the layout\n- Compare your generated code output with the screenshot to adjust spacing, positioning, and styling\n\n**Usage:**\n- Call this tool after generating code from Figma\n- Provide a nodeId (e.g., \"315-2920\") or leave empty for current selection\n- The tool will fetch the screenshot and provide it as a visual reference\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\"\n}\n\\`\\`\\``,\n annotations: {\n title: \"Improve Layout to Match Figma\",\n readOnlyHint: false,\n openWorldHint: false,\n },\n parameters: z.object({\n nodeId: z\n .string()\n .optional()\n .describe('Figma node ID (e.g., \"315-2920\" or \"315:2920\"). Leave empty for current selection.'),\n }),\n execute: async (args, _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 return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n } as ContentResult;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n if (!screenshot.content || screenshot.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ No screenshot returned from Figma MCP.\",\n },\n ],\n } as ContentResult;\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `✅ **Visual Reference from Figma**\n\n**Node ID:** ${args.nodeId || \"current selection\"}\n\n**Instructions for Layout Improvement:**\n\nCompare the screenshot below with your generated code output. Adjust the following to match the Figma design exactly:\n\n**Key Areas to Verify:**\n- ✅ **Element spacing and margins** - Ensure spacing matches the design\n- ✅ **Alignment and positioning** - Check vertical and horizontal alignment\n- ✅ **Colors and typography** - Match colors, font sizes, and font weights\n- ✅ **Border radius and shadows** - Verify rounded corners and shadow effects\n- ✅ **Responsive behavior** - Ensure layout works at different screen sizes\n- ✅ **Component sizing** - Check width, height, and aspect ratios\n\n**Visual Reference:**\nThe screenshot below shows the exact Figma design you should match.\n\n---\n\n`,\n },\n ...screenshot.content,\n ],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Improve layout error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Get Screenshot for Layout Improvement**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is the node ID valid?\n3. Is Figma MCP enabled? (Figma → Preferences → Enable MCP)\n4. Try restarting Figma Desktop\n\n${error instanceof Error && error.stack ? `\\n**Stack:**\\n\\`\\`\\`\\n${error.stack}\\n\\`\\`\\`` : \"\"}`,\n },\n ],\n } as ContentResult;\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(`\nAvailable Tools:\n- figma_get_screenshot: Get visual screenshot (fast)\n- figma_get_design_context: Get design data and generated code (with caching & streaming)\n- figma_suggest_components: Suggest design system components based on Figma design (with Pinecone & Frida AI)\n- figma_improve_layout: Trigger layout improvement to match Figma frame reference\n\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 * Call Figma's get_design_context tool\n */\n async getDesignContext(\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n forceCode?: boolean;\n },\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n const args = {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\n forceCode: options?.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 logger.debug(`get_design_context response type: ${typeof result}`);\n logger.debug(`get_design_context response keys: ${Object.keys(result).join(\", \")}`);\n\n return result as FigmaDesignContextResult;\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: {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\n forceCode: options?.forceCode ?? true,\n },\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 nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n },\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 logger.debug(`get_metadata response type: ${typeof result}`);\n logger.debug(`get_metadata response keys: ${Object.keys(result).join(\", \")}`);\n\n return result as FigmaMetadataResult;\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 */\n async getScreenshot(\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n },\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 * Component Suggestion Handler\n * Handles the logic for suggesting design system components based on Figma designs\n */\n\nimport \"dotenv/config\"; // Load .env file FIRST, before any service imports\nimport type { FigmaDesignContextResult } from \"../clients/figma-client.js\";\nimport { PineconeSearchService } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { DesignQueryExtractor } from \"../utils/design-query-extractor.js\";\nimport { logger } from \"../utils/logger.js\";\n\n// Cache for component suggestions\nconst componentSuggestionsCache = new Map<\n string,\n {\n data: Array<{ type: \"text\"; text: string }>;\n timestamp: number;\n }\n>();\nconst COMPONENT_CACHE_TTL_MS = 300000; // 5 minutes cache for component suggestions\n\n// Lazy initialization of services\nlet pineconeService: PineconeSearchService | null = null;\nlet pineconeServiceNamespace: string | undefined = undefined;\nlet fridaClient: FridaClient | null = null;\nlet queryExtractor: DesignQueryExtractor | null = null;\n\nfunction getPineconeService(namespace?: string): PineconeSearchService {\n // Recreate service if namespace changed\n if (!pineconeService || pineconeServiceNamespace !== namespace) {\n pineconeService = new PineconeSearchService({ namespace });\n pineconeServiceNamespace = namespace;\n }\n return pineconeService;\n}\n\nfunction getFridaClient(): FridaClient {\n if (!fridaClient) {\n fridaClient = new FridaClient();\n }\n return fridaClient;\n}\n\nfunction getQueryExtractor(): DesignQueryExtractor {\n if (!queryExtractor) {\n queryExtractor = new DesignQueryExtractor();\n }\n return queryExtractor;\n}\n\nexport interface ComponentSuggestionOptions {\n nodeId?: string;\n minScore?: number;\n topK?: number;\n useFrida?: boolean;\n query?: string;\n namespace?: string;\n designContext: FigmaDesignContextResult;\n getDesignContext: (\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n forceCode?: boolean;\n },\n ) => Promise<FigmaDesignContextResult>;\n streamContent?: (\n content: { type: \"text\"; text: string } | Array<{ type: \"text\"; text: string }>,\n ) => Promise<void>;\n}\n\nimport type { ContentResult } from \"fastmcp\";\n\nexport type ComponentSuggestionResult = ContentResult;\n\n/**\n * Handles component suggestion request\n */\nexport async function handleComponentSuggestion(\n options: ComponentSuggestionOptions,\n): Promise<ComponentSuggestionResult> {\n const {\n nodeId,\n minScore = 0.05,\n topK = 10,\n useFrida = true,\n query: customQuery,\n namespace,\n designContext,\n streamContent,\n } = options;\n\n try {\n // Create cache key\n const cacheKey = `${nodeId || \"current\"}:${minScore}:${topK}:${useFrida}:${customQuery || \"auto\"}`;\n const now = Date.now();\n const cached = componentSuggestionsCache.get(cacheKey);\n\n // Check cache\n if (cached && now - cached.timestamp < COMPONENT_CACHE_TTL_MS) {\n logger.debug(\n `Using cached result (age: ${((now - cached.timestamp) / 1000).toFixed(1)}s)`,\n );\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: `⚡ Using cached component suggestions (${((now - cached.timestamp) / 1000).toFixed(1)}s old)`,\n });\n }\n return { content: cached.data } as ComponentSuggestionResult;\n }\n\n if (!designContext.content || designContext.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ No design context returned from Figma MCP.\n\n**Node ID:** ${nodeId || \"current selection\"}\n\nCannot suggest components without design context.`,\n },\n ],\n };\n }\n\n // Extract query from design context\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: \"🔍 Extracting semantic query from design...\",\n });\n }\n\n const extractor = getQueryExtractor();\n const searchQuery = customQuery || extractor.extractQuery(designContext);\n\n logger.debug(`Extracted query: \"${searchQuery}\"`);\n\n // Search Pinecone\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: `🔎 Searching Pinecone for: \"${searchQuery}\"...`,\n });\n }\n\n logger.debug(\"Calling Pinecone search service...\");\n const searchService = getPineconeService(namespace);\n const searchStartTime = Date.now();\n const searchResults = await searchService.search(searchQuery, {\n minScore,\n topK,\n });\n const searchTime = Date.now() - searchStartTime;\n\n logger.debug(\n `Pinecone search completed in ${searchTime}ms - Found ${searchResults.relevantMatches} relevant components`,\n );\n\n if (searchResults.matches.length === 0) {\n const namespaceInfo = searchResults.searchMetadata.namespace\n ? `\\n**Namespace:** ${searchResults.searchMetadata.namespace}`\n : \"\";\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `⚠️ **No Components Found**\n\n**Query:** \"${searchQuery}\"\n**Min Score:** ${minScore}${namespaceInfo}\n**Index:** ${searchResults.searchMetadata.indexName}\n\nNo components from your design system matched the design context with sufficient relevance.\n\n**Possible Causes:**\n- The namespace \"${searchResults.searchMetadata.namespace || 'default'}\" may not exist or may be empty\n- Components may not be indexed in this namespace\n- The query may not match any components in this namespace\n\n**Suggestions:**\n- Verify that components are indexed in Pinecone${searchResults.searchMetadata.namespace ? ` namespace \"${searchResults.searchMetadata.namespace}\"` : \"\"}\n- Set namespace via \\`--project-id\\` CLI argument if not set\n- Try lowering the \\`minScore\\` parameter\n- Provide a more specific \\`query\\` parameter`,\n },\n ],\n };\n }\n\n // Extract component tags and detect patterns\n const componentTags = searchResults.matches.map(m => m.tag).join(\", \");\n const frameworkType = searchResults.matches[0]?.framework || \"html\";\n\n // Detect component prefix patterns dynamically (e.g., san-, comdig-, mat-, etc.)\n const prefixPatterns = Array.from(\n new Set(\n searchResults.matches\n .map(m => {\n const match = m.tag.match(/^([a-z]+-)/);\n return match ? match[1] : null;\n })\n .filter(Boolean)\n )\n ).join(\", \");\n\n // Format results\n const content: Array<{ type: \"text\"; text: string }> = [\n {\n type: \"text\" as const,\n text: `🚨 **MANDATORY: USE ONLY COMPONENTS FROM YOUR DESIGN SYSTEM**\n\n**CRITICAL INSTRUCTIONS:**\n- You MUST use ONLY the components listed below from your organization's design system\n- **DO NOT** use components from other libraries unless they appear in the search results\n- **DO NOT** use generic HTML elements directly - use the design system components instead\n${prefixPatterns ? `- Component prefixes in your system: ${prefixPatterns}` : \"\"}\n${frameworkType ? `- Framework type: ${frameworkType}` : \"\"}\n\n**Available Components for this design:**\n${componentTags || \"No components found\"}\n\n---\n\n✅ **Component Suggestions**\n\n**Query:** \"${searchQuery}\"\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n**Min Score:** ${minScore}\n\n---\n\n`,\n },\n ];\n\n // Add mandatory usage instructions\n content.push({\n type: \"text\" as const,\n text: `## 📋 MANDATORY USAGE INSTRUCTIONS\n\n**You MUST follow these rules when generating code:**\n\n1. **Use ONLY the components from the search results below**\n2. **DO NOT use:**\n - ❌ Components from other libraries not listed in the results\n - ❌ Generic HTML elements unless the component wraps them\n - ❌ Any component not found in your organization's design system\n\n3. **Use the recommended components:**\n - ✅ Use ONLY the components listed in the search results below\n - ✅ Follow the documentation provided for each component\n - ✅ Respect the component's framework and usage as documented\n - ✅ If a component is not in the list below, do NOT use it\n\n4. **Framework compatibility:** Check the \\`framework\\` field for each component\n\n---\n\n## Search Results (${searchResults.relevantMatches} components)\n\n${Formatters.toMarkdown(searchResults)}\n\n---\n\n`,\n });\n\n // Process with Frida AI if enabled\n if (useFrida) {\n const frida = getFridaClient();\n if (frida.isEnabled()) {\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: \"🤖 Processing with Frida AI for intelligent recommendations...\",\n });\n }\n\n const contextForFrida = Formatters.matchesToContext(\n searchResults.matches,\n );\n const question = `Based on this Figma design context, which component(s) from the design system should I use? Design description: ${searchQuery}`;\n\n logger.debug(`Calling Frida AI with ${searchResults.matches.length} component matches...`);\n const fridaStartTime = Date.now();\n const fridaResponse = await frida.ask(question, contextForFrida);\n const fridaTime = Date.now() - fridaStartTime;\n logger.debug(`Frida AI completed in ${fridaTime}ms - Success: ${fridaResponse.success}`);\n\n if (fridaResponse.success && fridaResponse.response) {\n content.push({\n type: \"text\" as const,\n text: `## 🤖 Frida AI Recommendation\n\n${fridaResponse.response}\n\n---\n\n`,\n });\n\n if (fridaResponse.metadata?.tokensUsed) {\n content.push({\n type: \"text\" as const,\n text: `*(Tokens used: ${fridaResponse.metadata.tokensUsed})*\n\n---\n\n`,\n });\n }\n } else {\n content.push({\n type: \"text\" as const,\n text: `⚠️ **Frida AI Processing Failed**\n\n${fridaResponse.error || \"Unknown error\"}\n\nFalling back to raw search results.\n\n---\n\n`,\n });\n }\n } else {\n content.push({\n type: \"text\" as const,\n text: `ℹ️ **Frida AI Not Configured**\n\nFrida AI is not enabled. Set \\`FRIDA_BEARER_TOKEN\\` and \\`FRIDA_API_URL\\` environment variables to enable intelligent recommendations.\n\nShowing raw search results instead.\n\n---\n\n`,\n });\n }\n }\n\n // Cache the result\n componentSuggestionsCache.set(cacheKey, {\n data: content,\n timestamp: now,\n });\n\n logger.debug(\"Completed successfully\");\n\n return { content };\n } catch (error) {\n logger.error(\"Failed to suggest components:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Suggest Components**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is Pinecone configured? (Check PINECONE_API_KEY)\n3. Are components indexed in Pinecone?\n4. Check the console for detailed error messages`,\n },\n ],\n };\n }\n}\n\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 documentation: string; // From metadata.documentation (markdown)\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 lowScoreMatches: Array<{ tag: string; score: number }>;\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: \"design_system@example.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, documentation\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 documentation: (metadata.documentation 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\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 lowScoreMatches: allMatches\n .filter((m) => (m.score || 0) < minScore)\n .map((match) => {\n const metadata = match.metadata || {};\n const tag = (metadata.tag as string) || \n (metadata.id as string) || \n match.id ||\n \"unknown\";\n return {\n tag,\n score: match.score || 0,\n };\n }),\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 * 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 || \"Innovation-gpt4o\";\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 optimized prompt for code generation\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert agent in code generation for UI design systems and component libraries.\nYour goal is to provide technical, precise, and ready-to-use answers that enable generating functional code immediately.\n\n**🚨 CRITICAL RULES - MANDATORY COMPLIANCE:**\n\n1. **You MUST use ONLY the components** from the AVAILABLE COMPONENT INFORMATION below\n2. **NEVER suggest or use:**\n - ❌ Components from other libraries not listed in the AVAILABLE COMPONENT INFORMATION\n - ❌ Generic HTML form elements: <button>, <input>, <select>, <textarea> (unless they are wrapped in design system components)\n - ❌ Any other component library or framework-specific components not in the AVAILABLE COMPONENT INFORMATION\n\n3. **Use components exactly as documented** - they may be Web Components, React components, Angular components, or any other framework\n4. **If a component is not in the AVAILABLE COMPONENT INFORMATION**, say so clearly - DO NOT invent or use generic alternatives\n\n**EXAMPLES OF WHAT NOT TO DO:**\n- ❌ WRONG: Using components from other libraries (mat-*, MUI, etc.) unless they appear in AVAILABLE COMPONENT INFORMATION\n- ❌ WRONG: Using any component that is NOT in the AVAILABLE COMPONENT INFORMATION below\n- ❌ WRONG: Inventing component names or props not in the documentation\n\n**EXAMPLES OF WHAT TO DO:**\n- ✅ Use ONLY components from the AVAILABLE COMPONENT INFORMATION below\n- ✅ Check the component tag/selector in the AVAILABLE COMPONENT INFORMATION before using it\n- ✅ Use the exact component names, props, and events as shown in the AVAILABLE COMPONENT INFORMATION\n- ✅ Follow the framework_type and import_statement provided for each component\n- ✅ If a component is not listed in AVAILABLE COMPONENT INFORMATION, do NOT use it - say clearly that it doesn't exist\n\n## AVAILABLE COMPONENT INFORMATION:\n\nThe component information below is provided in JSON format for accurate parsing.\nUse the exact prop names, types, and structure as shown in the JSON.\n\n${context}\n\n**IMPORTANT:** The component information above is in JSON format. Parse it carefully and use:\n- Exact prop names as shown in the props array\n- Exact prop types from type_signature field\n- Event names exactly as shown in the events array\n- Framework type from framework_type field\n- Import statements from import_statement field\n- Follow the structure and patterns from the JSON data\n\n## RESPONSE INSTRUCTIONS:\n\n### 1. MANDATORY STRUCTURE:\nYour response MUST follow this format:\n\n🚨 **RECOMMENDED COMPONENT:** [component name - MUST be from AVAILABLE COMPONENT INFORMATION]\n**CATEGORY:** [component category]\n**FRAMEWORK:** [framework_type from the component data]\n\n**DESCRIPTION:**\n[Brief explanation of the component and when to use it]\n\n**IMPORT:**\n\\`\\`\\`\n[import_statement from the component data if available]\n\\`\\`\\`\n\n**EXAMPLE CODE:**\n\\`\\`\\`html\n[Minimal functional and complete example]\n\\`\\`\\`\n\n**IMPORTANT PROPERTIES:**\n[List of key properties with types and possible values]\n- \\`property\\`: \\`type_signature\\` - [description]\n\n**EVENT HANDLING:**\n[If applicable, how to listen and handle events]\n\\`\\`\\`javascript\n[Example code to handle events]\n\\`\\`\\`\n\n**ADDITIONAL NOTES:**\n[Any important considerations, best practices, or limitations]\n\n### 2. CODE GENERATION RULES:\n\n1. **Use ONLY components from the AVAILABLE COMPONENT INFORMATION above** - Do NOT use components from other libraries\n2. **Do not invent properties or events** - Use only what exists in the component documentation provided\n3. **Exact types:** Include the exact types of properties from type_signature field\n4. **Functional code:** The example code MUST be copyable and functional\n5. **Required props:** If a prop is required, indicate it clearly\n6. **Default values:** If there are default values (default_value field), mention them\n7. **Events:** Include examples of how to listen to events if the component emits them\n8. **Framework compatibility:** Use the framework_type and import_statement from the component data\n9. **Necessary imports:** Include the import_statement from the component data\n10. **If a component doesn't exist:** Say clearly \"No component available for [feature]. Available components are: [list]\"\n\n### 3. QUESTION ANALYSIS:\n\n- If asking about a specific component: Provide complete technical documentation\n- If asking \"how to do X\": Suggest the most suitable component AND provide functional code\n- If asking about properties: List ALL relevant properties with exact types\n- If asking about events: Provide complete examples of event handling\n\n### 4. TECHNICAL ACCURACY:\n\n- Use the exact names of properties as they appear in the documentation\n- Respect exact types (union types, enums, etc.)\n- Include all attributes necessary for the code to work\n- Mention if there are slots available and how to use them\n\n### 5. IF NO INFORMATION:\n\nIf the context does not contain enough information to answer, say clearly:\n\"I don't have enough information about [aspect] in the provided context. Available components are: [list]\"\n\n## USER QUESTION:\n${question}\n\n## RESPONSE (Follow the mandatory structure above):`.trim();\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","/**\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 documentation: string;\n }>;\n lowScoreComponents: Array<{ tag: string; score: number }>;\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 documentation: match.documentation,\n })),\n lowScoreComponents: searchResults.lowScoreMatches || [],\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 let markdown = `## Search Results\n\n**Query:** \"${searchResults.query}\"\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n**Minimum score:** ${searchResults.searchMetadata.minScore}\n\n---\n\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag} (Score: ${match.score.toFixed(4)})\n\n**Name:** ${match.name || match.tag}\n**Category:** ${match.category}\n**Framework:** ${match.framework}\n\n**Documentation:**\n${match.documentation || \"No documentation available\"}\n\n---\n\n`;\n });\n\n if (\n searchResults.lowScoreMatches &&\n searchResults.lowScoreMatches.length > 0\n ) {\n markdown += `\\n### Components with low relevance (score < ${searchResults.searchMetadata.minScore})\\n\\n`;\n searchResults.lowScoreMatches.forEach((match, idx) => {\n markdown += `${idx + 1}. ${match.tag} (Score: ${match.score.toFixed(4)})\\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 id: match.id,\n tag: match.tag,\n name: match.name,\n framework: match.framework,\n category: match.category,\n documentation: match.documentation,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n}\n\n","/**\n * Design Query Extractor\n * Extracts semantic queries from Figma design context for component search\n */\n\nimport type { FigmaDesignContextResult } from \"../clients/figma-client.js\";\n\nexport interface ExtractionStrategy {\n name: string;\n extract(context: FigmaDesignContextResult): string[];\n}\n\n/**\n * Extracts semantic query from Figma design context\n */\nexport class DesignQueryExtractor {\n private strategies: ExtractionStrategy[];\n\n constructor() {\n this.strategies = [\n new TextExtractionStrategy(),\n new PatternMatchingStrategy(),\n new MetadataExtractionStrategy(),\n ];\n }\n\n /**\n * Extracts query from design context using all available strategies\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n const queries: string[] = [];\n\n // Try each strategy\n for (const strategy of this.strategies) {\n try {\n const extracted = strategy.extract(designContext);\n queries.push(...extracted);\n } catch (error) {\n console.warn(\n `[QUERY EXTRACTOR] Strategy ${strategy.name} failed:`,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n // Remove duplicates and empty strings\n const uniqueQueries = Array.from(\n new Set(queries.filter((q) => q && q.trim().length > 0)),\n );\n\n // If we have queries, combine them intelligently\n if (uniqueQueries.length > 0) {\n // Take the first few most relevant queries\n const topQueries = uniqueQueries.slice(0, 3);\n // Combine for better semantic search in component library\n return `${topQueries.join(\" \")} component`.trim();\n }\n\n return fallbackQuery;\n }\n}\n\n/**\n * Strategy: Extract meaningful text from design context\n */\nclass TextExtractionStrategy implements ExtractionStrategy {\n name = \"text-extraction\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n for (const item of context.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text.trim();\n if (text.length > 0) {\n // Extract component-like keywords\n const componentKeywords = this.extractComponentKeywords(text);\n queries.push(...componentKeywords);\n\n // Extract descriptive phrases\n const descriptivePhrases = this.extractDescriptivePhrases(text);\n queries.push(...descriptivePhrases);\n }\n }\n }\n\n return queries;\n }\n\n private extractComponentKeywords(text: string): string[] {\n const keywords: string[] = [];\n\n // Common UI component patterns\n const patterns = [\n { pattern: /button|btn/gi, keyword: \"button\" },\n { pattern: /input|textfield|text field/gi, keyword: \"input\" },\n { pattern: /card|panel/gi, keyword: \"card\" },\n { pattern: /badge|label|tag/gi, keyword: \"badge\" },\n { pattern: /alert|message|notification/gi, keyword: \"alert\" },\n { pattern: /modal|dialog|popup/gi, keyword: \"modal\" },\n { pattern: /dropdown|select|picker/gi, keyword: \"dropdown\" },\n { pattern: /checkbox|check box/gi, keyword: \"checkbox\" },\n { pattern: /radio|radio button/gi, keyword: \"radio\" },\n { pattern: /slider|range/gi, keyword: \"slider\" },\n { pattern: /table|grid|list/gi, keyword: \"table\" },\n { pattern: /breadcrumb|breadcrumb navigation/gi, keyword: \"breadcrumb\" },\n { pattern: /tooltip|tip/gi, keyword: \"tooltip\" },\n { pattern: /accordion|collapsible/gi, keyword: \"accordion\" },\n { pattern: /progress|loader|spinner/gi, keyword: \"progress\" },\n ];\n\n for (const { pattern, keyword } of patterns) {\n if (pattern.test(text)) {\n keywords.push(keyword);\n }\n }\n\n return keywords;\n }\n\n private extractDescriptivePhrases(text: string): string[] {\n const phrases: string[] = [];\n\n // Extract sentences or phrases that describe UI elements\n // Look for patterns like \"a button that...\", \"an input for...\", etc.\n const descriptionPatterns = [\n /(?:a |an |the )?([a-z]+(?: [a-z]+){0,3}) (?:that |for |to |with |in |on )/gi,\n /(?:create |make |add |use |show |display )([a-z]+(?: [a-z]+){0,3})/gi,\n ];\n\n for (const pattern of descriptionPatterns) {\n const matches = text.matchAll(pattern);\n for (const match of matches) {\n if (match[1] && match[1].length > 2) {\n phrases.push(match[1].trim());\n }\n }\n }\n\n return phrases.slice(0, 5); // Limit to top 5 phrases\n }\n}\n\n/**\n * Strategy: Pattern matching for common UI patterns\n */\nclass PatternMatchingStrategy implements ExtractionStrategy {\n name = \"pattern-matching\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n const combinedText = context.content\n .filter((item) => item.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text as string)\n .join(\" \");\n\n if (combinedText.length === 0) {\n return queries;\n }\n\n // Detect HTML elements and extract element types\n const elementTypes: string[] = [];\n\n // Button patterns\n if (/<(?:button|Button)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"button\");\n }\n\n // Input patterns (various types)\n if (/<(?:input|Input)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"input\");\n // Check for specific input types\n if (/type=[\"'](?:text|email|password|number)/gi.test(combinedText)) {\n elementTypes.push(\"text input\");\n }\n if (/type=[\"']checkbox/gi.test(combinedText)) {\n elementTypes.push(\"checkbox\");\n }\n if (/type=[\"']radio/gi.test(combinedText)) {\n elementTypes.push(\"radio\");\n }\n if (/type=[\"']range/gi.test(combinedText)) {\n elementTypes.push(\"slider\");\n }\n }\n\n // Textarea\n if (/<(?:textarea|Textarea)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"textarea\");\n }\n\n // Select/Dropdown\n if (/<(?:select|Select)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"dropdown\");\n elementTypes.push(\"select\");\n }\n\n // Card patterns\n if (/<(?:div|Div)[^>]*class[^>]*(?:card|Card|panel|Panel)/gi.test(combinedText)) {\n elementTypes.push(\"card\");\n }\n\n // Badge/Label patterns\n if (/<(?:span|Span)[^>]*class[^>]*(?:badge|Badge|label|Label|tag|Tag)/gi.test(combinedText)) {\n elementTypes.push(\"badge\");\n }\n\n // Alert/Message patterns\n if (/<(?:div|Div)[^>]*class[^>]*(?:alert|Alert|message|Message|notification|Notification)/gi.test(combinedText)) {\n elementTypes.push(\"alert\");\n }\n\n // Form patterns\n if (/<(?:form|Form)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"form\");\n }\n\n // Navigation patterns\n if (/<(?:nav|Nav|ul|Ul)[^>]*class[^>]*(?:nav|Nav|menu|Menu|breadcrumb|Breadcrumb)/gi.test(combinedText)) {\n elementTypes.push(\"navigation\");\n }\n\n // Link patterns\n if (/<(?:a|A)[^>]*href/gi.test(combinedText)) {\n elementTypes.push(\"link\");\n elementTypes.push(\"action link\");\n }\n\n // Convert element types to queries\n for (const elementType of elementTypes) {\n queries.push(`${elementType} component`);\n }\n\n // Also add category-based queries for better matching\n if (elementTypes.includes(\"button\")) {\n queries.push(\"button Buttons category\");\n }\n if (elementTypes.some((e) => e.includes(\"input\") || e.includes(\"select\") || e.includes(\"textarea\"))) {\n queries.push(\"form Forms category\");\n }\n if (elementTypes.includes(\"alert\") || elementTypes.includes(\"badge\")) {\n queries.push(\"feedback Feedback category\");\n }\n\n return queries;\n }\n}\n\n/**\n * Strategy: Extract from metadata/structured data\n */\nclass MetadataExtractionStrategy implements ExtractionStrategy {\n name = \"metadata-extraction\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n // Look for custom component tags in the text (web components with hyphens)\n const componentPattern = /<([a-z]+-[\\w-]+)/gi;\n \n for (const item of context.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const matches = item.text.matchAll(componentPattern);\n for (const match of matches) {\n const componentName = match[2];\n queries.push(componentName.replace(/-/g, \" \")); // Convert kebab-case to words\n }\n }\n }\n\n return queries;\n }\n}\n\n","/**\n * Component Extractor\n * Extracts custom component tags from generated code\n * Supports Web Components, React, Vue, and other framework components\n */\n\nexport interface ExtractedComponent {\n tag: string;\n fullTag: string; // e.g., \"my-button\" or \"CustomBadge\"\n occurrences: number;\n}\n\n/**\n * Extracts component tags from code content\n * Detects:\n * - Web Components (hyphenated custom elements): <my-button>, <custom-badge>\n * - PascalCase components (React/Vue): <Button>, <CustomBadge>\n * - Imported components from any library\n */\nexport class ComponentExtractor {\n /**\n * Pattern to match custom components in various formats:\n * - Web Components (hyphenated): <my-button>, <custom-badge>\n * - PascalCase components: <Button>, <CustomBadge>\n * - Standalone references\n * - Import statements\n */\n private static readonly COMPONENT_PATTERNS = [\n // Web Component tags (hyphenated custom elements): <my-button>, <custom-badge>\n /<([a-z]+-[\\w-]+)/gi,\n // PascalCase component tags (React/Vue/etc): <Button>, <CustomBadge>\n /<([A-Z][a-zA-Z0-9]+)(?:\\s|>|\\/)/g,\n // Standalone hyphenated references: my-button, custom-badge\n /\\b([a-z]+-[\\w-]+)\\b/gi,\n ];\n\n /**\n * Extracts all unique component tags from code content\n * @param content - Code content as string or array of content items\n * @returns Array of unique component tags found\n */\n static extractComponents(\n content: string | Array<{ type: string; text?: string }>,\n ): ExtractedComponent[] {\n const componentMap = new Map<string, ExtractedComponent>();\n\n // Normalize content to string array\n const textContents: string[] = [];\n \n if (typeof content === \"string\") {\n textContents.push(content);\n } else if (Array.isArray(content)) {\n for (const item of content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n textContents.push(item.text);\n }\n }\n }\n\n // Extract components from each text content\n for (const text of textContents) {\n for (const pattern of this.COMPONENT_PATTERNS) {\n const matches = text.matchAll(pattern);\n \n for (const match of matches) {\n if (!match[1]) continue;\n \n let fullTag = match[1];\n \n // Normalize tag\n // For hyphenated tags (web components), keep lowercase\n // For PascalCase tags (React/Vue), keep as-is\n const normalizedTag = fullTag.includes('-') \n ? fullTag.toLowerCase().replace(/-+$/, \"\")\n : fullTag;\n\n // Filter out common HTML tags and non-component patterns\n if (this.isCommonHtmlTag(normalizedTag)) {\n continue;\n }\n\n if (componentMap.has(normalizedTag)) {\n componentMap.get(normalizedTag)!.occurrences++;\n } else {\n componentMap.set(normalizedTag, {\n tag: normalizedTag,\n fullTag: normalizedTag,\n occurrences: 1,\n });\n }\n }\n }\n }\n\n // Return sorted by occurrences (most frequent first)\n return Array.from(componentMap.values()).sort(\n (a, b) => b.occurrences - a.occurrences,\n );\n }\n\n /**\n * Check if a tag is a common HTML tag (not a custom component)\n */\n private static isCommonHtmlTag(tag: string): boolean {\n const commonTags = new Set([\n 'div', 'span', 'p', 'a', 'img', 'ul', 'li', 'ol', 'table', 'tr', 'td', 'th',\n 'form', 'input', 'button', 'select', 'option', 'textarea', 'label',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'footer', 'nav', 'main', 'section',\n 'article', 'aside', 'figure', 'figcaption', 'strong', 'em', 'code', 'pre',\n 'iframe', 'video', 'audio', 'canvas', 'svg', 'path', 'g', 'circle', 'rect',\n 'script', 'style', 'link', 'meta', 'title', 'head', 'body', 'html'\n ]);\n return commonTags.has(tag.toLowerCase());\n }\n\n /**\n * Extracts component tags and returns just the tag names\n * @param content - Code content\n * @returns Array of unique component tag names\n */\n static extractComponentTags(\n content: string | Array<{ type: string; text?: string }>,\n ): string[] {\n return this.extractComponents(content).map((c) => c.tag);\n }\n\n /**\n * Checks if content contains any custom components\n * @param content - Code content\n * @returns true if components are found\n */\n static hasComponents(\n content: string | Array<{ type: string; text?: string }>,\n ): boolean {\n const components = this.extractComponents(content);\n return components.length > 0;\n }\n}\n\n","/**\n * Component Lookup Service\n * Wrapper around PineconeSearchService for efficient component lookups\n */\n\nimport type { ComponentMatch } from \"../services/pinecone/pinecone-service.js\";\nimport { PineconeSearchService } from \"../services/pinecone/pinecone-service.js\";\n\nexport interface ComponentLookupResult {\n tag: string;\n found: boolean;\n component: ComponentMatch | null;\n error?: string;\n}\n\nexport interface ComponentLookupOptions {\n minScore?: number;\n cacheResults?: boolean;\n namespace?: string;\n}\n\n/**\n * Service for looking up multiple design system components in parallel\n */\nexport class ComponentLookupService {\n private pineconeService: PineconeSearchService;\n private lookupCache: Map<string, ComponentMatch | null> = new Map();\n private cacheEnabled: boolean;\n\n constructor(\n pineconeService?: PineconeSearchService,\n options: ComponentLookupOptions = {},\n ) {\n this.pineconeService = pineconeService || new PineconeSearchService({ namespace: options.namespace });\n this.cacheEnabled = options.cacheResults !== false; // Default: true\n }\n\n /**\n * Looks up a single component by tag\n * @param tag - Component tag/selector (e.g., 'my-button', 'Button')\n * @param options - Lookup options\n * @returns Component lookup result\n */\n async lookupComponent(\n tag: string,\n options: ComponentLookupOptions = {},\n ): Promise<ComponentLookupResult> {\n // Check cache first (namespace-aware cache key)\n const cacheKey = options.namespace ? `${tag}:${options.namespace}` : tag;\n if (this.cacheEnabled && this.lookupCache.has(cacheKey)) {\n const cached = this.lookupCache.get(cacheKey) ?? null;\n return {\n tag,\n found: cached !== null,\n component: cached,\n };\n }\n\n try {\n const component = await this.pineconeService.getComponentDetails(tag);\n \n // Ensure component is ComponentMatch | null (not undefined)\n const componentResult: ComponentMatch | null = component ?? null;\n \n // Cache the result (namespace-aware cache key)\n if (this.cacheEnabled) {\n this.lookupCache.set(cacheKey, componentResult);\n }\n\n return {\n tag,\n found: componentResult !== null,\n component: componentResult,\n };\n } catch (error) {\n return {\n tag,\n found: false,\n component: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Looks up multiple components in parallel\n * @param tags - Array of component tags\n * @param options - Lookup options\n * @returns Array of lookup results\n */\n async lookupMultipleComponents(\n tags: string[],\n options: ComponentLookupOptions = {},\n ): Promise<ComponentLookupResult[]> {\n if (!tags || tags.length === 0) {\n return [];\n }\n\n // Remove duplicates\n const uniqueTags = Array.from(new Set(tags));\n\n // Lookup all components in parallel\n const lookupPromises = uniqueTags.map((tag) =>\n this.lookupComponent(tag, options),\n );\n\n const results = await Promise.all(lookupPromises);\n\n // Sort by found status (found first) and then by tag name\n return results.sort((a, b) => {\n if (a.found !== b.found) {\n return a.found ? -1 : 1;\n }\n return a.tag.localeCompare(b.tag);\n });\n }\n\n /**\n * Gets a summary of found components\n * @param results - Lookup results\n * @returns Summary object\n */\n static getSummary(results: ComponentLookupResult[]): {\n total: number;\n found: number;\n notFound: number;\n foundComponents: ComponentMatch[];\n notFoundTags: string[];\n } {\n const found = results.filter((r) => r.found);\n const notFound = results.filter((r) => !r.found);\n\n return {\n total: results.length,\n found: found.length,\n notFound: notFound.length,\n foundComponents: found\n .map((r) => r.component)\n .filter((c): c is ComponentMatch => c !== null),\n notFoundTags: notFound.map((r) => r.tag),\n };\n }\n\n /**\n * Clears the lookup cache\n */\n clearCache(): void {\n this.lookupCache.clear();\n }\n\n /**\n * Gets cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.lookupCache.size,\n keys: Array.from(this.lookupCache.keys()),\n };\n }\n}\n\n"],"mappings":"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","names":["pineconeService","require","header","queryExtractor"]}
1
+ {"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/handlers/component-suggestion-handler.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/utils/design-query-extractor.ts","../src/figma2frida/utils/component-extractor.ts","../src/figma2frida/services/component-lookup.ts","../src/figma2frida/services/auth/token-validator.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 = \"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, FigmaDesignContextResult } from \"./clients/figma-client.js\";\nimport { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\nimport { ComponentExtractor } from \"./utils/component-extractor.js\";\nimport { ComponentLookupService } from \"./services/component-lookup.js\";\nimport type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.js\";\nimport { validateFridaApiToken } from \"./services/auth/token-validator.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 SERVER_VERSION = \"1.0.2\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${SERVER_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.5\";\nprocess.env.PINECONE_TOP_K = \"10\";\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\";\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// Simple in-memory cache for Figma design contexts\nconst designContextCache = new Map<\n string,\n {\n data: FigmaDesignContextResult;\n timestamp: number;\n forceCode: boolean;\n }\n>();\nconst CACHE_TTL_MS = 60000; // 1 minute cache\n\nconst server = new FastMCP({\n instructions: `You are a Figma design assistant optimized for fast code generation using your organization's design system components.\n\n**PRIMARY WORKFLOW (Most Common):**\n1. User asks for code from Figma design\n2. Call \\`figma_get_design_context\\` with:\n - \\`forceCode: true\\`\n - \\`transformToDesignSystem: true\\` (default)\n - \\`autoSearchComponents: true\\` (default)\n - \\`autoImproveLayout: false\\` (default - set to true if visual check is needed)\n3. This tool automatically:\n - Fetches design from Figma\n - Searches for matching design system components\n - Returns code with component documentation\n - Can include a visual screenshot & layout improvement hints (if requested)\n4. Use the transformed code and component docs provided to generate final code.\n\n**ALTERNATIVE WORKFLOWS:**\n\n**Option A: Component Discovery (before code generation)**\n- Call \\`figma_suggest_components\\` to explore available components.\n- Then use results to inform code generation.\n\n**Option B: Query-Only Component Search**\n- Call \\`figma_suggest_components\\` with the \\`query\\` parameter (omit \\`nodeId\\`).\n- **Figma is OPTIONAL** in this mode - it works even if Figma is closed.\n- Useful for browsing design system components without a design context.\n\n**Available tools:**\n- \\`figma_get_design_context\\`: Main tool for code generation (use this for primary workflow).\n- \\`figma_suggest_components\\`: Component discovery/exploration. Works without Figma if \\`query\\` is provided.\n- \\`figma_get_screenshot\\`: Quick visual reference (fast, ~0.5-1s).\n- \\`figma_improve_layout\\`: Layout refinement (call manually only if you need a fresh screenshot without regenerating code).\n\n**🚨 CRITICAL: Follow Figma Design Exactly**\nWhen generating code, you MUST:\n1. **USE THE TRANSFORMED CODE AS YOUR BASE** - It preserves the EXACT structure and layout from Figma.\n2. **USE ONLY DESIGN SYSTEM COMPONENTS** - Use only components found in search results or suggestions.\n3. **PRESERVE DESIGN STRUCTURE** - Maintain all container divs, spacing, and positioning.\n4. **SHOW ELEMENT ANALYSIS** - Display mapping of HTML elements to design system components.`,\n name: \"figma-proxy\",\n version: \"1.0.0\",\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// ============================================================================\n// TOOL 1: Get Screenshot (Fast Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"figma_get_screenshot\",\n description: `Get a screenshot of a Figma node for visual reference.\n\n**Fast & Simple:**\n- Takes ~0.5-1 second\n- Returns just the image, no code generation\n- Use this when you need to see what the design looks like\n\n**Usage:**\n- Provide a nodeId (e.g., \"315-2920\")\n- Or leave empty to use current Figma selection\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\"\n}\n\\`\\`\\``,\n annotations: {\n title: \"Get Screenshot\",\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(`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(args.nodeId);\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 return { content: screenshot.content as Content[] } 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// TOOL 2: Get Design Context (Direct Figma Proxy) - Main Tool\n// ============================================================================\n\nserver.addTool({\n name: \"figma_get_design_context\",\n description: `The ALL-IN-ONE tool for generating code from Figma Desktop.\n\n**Primary Workflow:**\n- Call this tool when the user wants to generate code from a Figma design.\n- It returns design data, generated code, component suggestions, and visual references in a single turn.\n\n**What this does:**\n- Calls Figma's get_design_context tool\n- Returns design data and optionally generated code (React, HTML, etc.)\n- **Discovery (Semantic)**: Automatically analyzes design to suggest components (Pinecone search)\n- **Validation (Exact)**: If code is generated, verifies that used components exist in the library\n- Automatically includes a screenshot for layout refinement (if requested)\n- Results are cached for 60 seconds for instant subsequent access\n- Streams progress updates for better responsiveness\n\n**Performance Modes:**\n- \\`forceCode: false\\` (default) - Fast metadata-only mode (~1-2s)\n- \\`forceCode: true\\` - Full code generation (~3-15s depending on complexity)\n\n**Component Search:**\n- When \\`forceCode: true\\` and \\`autoSearchComponents: true\\` (default), automatically:\n - Extracts component tags from generated code\n - Searches component information in Pinecone\n - Streams component details while processing\n - Adds summary section with found/not found components\n\n**Code Transformation:**\n- When \\`forceCode: true\\` and \\`transformToDesignSystem: true\\` (default), automatically:\n - **Analyzes** all HTML elements found in Figma design\n - **Shows mapping** of HTML elements → design system components before transformation\n - **Transforms** generic HTML elements (button, input, etc.) to design system components\n - **Preserves** ALL structure, layout, CSS classes, and styling from Figma design\n - **Maintains** all container divs, spacing, positioning, and visual hierarchy\n - **Uses component metadata** including framework type, import statements, and usage examples\n - Returns transformed code as the main output, with original code for reference\n - Shows detailed analysis and transformation summary\n\n**Output includes:**\n1. Element Analysis - What HTML elements were found in Figma\n2. Element Mapping - Which design system components will be used for each element\n3. Transformed Code - Ready-to-use code preserving Figma design structure\n4. Original Code - For reference and comparison\n\n**Usage:**\n- Provide a nodeId (e.g., \"315-2920\")\n- Or leave empty to use current Figma selection\n- Set forceCode to true only when you need the actual React/HTML code\n- Set autoSearchComponents to false to disable automatic component search\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\",\n \"forceCode\": true,\n \"autoSearchComponents\": true\n}\n\\`\\`\\`\n\n**Tip:** Start with \\`forceCode: false\\` to quickly see what's available, then request code if needed.`,\n annotations: {\n title: \"Get Design Context from Figma\",\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\" or \"315:2920\"). Leave empty for current selection.'),\n forceCode: z\n .boolean()\n .optional()\n .describe(\"Force code generation even for large outputs (default: false). Set to true only when you need the actual React/HTML code.\"),\n autoSearchComponents: z\n .boolean()\n .optional()\n .describe(\"Automatically search for design system components in the generated code (default: true). Only works when forceCode is true.\"),\n transformToDesignSystem: z\n .boolean()\n .optional()\n .describe(\"Transform Figma-generated code to use design system components (default: true). Only works when forceCode is true. Replaces generic HTML elements (button, input, etc.) with components from your design system library. Framework and language are determined by component metadata.\"),\n autoImproveLayout: z\n .boolean()\n .optional()\n .describe(\"Automatically include a screenshot and layout improvement reference (default: false). Set to true for visual verification.\"),\n }),\n execute: async (args, context) => {\n try {\n logger.debug(\"Tool called\");\n logger.debug(`nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`forceCode: ${args.forceCode ?? false}`);\n logger.debug(`autoImproveLayout: ${args.autoImproveLayout ?? false}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n \n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n };\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const nodeId = args.nodeId;\n const forceCode = args.forceCode ?? false;\n const autoSearchComponents = args.autoSearchComponents ?? true;\n const transformToDesignSystem = args.transformToDesignSystem ?? true;\n const autoImproveLayout = args.autoImproveLayout ?? false;\n\n logger.debug(`NodeId: ${nodeId || \"current selection\"}`);\n logger.debug(`ForceCode: ${forceCode}`);\n logger.debug(`AutoSearchComponents: ${autoSearchComponents}`);\n logger.debug(`TransformToDesignSystem: ${transformToDesignSystem}`);\n logger.debug(`autoImproveLayout: ${autoImproveLayout}`);\n\n // Create cache key - Include all parameters that affect output\n const cacheKey = `${nodeId || \"current\"}:${forceCode}:${autoSearchComponents}:${transformToDesignSystem}:${autoImproveLayout}`;\n const now = Date.now();\n const cached = designContextCache.get(cacheKey);\n\n // Check if we have a valid cached result\n if (cached && now - cached.timestamp < CACHE_TTL_MS) {\n logger.debug(`Using cached result (age: ${(now - cached.timestamp).toFixed(0)}ms)`);\n await context.streamContent({\n type: \"text\",\n text: `⚡ Using cached design context (${((now - cached.timestamp) / 1000).toFixed(1)}s old)`,\n });\n\n const header = {\n type: \"text\" as const,\n text: `✅ **Design Context from Figma** (Cached)\n\n**Node ID:** ${nodeId || \"current selection\"}\n**Content Items:** ${cached.data.content?.length || 0}\n**Cache Age:** ${((now - cached.timestamp) / 1000).toFixed(1)}s\n**Mode:** ${forceCode ? \"Full code generation\" : \"Metadata only (fast mode)\"}\n\n💾 **Cache hit!** This response was retrieved from cache for instant performance.\n\n---\n\n`,\n };\n\n return {\n content: [header, ...(cached.data.content || [])],\n } as ContentResult;\n }\n\n // Provide immediate feedback to user\n await context.streamContent({\n type: \"text\",\n text: `🔄 Fetching design from Figma${forceCode ? \" (including code generation)\" : \"\"}...`,\n });\n\n // Call Figma's get_design_context directly\n logger.debug(\"Calling Figma MCP get_design_context...\");\n const startTime = performance.now();\n const designResult = await figmaClient.getDesignContext(nodeId, {\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode,\n });\n const endTime = performance.now();\n\n // Cache the result\n designContextCache.set(cacheKey, {\n data: designResult,\n timestamp: now,\n forceCode,\n });\n logger.debug(`Cached result for key: ${cacheKey}`);\n\n logger.debug(`Response received in ${(endTime - startTime).toFixed(0)}ms`);\n logger.debug(`Content items: ${designResult.content?.length || 0}`);\n\n if (!designResult.content || designResult.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ No design context returned from Figma MCP.\n\n**Node ID:** ${nodeId || \"current selection\"}\n\n**Troubleshooting:**\n- Ensure the node exists and is accessible in Figma\n- Try selecting the node in Figma first\n- Check if the node has any visible design elements`,\n },\n ],\n };\n }\n\n // Log what we got\n designResult.content.forEach((item, idx) => {\n logger.debug(`Content[${idx}]:`, {\n type: item.type,\n hasText: item.type === \"text\" && \"text\" in item,\n textLength: item.type === \"text\" && \"text\" in item ? item.text?.length : 0,\n hasData: item.type === \"image\" && \"data\" in item,\n });\n });\n\n // Add a header with timing information\n const header = {\n type: \"text\" as const,\n text: `✅ **Design Context from Figma**\n\n**Node ID:** ${nodeId || \"current selection\"}\n**Content Items:** ${designResult.content.length}\n**Fetch Time:** ${(endTime - startTime).toFixed(0)}ms\n**Mode:** ${forceCode ? \"Full code generation\" : \"Metadata only (fast mode)\"}\n\n${forceCode ? \"\" : \"💡 **Tip:** If you need the actual React/HTML code, call this tool again with `forceCode: true`\\n\\n\"}**What you're seeing:** Raw output from Figma's get_design_context tool.\n\n---\n\n`,\n };\n\n logger.debug(\"Design context retrieved successfully\");\n\n // If transformToDesignSystem is enabled (even without forceCode), search for components\n // This supports Use Case 2: Code + Components (discovery mode)\n let transformedCodeSection: Content | null = null;\n let componentSuggestions: ComponentMatch[] = [];\n\n if (transformToDesignSystem && designResult.content) {\n try {\n if (autoSearchComponents) {\n await context.streamContent({\n type: \"text\",\n text: \"🔍 Discovering design system components from design analysis...\",\n });\n\n try {\n // Extract semantic query from design context\n const queryExtractor = new DesignQueryExtractor();\n const searchQuery = queryExtractor.extractQuery(designResult);\n logger.debug(`Extracted query: \"${searchQuery}\"`);\n\n await context.streamContent({\n type: \"text\",\n text: `🔎 Searching Pinecone for: \"${searchQuery}\"...`,\n });\n\n // Search Pinecone for matching components\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n const searchResults = await searchService.search(searchQuery, {\n // topK and minScore use service defaults (read from PINECONE_TOP_K and PINECONE_MIN_SCORE env vars)\n });\n\n componentSuggestions = searchResults.matches;\n const componentNames = componentSuggestions.map((comp) => comp.tag).join(\", \");\n logger.debug(\n `Found ${componentSuggestions.length} components from Pinecone: ${componentNames}`,\n );\n\n if (componentSuggestions.length > 0) {\n await context.streamContent({\n type: \"text\",\n text: `✅ Discovered ${componentSuggestions.length} design system components:\\n${componentSuggestions\n .map((c) => ` - ${c.tag} (${c.category})`)\n .join(\"\\n\")}`,\n });\n } else {\n await context.streamContent({\n type: \"text\",\n text: `⚠️ No components found in Pinecone. Using default mappings.`,\n });\n }\n } catch (error) {\n logger.warn(\n \"Could not get component suggestions:\",\n error,\n );\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error searching Pinecone: ${error instanceof Error ? error.message : String(error)}\\nFalling back to default mappings.`,\n });\n // Continue without suggestions, will use default mappings\n }\n }\n\n // Return component documentation to agent (regardless of forceCode)\n if (componentSuggestions.length > 0) {\n \n // Extract query for display\n const queryExtractor = new DesignQueryExtractor();\n const searchQuery = queryExtractor.extractQuery(designResult);\n\n // Read environment variables for Pinecone search parameters (validated at startup)\n const minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n const topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n const indexName = process.env.PINECONE_INDEX!;\n\n transformedCodeSection = {\n type: \"text\" as const,\n text: `## 🔍 **Available Design System Components from Pinecone**\n\n**Search Query:** \"${searchQuery}\"\n**Components Found:** ${componentSuggestions.length}\n\nUse the component documentation below to transform the Figma code into design system components. The agent will generate the code using these component specifications.\n\n---\n\n${Formatters.toMarkdown({\n query: searchQuery,\n matches: componentSuggestions,\n relevantMatches: componentSuggestions.length,\n totalMatches: componentSuggestions.length,\n searchMetadata: { minScore, topK, indexName },\n lowScoreMatches: []\n})}\n\n**💡 Instructions:** Use the component documentation above to transform the Figma code. Each component includes:\n- Exact prop names and types\n- Event names and types\n- Full documentation\n- Usage examples\n\nGenerate code that uses these components with the correct props and structure.\n\n---\n\n`,\n } as Content;\n } else if (autoSearchComponents) {\n // Only show \"not found\" if we actually searched\n await context.streamContent({\n type: \"text\",\n text: `⚠️ No components found in Pinecone for this design.`,\n });\n }\n } catch (error) {\n logger.error(\"Code transform error:\", error);\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error transforming code: ${error instanceof Error ? error.message : String(error)}\\n`,\n });\n }\n }\n\n // If forceCode is true and autoSearchComponents is enabled, search for components\n // This is for VALIDATION of generated code (requires code to be present)\n let componentSection: Content | null = null;\n if (forceCode && autoSearchComponents && designResult.content) {\n try {\n await context.streamContent({\n type: \"text\",\n text: \"🔍 Analyzing generated code for design system components...\",\n });\n\n // Extract components from the generated code\n const extractedComponents = ComponentExtractor.extractComponents(\n designResult.content,\n );\n\n if (extractedComponents.length > 0) {\n await context.streamContent({\n type: \"text\",\n text: `📦 Found ${extractedComponents.length} component reference(s): ${extractedComponents.map((c) => c.tag).join(\", \")}`,\n });\n\n // Lookup components in Pinecone\n const lookupService = new ComponentLookupService(undefined, { namespace: PINECONE_NAMESPACE });\n const componentTags = extractedComponents.map((c) => c.tag);\n\n await context.streamContent({\n type: \"text\",\n text: `🔎 Searching component information in Pinecone...`,\n });\n\n const lookupResults = await lookupService.lookupMultipleComponents(\n componentTags,\n );\n\n const summary = ComponentLookupService.getSummary(lookupResults);\n\n // Stream individual component information\n for (const result of lookupResults) {\n if (result.found && result.component) {\n const comp = result.component;\n await context.streamContent({\n type: \"text\",\n text: `✅ **${comp.tag}** - ${comp.category}\\n${comp.name || comp.tag}\\n${comp.documentation ? comp.documentation.substring(0, 200) + \"...\" : \"No documentation available\"}\\n`,\n });\n } else {\n await context.streamContent({\n type: \"text\",\n text: `⚠️ **${result.tag}** - Not found in component library\\n`,\n });\n }\n }\n\n // Create summary section\n let summaryText = `\\n## 📋 **Component Analysis Summary**\n\n**Total components found in code:** ${summary.total}\n**Found in library:** ${summary.found}\n**Not found:** ${summary.notFound}\n\n`;\n\n if (summary.foundComponents.length > 0) {\n summaryText += `### ✅ Components Found:\\n\\n`;\n summary.foundComponents.forEach((comp) => {\n summaryText += `- **${comp.tag}** (${comp.category}) - Score: ${comp.score.toFixed(4)}\\n`;\n if (comp.documentation) {\n summaryText += ` - ${comp.documentation.substring(0, 100)}${comp.documentation.length > 100 ? \"...\" : \"\"}\\n`;\n }\n });\n summaryText += `\\n`;\n }\n\n if (summary.notFoundTags.length > 0) {\n summaryText += `### ⚠️ Components Not Found:\\n\\n`;\n summary.notFoundTags.forEach((tag) => {\n summaryText += `- **${tag}** - This component may not be indexed in Pinecone or may not exist\\n`;\n });\n summaryText += `\\n`;\n }\n\n summaryText += `💡 **Tip:** Use \\`figma_suggest_components\\` tool to get detailed information and usage examples for these components.\\n\\n---\\n\\n`;\n\n componentSection = {\n type: \"text\" as const,\n text: summaryText,\n } as Content;\n } else {\n await context.streamContent({\n type: \"text\",\n text: `ℹ️ No design system components found in the generated code.\\n`,\n });\n }\n } catch (error) {\n logger.error(\"Component search error:\", error);\n await context.streamContent({\n type: \"text\",\n text: `⚠️ Error searching for components: ${error instanceof Error ? error.message : String(error)}\\n`,\n });\n }\n }\n\n // Return content with optional sections\n const finalContent: Content[] = [header];\n \n // Always include original Figma code\n finalContent.push(...(designResult.content as Content[]));\n \n // Add component documentation if available (for agent to use)\n if (transformedCodeSection) {\n finalContent.push(transformedCodeSection);\n }\n \n // Add component analysis section if available\n if (componentSection) {\n finalContent.push(componentSection);\n }\n\n // If autoImproveLayout is enabled (default: false), fetch and add screenshot\n // This supports Use Case 4: Refinement Loop (manual or auto)\n if (autoImproveLayout) {\n try {\n logger.debug(\"Fetching integrated screenshot for layout improvement...\");\n await context.streamContent({\n type: \"text\",\n text: \"📸 Fetching Figma screenshot for layout refinement...\",\n });\n const screenshot = await figmaClient.getScreenshot(nodeId);\n if (screenshot.content && screenshot.content.length > 0) {\n finalContent.push({\n type: \"text\" as const,\n text: `\\n## 📐 **Layout Improvement Reference**\\n\\nUse the screenshot below to verify your generated code matches the Figma design exactly.\\n\\n**Key Areas to Verify:**\\n- ✅ **Element spacing and margins**\\n- ✅ **Alignment and positioning**\\n- ✅ **Colors and typography**\\n- ✅ **Border radius and shadows**\\n\\n---\\n\\n`,\n });\n finalContent.push(...(screenshot.content as Content[]));\n }\n } catch (error) {\n logger.error(\"Screenshot fetch failed:\", error);\n finalContent.push({\n type: \"text\" as const,\n text: `\\n⚠️ **Note:** Automated screenshot for layout improvement failed: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n return {\n content: finalContent,\n } as ContentResult;\n } catch (error) {\n logger.error(\"Design context error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Get Design Context**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is the node ID valid?\n3. Is Figma MCP enabled? (Figma → Preferences → Enable MCP)\n4. Try restarting Figma Desktop\n\n${error instanceof Error && error.stack ? `\\n**Stack:**\\n${error.stack}` : \"\"}`,\n },\n ],\n };\n }\n },\n});\n\n// ============================================================================\n// TOOL 3: Suggest Components from Design System\n// ============================================================================\n\nserver.addTool({\n name: \"figma_suggest_components\",\n description: `Search and explore design system components.\n\n**Figma is OPTIONAL:**\n- If you provide a \\`query\\` and omit \\`nodeId\\`, the tool works even if Figma is closed.\n- If you omit \\`query\\`, it extracts the context from the current Figma selection.\n\n**WHEN TO USE:**\n- Use this tool for **DISCOVERY** and **EXPLORATION** of the component library.\n- Use this when you want to know \"What components are available for X?\" without generating full code.\n\n**⚠️ DO NOT USE FOR CODE GENERATION:**\n- If your goal is to generate code from a Figma design, use \\`figma_get_design_context\\` instead. It is faster and integrates component search automatically.`,\n annotations: {\n title: \"Suggest Design System Components\",\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\" or \"315:2920\"). Leave empty for current selection.'),\n minScore: z\n .number()\n .optional()\n .describe(\"Minimum Pinecone relevance score (default: 0.05). Higher values return more relevant results.\"),\n topK: z\n .number()\n .optional()\n .describe(\"Maximum number of components to retrieve (default: 10).\"),\n useFrida: z\n .boolean()\n .optional()\n .describe(\"Enable Frida AI processing for intelligent recommendations (default: true).\"),\n query: z\n .string()\n .optional()\n .describe(\"Custom search query. If provided, Figma connection is optional unless nodeId is also provided.\"),\n }),\n execute: async (args, context) => {\n logger.debug(\"Tool called\");\n logger.debug(`nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`query: ${args.query || 'none'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n \n const requiresFigma = !args.query || args.nodeId;\n if (!figmaConnected && requiresFigma) {\n logger.warn(\"Early return: figmaConnected is false and Figma is required\");\n return {\n content: [\n {\n type: \"text\" as const,\n text: args.query \n ? \"❌ Figma connection required when using nodeId. For query-only mode, omit nodeId.\" \n : \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n };\n }\n\n logger.debug(\"Proceeding with component suggestion...\");\n const nodeId = args.nodeId;\n const minScore = args.minScore ?? 0.05;\n const topK = args.topK ?? 10;\n const useFrida = args.useFrida ?? true;\n const customQuery = args.query;\n\n logger.debug(`NodeId: ${nodeId || \"current selection\"}`);\n logger.debug(`MinScore: ${minScore}`);\n logger.debug(`TopK: ${topK}`);\n logger.debug(`UseFrida: ${useFrida}`);\n\n // Get design context from Figma (only if needed)\n let designResult: FigmaDesignContextResult;\n \n if (customQuery && !nodeId) {\n // Query-only mode: skip Figma\n logger.debug(\"Query-only mode: skipping Figma fetch\");\n designResult = { content: [] };\n } else {\n // Normal mode: fetch from Figma\n await context.streamContent({\n type: \"text\",\n text: \"🎨 Fetching design context from Figma...\",\n });\n\n const designCacheKey = `${nodeId || \"current\"}:false`;\n const now = Date.now();\n const cachedDesign = designContextCache.get(designCacheKey);\n const designCacheAge = cachedDesign\n ? now - cachedDesign.timestamp\n : CACHE_TTL_MS + 1;\n\n if (cachedDesign && designCacheAge < CACHE_TTL_MS) {\n logger.debug(\"Using cached design context\");\n designResult = cachedDesign.data;\n } else {\n designResult = await figmaClient.getDesignContext(nodeId, {\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: false, // Use metadata mode for faster response\n });\n // Cache it\n designContextCache.set(designCacheKey, {\n data: designResult,\n timestamp: now,\n forceCode: false,\n });\n }\n }\n\n // Use the handler for component suggestion logic\n return handleComponentSuggestion({\n nodeId,\n minScore,\n topK,\n useFrida,\n query: customQuery,\n namespace: PINECONE_NAMESPACE,\n designContext: designResult,\n getDesignContext: figmaClient.getDesignContext.bind(figmaClient),\n streamContent: async (content: { type: \"text\"; text: string } | Array<{ type: \"text\"; text: string }>) => {\n if (Array.isArray(content)) {\n for (const item of content) {\n await context.streamContent(item);\n }\n } else {\n await context.streamContent(content);\n }\n },\n });\n },\n});\n\n// ============================================================================\n// TOOL 4: Improve Layout to Match Figma Frame Reference\n// ============================================================================\n\nserver.addTool({\n name: \"figma_improve_layout\",\n description: `Improve the generated layout to visually match the Figma frame reference.\n\n**WHEN TO USE:**\n- Use this tool when the user asks to fix spacing, alignment, or visual issues AFTER code generation.\n- It provides a fresh screenshot and specific layout improvement instructions.\n- This is a refinement tool, typically used in a loop to polish the UI.\n\n**What this does:**\n- Fetches the Figma screenshot (visual reference) for the specified node\n- Provides the screenshot as a visual reference for layout improvement\n- Use this tool after generating code from Figma to refine the layout\n- Compare your generated code output with the screenshot to adjust spacing, positioning, and styling\n\n**Usage:**\n- Call this tool after generating code from Figma\n- Provide a nodeId (e.g., \"315-2920\") or leave empty for current selection\n- The tool will fetch the screenshot and provide it as a visual reference\n\n**Example:**\n\\`\\`\\`json\n{\n \"nodeId\": \"315-2920\"\n}\n\\`\\`\\``,\n annotations: {\n title: \"Improve Layout to Match Figma\",\n readOnlyHint: false,\n openWorldHint: false,\n },\n parameters: z.object({\n nodeId: z\n .string()\n .optional()\n .describe('Figma node ID (e.g., \"315-2920\" or \"315:2920\"). Leave empty for current selection.'),\n }),\n execute: async (args, _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 return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n },\n ],\n } as ContentResult;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n if (!screenshot.content || screenshot.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"❌ No screenshot returned from Figma MCP.\",\n },\n ],\n } as ContentResult;\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `✅ **Visual Reference from Figma**\n\n**Node ID:** ${args.nodeId || \"current selection\"}\n\n**Instructions for Layout Improvement:**\n\nCompare the screenshot below with your generated code output. Adjust the following to match the Figma design exactly:\n\n**Key Areas to Verify:**\n- ✅ **Element spacing and margins** - Ensure spacing matches the design\n- ✅ **Alignment and positioning** - Check vertical and horizontal alignment\n- ✅ **Colors and typography** - Match colors, font sizes, and font weights\n- ✅ **Border radius and shadows** - Verify rounded corners and shadow effects\n- ✅ **Responsive behavior** - Ensure layout works at different screen sizes\n- ✅ **Component sizing** - Check width, height, and aspect ratios\n\n**Visual Reference:**\nThe screenshot below shows the exact Figma design you should match.\n\n---\n\n`,\n },\n ...screenshot.content,\n ],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Improve layout error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Get Screenshot for Layout Improvement**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is the node ID valid?\n3. Is Figma MCP enabled? (Figma → Preferences → Enable MCP)\n4. Try restarting Figma Desktop\n\n${error instanceof Error && error.stack ? `\\n**Stack:**\\n\\`\\`\\`\\n${error.stack}\\n\\`\\`\\`` : \"\"}`,\n },\n ],\n } as ContentResult;\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(`\nAvailable Tools:\n- figma_get_screenshot: Get visual screenshot (fast)\n- figma_get_design_context: Get design data and generated code (with caching & streaming)\n- figma_suggest_components: Suggest design system components based on Figma design (with Pinecone & Frida AI)\n- figma_improve_layout: Trigger layout improvement to match Figma frame reference\n\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 * Call Figma's get_design_context tool\n */\n async getDesignContext(\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n forceCode?: boolean;\n },\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n const args = {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\n forceCode: options?.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 logger.debug(`get_design_context response type: ${typeof result}`);\n logger.debug(`get_design_context response keys: ${Object.keys(result).join(\", \")}`);\n\n return result as FigmaDesignContextResult;\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: {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\n forceCode: options?.forceCode ?? true,\n },\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 nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n },\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 logger.debug(`get_metadata response type: ${typeof result}`);\n logger.debug(`get_metadata response keys: ${Object.keys(result).join(\", \")}`);\n\n return result as FigmaMetadataResult;\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 */\n async getScreenshot(\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n },\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n ...(nodeId ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 ? { nodeId } : {}),\n clientLanguages: options?.clientLanguages || \"typescript\",\n clientFrameworks: options?.clientFrameworks || \"react\",\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 * Component Suggestion Handler\n * Handles the logic for suggesting design system components based on Figma designs\n */\n\nimport \"dotenv/config\"; // Load .env file FIRST, before any service imports\nimport type { FigmaDesignContextResult } from \"../clients/figma-client.js\";\nimport { PineconeSearchService } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { DesignQueryExtractor } from \"../utils/design-query-extractor.js\";\nimport { logger } from \"../utils/logger.js\";\n\n// Cache for component suggestions\nconst componentSuggestionsCache = new Map<\n string,\n {\n data: Array<{ type: \"text\"; text: string }>;\n timestamp: number;\n }\n>();\nconst COMPONENT_CACHE_TTL_MS = 300000; // 5 minutes cache for component suggestions\n\n// Lazy initialization of services\nlet pineconeService: PineconeSearchService | null = null;\nlet pineconeServiceNamespace: string | undefined = undefined;\nlet fridaClient: FridaClient | null = null;\nlet queryExtractor: DesignQueryExtractor | null = null;\n\nfunction getPineconeService(namespace?: string): PineconeSearchService {\n // Recreate service if namespace changed\n if (!pineconeService || pineconeServiceNamespace !== namespace) {\n pineconeService = new PineconeSearchService({ namespace });\n pineconeServiceNamespace = namespace;\n }\n return pineconeService;\n}\n\nfunction getFridaClient(): FridaClient {\n if (!fridaClient) {\n fridaClient = new FridaClient();\n }\n return fridaClient;\n}\n\nfunction getQueryExtractor(): DesignQueryExtractor {\n if (!queryExtractor) {\n queryExtractor = new DesignQueryExtractor();\n }\n return queryExtractor;\n}\n\nexport interface ComponentSuggestionOptions {\n nodeId?: string;\n minScore?: number;\n topK?: number;\n useFrida?: boolean;\n query?: string;\n namespace?: string;\n designContext: FigmaDesignContextResult;\n getDesignContext: (\n nodeId?: string,\n options?: {\n clientLanguages?: string;\n clientFrameworks?: string;\n forceCode?: boolean;\n },\n ) => Promise<FigmaDesignContextResult>;\n streamContent?: (\n content: { type: \"text\"; text: string } | Array<{ type: \"text\"; text: string }>,\n ) => Promise<void>;\n}\n\nimport type { ContentResult } from \"fastmcp\";\n\nexport type ComponentSuggestionResult = ContentResult;\n\n/**\n * Handles component suggestion request\n */\nexport async function handleComponentSuggestion(\n options: ComponentSuggestionOptions,\n): Promise<ComponentSuggestionResult> {\n const {\n nodeId,\n minScore = 0.05,\n topK = 10,\n useFrida = true,\n query: customQuery,\n namespace,\n designContext,\n streamContent,\n } = options;\n\n try {\n // Create cache key\n const cacheKey = `${nodeId || \"current\"}:${minScore}:${topK}:${useFrida}:${customQuery || \"auto\"}`;\n const now = Date.now();\n const cached = componentSuggestionsCache.get(cacheKey);\n\n // Check cache\n if (cached && now - cached.timestamp < COMPONENT_CACHE_TTL_MS) {\n logger.debug(\n `Using cached result (age: ${((now - cached.timestamp) / 1000).toFixed(1)}s)`,\n );\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: `⚡ Using cached component suggestions (${((now - cached.timestamp) / 1000).toFixed(1)}s old)`,\n });\n }\n return { content: cached.data } as ComponentSuggestionResult;\n }\n\n if (!designContext.content || designContext.content.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ No design context returned from Figma MCP.\n\n**Node ID:** ${nodeId || \"current selection\"}\n\nCannot suggest components without design context.`,\n },\n ],\n };\n }\n\n // Extract query from design context\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: \"🔍 Extracting semantic query from design...\",\n });\n }\n\n const extractor = getQueryExtractor();\n const searchQuery = customQuery || extractor.extractQuery(designContext);\n\n logger.debug(`Extracted query: \"${searchQuery}\"`);\n\n // Search Pinecone\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: `🔎 Searching Pinecone for: \"${searchQuery}\"...`,\n });\n }\n\n logger.debug(\"Calling Pinecone search service...\");\n const searchService = getPineconeService(namespace);\n const searchStartTime = Date.now();\n const searchResults = await searchService.search(searchQuery, {\n minScore,\n topK,\n });\n const searchTime = Date.now() - searchStartTime;\n\n logger.debug(\n `Pinecone search completed in ${searchTime}ms - Found ${searchResults.relevantMatches} relevant components`,\n );\n\n if (searchResults.matches.length === 0) {\n const namespaceInfo = searchResults.searchMetadata.namespace\n ? `\\n**Namespace:** ${searchResults.searchMetadata.namespace}`\n : \"\";\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `⚠️ **No Components Found**\n\n**Query:** \"${searchQuery}\"\n**Min Score:** ${minScore}${namespaceInfo}\n**Index:** ${searchResults.searchMetadata.indexName}\n\nNo components from your design system matched the design context with sufficient relevance.\n\n**Possible Causes:**\n- The namespace \"${searchResults.searchMetadata.namespace || 'default'}\" may not exist or may be empty\n- Components may not be indexed in this namespace\n- The query may not match any components in this namespace\n\n**Suggestions:**\n- Verify that components are indexed in Pinecone${searchResults.searchMetadata.namespace ? ` namespace \"${searchResults.searchMetadata.namespace}\"` : \"\"}\n- Set namespace via \\`--project-id\\` CLI argument if not set\n- Try lowering the \\`minScore\\` parameter\n- Provide a more specific \\`query\\` parameter`,\n },\n ],\n };\n }\n\n // Extract component tags and detect patterns\n const componentTags = searchResults.matches.map(m => m.tag).join(\", \");\n const frameworkType = searchResults.matches[0]?.framework || \"html\";\n\n // Detect component prefix patterns dynamically (e.g., san-, comdig-, mat-, etc.)\n const prefixPatterns = Array.from(\n new Set(\n searchResults.matches\n .map(m => {\n const match = m.tag.match(/^([a-z]+-)/);\n return match ? match[1] : null;\n })\n .filter(Boolean)\n )\n ).join(\", \");\n\n // Format results\n const content: Array<{ type: \"text\"; text: string }> = [\n {\n type: \"text\" as const,\n text: `🚨 **MANDATORY: USE ONLY COMPONENTS FROM YOUR DESIGN SYSTEM**\n\n**CRITICAL INSTRUCTIONS:**\n- You MUST use ONLY the components listed below from your organization's design system\n- **DO NOT** use components from other libraries unless they appear in the search results\n- **DO NOT** use generic HTML elements directly - use the design system components instead\n${prefixPatterns ? `- Component prefixes in your system: ${prefixPatterns}` : \"\"}\n${frameworkType ? `- Framework type: ${frameworkType}` : \"\"}\n\n**Available Components for this design:**\n${componentTags || \"No components found\"}\n\n---\n\n✅ **Component Suggestions**\n\n**Query:** \"${searchQuery}\"\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n**Min Score:** ${minScore}\n\n---\n\n`,\n },\n ];\n\n // Add mandatory usage instructions\n content.push({\n type: \"text\" as const,\n text: `## 📋 MANDATORY USAGE INSTRUCTIONS\n\n**You MUST follow these rules when generating code:**\n\n1. **Use ONLY the components from the search results below**\n2. **DO NOT use:**\n - ❌ Components from other libraries not listed in the results\n - ❌ Generic HTML elements unless the component wraps them\n - ❌ Any component not found in your organization's design system\n\n3. **Use the recommended components:**\n - ✅ Use ONLY the components listed in the search results below\n - ✅ Follow the documentation provided for each component\n - ✅ Respect the component's framework and usage as documented\n - ✅ If a component is not in the list below, do NOT use it\n\n4. **Framework compatibility:** Check the \\`framework\\` field for each component\n\n---\n\n## Search Results (${searchResults.relevantMatches} components)\n\n${Formatters.toMarkdown(searchResults)}\n\n---\n\n`,\n });\n\n // Process with Frida AI if enabled\n if (useFrida) {\n const frida = getFridaClient();\n if (frida.isEnabled()) {\n if (streamContent) {\n await streamContent({\n type: \"text\",\n text: \"🤖 Processing with Frida AI for intelligent recommendations...\",\n });\n }\n\n const contextForFrida = Formatters.matchesToContext(\n searchResults.matches,\n );\n const question = `Based on this Figma design context, which component(s) from the design system should I use? Design description: ${searchQuery}`;\n\n logger.debug(`Calling Frida AI with ${searchResults.matches.length} component matches...`);\n const fridaStartTime = Date.now();\n const fridaResponse = await frida.ask(question, contextForFrida);\n const fridaTime = Date.now() - fridaStartTime;\n logger.debug(`Frida AI completed in ${fridaTime}ms - Success: ${fridaResponse.success}`);\n\n if (fridaResponse.success && fridaResponse.response) {\n content.push({\n type: \"text\" as const,\n text: `## 🤖 Frida AI Recommendation\n\n${fridaResponse.response}\n\n---\n\n`,\n });\n\n if (fridaResponse.metadata?.tokensUsed) {\n content.push({\n type: \"text\" as const,\n text: `*(Tokens used: ${fridaResponse.metadata.tokensUsed})*\n\n---\n\n`,\n });\n }\n } else {\n content.push({\n type: \"text\" as const,\n text: `⚠️ **Frida AI Processing Failed**\n\n${fridaResponse.error || \"Unknown error\"}\n\nFalling back to raw search results.\n\n---\n\n`,\n });\n }\n } else {\n content.push({\n type: \"text\" as const,\n text: `ℹ️ **Frida AI Not Configured**\n\nFrida AI is not enabled. Set \\`FRIDA_BEARER_TOKEN\\` and \\`FRIDA_API_URL\\` environment variables to enable intelligent recommendations.\n\nShowing raw search results instead.\n\n---\n\n`,\n });\n }\n }\n\n // Cache the result\n componentSuggestionsCache.set(cacheKey, {\n data: content,\n timestamp: now,\n });\n\n logger.debug(\"Completed successfully\");\n\n return { content };\n } catch (error) {\n logger.error(\"Failed to suggest components:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ **Failed to Suggest Components**\n\n**Error:** ${error instanceof Error ? error.message : String(error)}\n\n**Troubleshooting:**\n1. Is Figma Desktop running?\n2. Is Pinecone configured? (Check PINECONE_API_KEY)\n3. Are components indexed in Pinecone?\n4. Check the console for detailed error messages`,\n },\n ],\n };\n }\n}\n\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 documentation: string; // From metadata.documentation (markdown)\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 lowScoreMatches: Array<{ tag: string; score: number }>;\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: \"design_system@example.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, documentation\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 documentation: (metadata.documentation 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\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 lowScoreMatches: allMatches\n .filter((m) => (m.score || 0) < minScore)\n .map((match) => {\n const metadata = match.metadata || {};\n const tag = (metadata.tag as string) || \n (metadata.id as string) || \n match.id ||\n \"unknown\";\n return {\n tag,\n score: match.score || 0,\n };\n }),\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 * 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 || \"Innovation-gpt4o\";\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 optimized prompt for code generation\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert agent in code generation for UI design systems and component libraries.\nYour goal is to provide technical, precise, and ready-to-use answers that enable generating functional code immediately.\n\n**🚨 CRITICAL RULES - MANDATORY COMPLIANCE:**\n\n1. **You MUST use ONLY the components** from the AVAILABLE COMPONENT INFORMATION below\n2. **NEVER suggest or use:**\n - ❌ Components from other libraries not listed in the AVAILABLE COMPONENT INFORMATION\n - ❌ Generic HTML form elements: <button>, <input>, <select>, <textarea> (unless they are wrapped in design system components)\n - ❌ Any other component library or framework-specific components not in the AVAILABLE COMPONENT INFORMATION\n\n3. **Use components exactly as documented** - they may be Web Components, React components, Angular components, or any other framework\n4. **If a component is not in the AVAILABLE COMPONENT INFORMATION**, say so clearly - DO NOT invent or use generic alternatives\n\n**EXAMPLES OF WHAT NOT TO DO:**\n- ❌ WRONG: Using components from other libraries (mat-*, MUI, etc.) unless they appear in AVAILABLE COMPONENT INFORMATION\n- ❌ WRONG: Using any component that is NOT in the AVAILABLE COMPONENT INFORMATION below\n- ❌ WRONG: Inventing component names or props not in the documentation\n\n**EXAMPLES OF WHAT TO DO:**\n- ✅ Use ONLY components from the AVAILABLE COMPONENT INFORMATION below\n- ✅ Check the component tag/selector in the AVAILABLE COMPONENT INFORMATION before using it\n- ✅ Use the exact component names, props, and events as shown in the AVAILABLE COMPONENT INFORMATION\n- ✅ Follow the framework_type and import_statement provided for each component\n- ✅ If a component is not listed in AVAILABLE COMPONENT INFORMATION, do NOT use it - say clearly that it doesn't exist\n\n## AVAILABLE COMPONENT INFORMATION:\n\nThe component information below is provided in JSON format for accurate parsing.\nUse the exact prop names, types, and structure as shown in the JSON.\n\n${context}\n\n**IMPORTANT:** The component information above is in JSON format. Parse it carefully and use:\n- Exact prop names as shown in the props array\n- Exact prop types from type_signature field\n- Event names exactly as shown in the events array\n- Framework type from framework_type field\n- Import statements from import_statement field\n- Follow the structure and patterns from the JSON data\n\n## RESPONSE INSTRUCTIONS:\n\n### 1. MANDATORY STRUCTURE:\nYour response MUST follow this format:\n\n🚨 **RECOMMENDED COMPONENT:** [component name - MUST be from AVAILABLE COMPONENT INFORMATION]\n**CATEGORY:** [component category]\n**FRAMEWORK:** [framework_type from the component data]\n\n**DESCRIPTION:**\n[Brief explanation of the component and when to use it]\n\n**IMPORT:**\n\\`\\`\\`\n[import_statement from the component data if available]\n\\`\\`\\`\n\n**EXAMPLE CODE:**\n\\`\\`\\`html\n[Minimal functional and complete example]\n\\`\\`\\`\n\n**IMPORTANT PROPERTIES:**\n[List of key properties with types and possible values]\n- \\`property\\`: \\`type_signature\\` - [description]\n\n**EVENT HANDLING:**\n[If applicable, how to listen and handle events]\n\\`\\`\\`javascript\n[Example code to handle events]\n\\`\\`\\`\n\n**ADDITIONAL NOTES:**\n[Any important considerations, best practices, or limitations]\n\n### 2. CODE GENERATION RULES:\n\n1. **Use ONLY components from the AVAILABLE COMPONENT INFORMATION above** - Do NOT use components from other libraries\n2. **Do not invent properties or events** - Use only what exists in the component documentation provided\n3. **Exact types:** Include the exact types of properties from type_signature field\n4. **Functional code:** The example code MUST be copyable and functional\n5. **Required props:** If a prop is required, indicate it clearly\n6. **Default values:** If there are default values (default_value field), mention them\n7. **Events:** Include examples of how to listen to events if the component emits them\n8. **Framework compatibility:** Use the framework_type and import_statement from the component data\n9. **Necessary imports:** Include the import_statement from the component data\n10. **If a component doesn't exist:** Say clearly \"No component available for [feature]. Available components are: [list]\"\n\n### 3. QUESTION ANALYSIS:\n\n- If asking about a specific component: Provide complete technical documentation\n- If asking \"how to do X\": Suggest the most suitable component AND provide functional code\n- If asking about properties: List ALL relevant properties with exact types\n- If asking about events: Provide complete examples of event handling\n\n### 4. TECHNICAL ACCURACY:\n\n- Use the exact names of properties as they appear in the documentation\n- Respect exact types (union types, enums, etc.)\n- Include all attributes necessary for the code to work\n- Mention if there are slots available and how to use them\n\n### 5. IF NO INFORMATION:\n\nIf the context does not contain enough information to answer, say clearly:\n\"I don't have enough information about [aspect] in the provided context. Available components are: [list]\"\n\n## USER QUESTION:\n${question}\n\n## RESPONSE (Follow the mandatory structure above):`.trim();\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","/**\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 documentation: string;\n }>;\n lowScoreComponents: Array<{ tag: string; score: number }>;\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 documentation: match.documentation,\n })),\n lowScoreComponents: searchResults.lowScoreMatches || [],\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 let markdown = `## Search Results\n\n**Query:** \"${searchResults.query}\"\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n**Minimum score:** ${searchResults.searchMetadata.minScore}\n\n---\n\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag} (Score: ${match.score.toFixed(4)})\n\n**Name:** ${match.name || match.tag}\n**Category:** ${match.category}\n**Framework:** ${match.framework}\n\n**Documentation:**\n${match.documentation || \"No documentation available\"}\n\n---\n\n`;\n });\n\n if (\n searchResults.lowScoreMatches &&\n searchResults.lowScoreMatches.length > 0\n ) {\n markdown += `\\n### Components with low relevance (score < ${searchResults.searchMetadata.minScore})\\n\\n`;\n searchResults.lowScoreMatches.forEach((match, idx) => {\n markdown += `${idx + 1}. ${match.tag} (Score: ${match.score.toFixed(4)})\\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 id: match.id,\n tag: match.tag,\n name: match.name,\n framework: match.framework,\n category: match.category,\n documentation: match.documentation,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n}\n\n","/**\n * Design Query Extractor\n * Extracts semantic queries from Figma design context for component search\n */\n\nimport type { FigmaDesignContextResult } from \"../clients/figma-client.js\";\n\nexport interface ExtractionStrategy {\n name: string;\n extract(context: FigmaDesignContextResult): string[];\n}\n\n/**\n * Extracts semantic query from Figma design context\n */\nexport class DesignQueryExtractor {\n private strategies: ExtractionStrategy[];\n\n constructor() {\n this.strategies = [\n new TextExtractionStrategy(),\n new PatternMatchingStrategy(),\n new MetadataExtractionStrategy(),\n ];\n }\n\n /**\n * Extracts query from design context using all available strategies\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n const queries: string[] = [];\n\n // Try each strategy\n for (const strategy of this.strategies) {\n try {\n const extracted = strategy.extract(designContext);\n queries.push(...extracted);\n } catch (error) {\n console.warn(\n `[QUERY EXTRACTOR] Strategy ${strategy.name} failed:`,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n // Remove duplicates and empty strings\n const uniqueQueries = Array.from(\n new Set(queries.filter((q) => q && q.trim().length > 0)),\n );\n\n // If we have queries, combine them intelligently\n if (uniqueQueries.length > 0) {\n // Take the first few most relevant queries\n const topQueries = uniqueQueries.slice(0, 3);\n // Combine for better semantic search in component library\n return `${topQueries.join(\" \")} component`.trim();\n }\n\n return fallbackQuery;\n }\n}\n\n/**\n * Strategy: Extract meaningful text from design context\n */\nclass TextExtractionStrategy implements ExtractionStrategy {\n name = \"text-extraction\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n for (const item of context.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text.trim();\n if (text.length > 0) {\n // Extract component-like keywords\n const componentKeywords = this.extractComponentKeywords(text);\n queries.push(...componentKeywords);\n\n // Extract descriptive phrases\n const descriptivePhrases = this.extractDescriptivePhrases(text);\n queries.push(...descriptivePhrases);\n }\n }\n }\n\n return queries;\n }\n\n private extractComponentKeywords(text: string): string[] {\n const keywords: string[] = [];\n\n // Common UI component patterns\n const patterns = [\n { pattern: /button|btn/gi, keyword: \"button\" },\n { pattern: /input|textfield|text field/gi, keyword: \"input\" },\n { pattern: /card|panel/gi, keyword: \"card\" },\n { pattern: /badge|label|tag/gi, keyword: \"badge\" },\n { pattern: /alert|message|notification/gi, keyword: \"alert\" },\n { pattern: /modal|dialog|popup/gi, keyword: \"modal\" },\n { pattern: /dropdown|select|picker/gi, keyword: \"dropdown\" },\n { pattern: /checkbox|check box/gi, keyword: \"checkbox\" },\n { pattern: /radio|radio button/gi, keyword: \"radio\" },\n { pattern: /slider|range/gi, keyword: \"slider\" },\n { pattern: /table|grid|list/gi, keyword: \"table\" },\n { pattern: /breadcrumb|breadcrumb navigation/gi, keyword: \"breadcrumb\" },\n { pattern: /tooltip|tip/gi, keyword: \"tooltip\" },\n { pattern: /accordion|collapsible/gi, keyword: \"accordion\" },\n { pattern: /progress|loader|spinner/gi, keyword: \"progress\" },\n ];\n\n for (const { pattern, keyword } of patterns) {\n if (pattern.test(text)) {\n keywords.push(keyword);\n }\n }\n\n return keywords;\n }\n\n private extractDescriptivePhrases(text: string): string[] {\n const phrases: string[] = [];\n\n // Extract sentences or phrases that describe UI elements\n // Look for patterns like \"a button that...\", \"an input for...\", etc.\n const descriptionPatterns = [\n /(?:a |an |the )?([a-z]+(?: [a-z]+){0,3}) (?:that |for |to |with |in |on )/gi,\n /(?:create |make |add |use |show |display )([a-z]+(?: [a-z]+){0,3})/gi,\n ];\n\n for (const pattern of descriptionPatterns) {\n const matches = text.matchAll(pattern);\n for (const match of matches) {\n if (match[1] && match[1].length > 2) {\n phrases.push(match[1].trim());\n }\n }\n }\n\n return phrases.slice(0, 5); // Limit to top 5 phrases\n }\n}\n\n/**\n * Strategy: Pattern matching for common UI patterns\n */\nclass PatternMatchingStrategy implements ExtractionStrategy {\n name = \"pattern-matching\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n const combinedText = context.content\n .filter((item) => item.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text as string)\n .join(\" \");\n\n if (combinedText.length === 0) {\n return queries;\n }\n\n // Detect HTML elements and extract element types\n const elementTypes: string[] = [];\n\n // Button patterns\n if (/<(?:button|Button)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"button\");\n }\n\n // Input patterns (various types)\n if (/<(?:input|Input)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"input\");\n // Check for specific input types\n if (/type=[\"'](?:text|email|password|number)/gi.test(combinedText)) {\n elementTypes.push(\"text input\");\n }\n if (/type=[\"']checkbox/gi.test(combinedText)) {\n elementTypes.push(\"checkbox\");\n }\n if (/type=[\"']radio/gi.test(combinedText)) {\n elementTypes.push(\"radio\");\n }\n if (/type=[\"']range/gi.test(combinedText)) {\n elementTypes.push(\"slider\");\n }\n }\n\n // Textarea\n if (/<(?:textarea|Textarea)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"textarea\");\n }\n\n // Select/Dropdown\n if (/<(?:select|Select)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"dropdown\");\n elementTypes.push(\"select\");\n }\n\n // Card patterns\n if (/<(?:div|Div)[^>]*class[^>]*(?:card|Card|panel|Panel)/gi.test(combinedText)) {\n elementTypes.push(\"card\");\n }\n\n // Badge/Label patterns\n if (/<(?:span|Span)[^>]*class[^>]*(?:badge|Badge|label|Label|tag|Tag)/gi.test(combinedText)) {\n elementTypes.push(\"badge\");\n }\n\n // Alert/Message patterns\n if (/<(?:div|Div)[^>]*class[^>]*(?:alert|Alert|message|Message|notification|Notification)/gi.test(combinedText)) {\n elementTypes.push(\"alert\");\n }\n\n // Form patterns\n if (/<(?:form|Form)[^>]*>/gi.test(combinedText)) {\n elementTypes.push(\"form\");\n }\n\n // Navigation patterns\n if (/<(?:nav|Nav|ul|Ul)[^>]*class[^>]*(?:nav|Nav|menu|Menu|breadcrumb|Breadcrumb)/gi.test(combinedText)) {\n elementTypes.push(\"navigation\");\n }\n\n // Link patterns\n if (/<(?:a|A)[^>]*href/gi.test(combinedText)) {\n elementTypes.push(\"link\");\n elementTypes.push(\"action link\");\n }\n\n // Convert element types to queries\n for (const elementType of elementTypes) {\n queries.push(`${elementType} component`);\n }\n\n // Also add category-based queries for better matching\n if (elementTypes.includes(\"button\")) {\n queries.push(\"button Buttons category\");\n }\n if (elementTypes.some((e) => e.includes(\"input\") || e.includes(\"select\") || e.includes(\"textarea\"))) {\n queries.push(\"form Forms category\");\n }\n if (elementTypes.includes(\"alert\") || elementTypes.includes(\"badge\")) {\n queries.push(\"feedback Feedback category\");\n }\n\n return queries;\n }\n}\n\n/**\n * Strategy: Extract from metadata/structured data\n */\nclass MetadataExtractionStrategy implements ExtractionStrategy {\n name = \"metadata-extraction\";\n\n extract(context: FigmaDesignContextResult): string[] {\n const queries: string[] = [];\n\n if (!context.content) {\n return queries;\n }\n\n // Look for custom component tags in the text (web components with hyphens)\n const componentPattern = /<([a-z]+-[\\w-]+)/gi;\n \n for (const item of context.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const matches = item.text.matchAll(componentPattern);\n for (const match of matches) {\n const componentName = match[2];\n queries.push(componentName.replace(/-/g, \" \")); // Convert kebab-case to words\n }\n }\n }\n\n return queries;\n }\n}\n\n","/**\n * Component Extractor\n * Extracts custom component tags from generated code\n * Supports Web Components, React, Vue, and other framework components\n */\n\nexport interface ExtractedComponent {\n tag: string;\n fullTag: string; // e.g., \"my-button\" or \"CustomBadge\"\n occurrences: number;\n}\n\n/**\n * Extracts component tags from code content\n * Detects:\n * - Web Components (hyphenated custom elements): <my-button>, <custom-badge>\n * - PascalCase components (React/Vue): <Button>, <CustomBadge>\n * - Imported components from any library\n */\nexport class ComponentExtractor {\n /**\n * Pattern to match custom components in various formats:\n * - Web Components (hyphenated): <my-button>, <custom-badge>\n * - PascalCase components: <Button>, <CustomBadge>\n * - Standalone references\n * - Import statements\n */\n private static readonly COMPONENT_PATTERNS = [\n // Web Component tags (hyphenated custom elements): <my-button>, <custom-badge>\n /<([a-z]+-[\\w-]+)/gi,\n // PascalCase component tags (React/Vue/etc): <Button>, <CustomBadge>\n /<([A-Z][a-zA-Z0-9]+)(?:\\s|>|\\/)/g,\n // Standalone hyphenated references: my-button, custom-badge\n /\\b([a-z]+-[\\w-]+)\\b/gi,\n ];\n\n /**\n * Extracts all unique component tags from code content\n * @param content - Code content as string or array of content items\n * @returns Array of unique component tags found\n */\n static extractComponents(\n content: string | Array<{ type: string; text?: string }>,\n ): ExtractedComponent[] {\n const componentMap = new Map<string, ExtractedComponent>();\n\n // Normalize content to string array\n const textContents: string[] = [];\n \n if (typeof content === \"string\") {\n textContents.push(content);\n } else if (Array.isArray(content)) {\n for (const item of content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n textContents.push(item.text);\n }\n }\n }\n\n // Extract components from each text content\n for (const text of textContents) {\n for (const pattern of this.COMPONENT_PATTERNS) {\n const matches = text.matchAll(pattern);\n \n for (const match of matches) {\n if (!match[1]) continue;\n \n let fullTag = match[1];\n \n // Normalize tag\n // For hyphenated tags (web components), keep lowercase\n // For PascalCase tags (React/Vue), keep as-is\n const normalizedTag = fullTag.includes('-') \n ? fullTag.toLowerCase().replace(/-+$/, \"\")\n : fullTag;\n\n // Filter out common HTML tags and non-component patterns\n if (this.isCommonHtmlTag(normalizedTag)) {\n continue;\n }\n\n if (componentMap.has(normalizedTag)) {\n componentMap.get(normalizedTag)!.occurrences++;\n } else {\n componentMap.set(normalizedTag, {\n tag: normalizedTag,\n fullTag: normalizedTag,\n occurrences: 1,\n });\n }\n }\n }\n }\n\n // Return sorted by occurrences (most frequent first)\n return Array.from(componentMap.values()).sort(\n (a, b) => b.occurrences - a.occurrences,\n );\n }\n\n /**\n * Check if a tag is a common HTML tag (not a custom component)\n */\n private static isCommonHtmlTag(tag: string): boolean {\n const commonTags = new Set([\n 'div', 'span', 'p', 'a', 'img', 'ul', 'li', 'ol', 'table', 'tr', 'td', 'th',\n 'form', 'input', 'button', 'select', 'option', 'textarea', 'label',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'footer', 'nav', 'main', 'section',\n 'article', 'aside', 'figure', 'figcaption', 'strong', 'em', 'code', 'pre',\n 'iframe', 'video', 'audio', 'canvas', 'svg', 'path', 'g', 'circle', 'rect',\n 'script', 'style', 'link', 'meta', 'title', 'head', 'body', 'html'\n ]);\n return commonTags.has(tag.toLowerCase());\n }\n\n /**\n * Extracts component tags and returns just the tag names\n * @param content - Code content\n * @returns Array of unique component tag names\n */\n static extractComponentTags(\n content: string | Array<{ type: string; text?: string }>,\n ): string[] {\n return this.extractComponents(content).map((c) => c.tag);\n }\n\n /**\n * Checks if content contains any custom components\n * @param content - Code content\n * @returns true if components are found\n */\n static hasComponents(\n content: string | Array<{ type: string; text?: string }>,\n ): boolean {\n const components = this.extractComponents(content);\n return components.length > 0;\n }\n}\n\n","/**\n * Component Lookup Service\n * Wrapper around PineconeSearchService for efficient component lookups\n */\n\nimport type { ComponentMatch } from \"../services/pinecone/pinecone-service.js\";\nimport { PineconeSearchService } from \"../services/pinecone/pinecone-service.js\";\n\nexport interface ComponentLookupResult {\n tag: string;\n found: boolean;\n component: ComponentMatch | null;\n error?: string;\n}\n\nexport interface ComponentLookupOptions {\n minScore?: number;\n cacheResults?: boolean;\n namespace?: string;\n}\n\n/**\n * Service for looking up multiple design system components in parallel\n */\nexport class ComponentLookupService {\n private pineconeService: PineconeSearchService;\n private lookupCache: Map<string, ComponentMatch | null> = new Map();\n private cacheEnabled: boolean;\n\n constructor(\n pineconeService?: PineconeSearchService,\n options: ComponentLookupOptions = {},\n ) {\n this.pineconeService = pineconeService || new PineconeSearchService({ namespace: options.namespace });\n this.cacheEnabled = options.cacheResults !== false; // Default: true\n }\n\n /**\n * Looks up a single component by tag\n * @param tag - Component tag/selector (e.g., 'my-button', 'Button')\n * @param options - Lookup options\n * @returns Component lookup result\n */\n async lookupComponent(\n tag: string,\n options: ComponentLookupOptions = {},\n ): Promise<ComponentLookupResult> {\n // Check cache first (namespace-aware cache key)\n const cacheKey = options.namespace ? `${tag}:${options.namespace}` : tag;\n if (this.cacheEnabled && this.lookupCache.has(cacheKey)) {\n const cached = this.lookupCache.get(cacheKey) ?? null;\n return {\n tag,\n found: cached !== null,\n component: cached,\n };\n }\n\n try {\n const component = await this.pineconeService.getComponentDetails(tag);\n \n // Ensure component is ComponentMatch | null (not undefined)\n const componentResult: ComponentMatch | null = component ?? null;\n \n // Cache the result (namespace-aware cache key)\n if (this.cacheEnabled) {\n this.lookupCache.set(cacheKey, componentResult);\n }\n\n return {\n tag,\n found: componentResult !== null,\n component: componentResult,\n };\n } catch (error) {\n return {\n tag,\n found: false,\n component: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Looks up multiple components in parallel\n * @param tags - Array of component tags\n * @param options - Lookup options\n * @returns Array of lookup results\n */\n async lookupMultipleComponents(\n tags: string[],\n options: ComponentLookupOptions = {},\n ): Promise<ComponentLookupResult[]> {\n if (!tags || tags.length === 0) {\n return [];\n }\n\n // Remove duplicates\n const uniqueTags = Array.from(new Set(tags));\n\n // Lookup all components in parallel\n const lookupPromises = uniqueTags.map((tag) =>\n this.lookupComponent(tag, options),\n );\n\n const results = await Promise.all(lookupPromises);\n\n // Sort by found status (found first) and then by tag name\n return results.sort((a, b) => {\n if (a.found !== b.found) {\n return a.found ? -1 : 1;\n }\n return a.tag.localeCompare(b.tag);\n });\n }\n\n /**\n * Gets a summary of found components\n * @param results - Lookup results\n * @returns Summary object\n */\n static getSummary(results: ComponentLookupResult[]): {\n total: number;\n found: number;\n notFound: number;\n foundComponents: ComponentMatch[];\n notFoundTags: string[];\n } {\n const found = results.filter((r) => r.found);\n const notFound = results.filter((r) => !r.found);\n\n return {\n total: results.length,\n found: found.length,\n notFound: notFound.length,\n foundComponents: found\n .map((r) => r.component)\n .filter((c): c is ComponentMatch => c !== null),\n notFoundTags: notFound.map((r) => r.tag),\n };\n }\n\n /**\n * Clears the lookup cache\n */\n clearCache(): void {\n this.lookupCache.clear();\n }\n\n /**\n * Gets cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.lookupCache.size,\n keys: Array.from(this.lookupCache.keys()),\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"],"mappings":"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","names":["pineconeService","require","header","queryExtractor"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fridaplatform-stk/figma2frida-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "main": "dist/figma2frida.js",
5
5
  "scripts": {
6
6
  "build": "tsup",