@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 +94 -172
- package/dist/figma2frida.js +64 -0
- package/dist/figma2frida.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,121 +1,76 @@
|
|
|
1
1
|
# Figma2Frida MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> AI-powered bridge between Figma designs and your organization's design system components
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 🎯 What Is Figma2Frida?
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
+
Your AI assistant gets four specialized tools:
|
|
19
18
|
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
-
|
|
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
|
-
##
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
42
|
+
## 📦 Installation
|
|
49
43
|
|
|
50
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
+
### Step 2: Configure Your AI Assistant
|
|
96
51
|
|
|
97
|
-
|
|
52
|
+
Add to your configuration file:
|
|
98
53
|
|
|
99
|
-
|
|
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": "
|
|
60
|
+
"command": "npx",
|
|
106
61
|
"args": [
|
|
107
|
-
"/
|
|
108
|
-
"--
|
|
109
|
-
"
|
|
62
|
+
"@fridaplatform-stk/figma2frida-mcp",
|
|
63
|
+
"--project-id",
|
|
64
|
+
"YOUR_PROJECT_ID",
|
|
110
65
|
"--frida-api-token",
|
|
111
|
-
"
|
|
66
|
+
"YOUR_API_TOKEN"
|
|
112
67
|
]
|
|
113
68
|
}
|
|
114
69
|
}
|
|
115
70
|
}
|
|
116
71
|
```
|
|
117
72
|
|
|
118
|
-
**
|
|
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
|
-
"--
|
|
128
|
-
"
|
|
82
|
+
"--project-id",
|
|
83
|
+
"YOUR_PROJECT_ID",
|
|
129
84
|
"--frida-api-token",
|
|
130
|
-
"
|
|
85
|
+
"YOUR_API_TOKEN"
|
|
131
86
|
]
|
|
132
87
|
}
|
|
133
88
|
}
|
|
134
89
|
}
|
|
135
90
|
```
|
|
136
91
|
|
|
137
|
-
|
|
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
|
-
|
|
94
|
+
Restart Claude Desktop, Cursor, or your IDE to load the MCP server.
|
|
157
95
|
|
|
158
|
-
|
|
96
|
+
## 🔑 Getting Access Tokens
|
|
159
97
|
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
###
|
|
102
|
+
### How to Get Tokens
|
|
165
103
|
|
|
166
|
-
|
|
167
|
-
npm run dev
|
|
168
|
-
```
|
|
104
|
+
**Contact the Softtek Frida Team:**
|
|
169
105
|
|
|
170
|
-
|
|
106
|
+
📧 Reach out to your organization's Frida team or Softtek Frida support to request access.
|
|
171
107
|
|
|
172
|
-
|
|
108
|
+
You'll need to provide:
|
|
109
|
+
- Your organization name
|
|
110
|
+
- Intended use case
|
|
111
|
+
- Team/project information
|
|
173
112
|
|
|
174
|
-
|
|
113
|
+
The Frida team will provide your credentials securely.
|
|
175
114
|
|
|
176
|
-
|
|
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
|
-
|
|
117
|
+
For the best experience, also install the **[Frida Code Copilot VS Code Extension](https://marketplace.visualstudio.com/)**:
|
|
181
118
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
187
|
-
npm whoami
|
|
124
|
+
## 📋 Prerequisites
|
|
188
125
|
|
|
189
|
-
|
|
190
|
-
|
|
126
|
+
- **Node.js 18+**
|
|
127
|
+
- **Figma Desktop** with MCP enabled
|
|
128
|
+
- **Frida API Token** (contact Softtek Frida team)
|
|
191
129
|
|
|
192
|
-
|
|
193
|
-
npm run build
|
|
130
|
+
## 🚀 Example Usage
|
|
194
131
|
|
|
195
|
-
|
|
196
|
-
npm pack --dry-run
|
|
132
|
+
Once configured, simply ask your AI assistant:
|
|
197
133
|
|
|
198
|
-
|
|
199
|
-
|
|
134
|
+
```
|
|
135
|
+
"Generate React code for this Figma button component"
|
|
200
136
|
```
|
|
201
137
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
219
|
-
|
|
142
|
+
```
|
|
143
|
+
"Update this code to match the Figma spacing exactly"
|
|
220
144
|
```
|
|
221
145
|
|
|
222
|
-
|
|
146
|
+
The AI will automatically use the Figma2Frida tools to help you.
|
|
223
147
|
|
|
224
|
-
|
|
148
|
+
## 🐛 Troubleshooting
|
|
225
149
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
156
|
+
**"Missing required argument"**
|
|
157
|
+
→ Check both `--project-id` and `--frida-api-token` are in your config
|
|
232
158
|
|
|
233
|
-
|
|
234
|
-
|
|
159
|
+
**"Rate limit exceeded"**
|
|
160
|
+
→ Wait a few minutes before trying again
|
|
235
161
|
|
|
236
|
-
|
|
237
|
-
Make sure Figma Desktop is running with MCP enabled at `http://127.0.0.1:3845/sse`.
|
|
162
|
+
## 🤝 Support
|
|
238
163
|
|
|
239
|
-
|
|
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
|
-
|
|
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
|
-
|
|
168
|
+
MIT License
|
|
248
169
|
|
|
249
|
-
|
|
170
|
+
## 👥 Author
|
|
250
171
|
|
|
251
|
-
|
|
172
|
+
**Frida Platform STK** - Softtek
|
|
252
173
|
|
|
253
|
-
|
|
174
|
+
---
|
|
254
175
|
|
|
176
|
+
Made with ❤️ by the Frida team
|
package/dist/figma2frida.js
CHANGED
|
@@ -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();
|
package/dist/figma2frida.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/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"]}
|