viewgate-mcp 1.0.16 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +38 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -431,35 +431,54 @@ Instruction: ${ann.message}`
|
|
|
431
431
|
};
|
|
432
432
|
}
|
|
433
433
|
// 2. Parse Figma URL
|
|
434
|
-
|
|
435
|
-
|
|
434
|
+
let fileKey = "";
|
|
435
|
+
try {
|
|
436
|
+
if (url.includes("/file/") || url.includes("/design/")) {
|
|
437
|
+
const parts = url.split(/\/(?:file|design)\//)[1].split("/");
|
|
438
|
+
fileKey = parts[0].split(/[?#]/)[0];
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
throw new Error("Could not parse Figma File Key from URL.");
|
|
443
|
+
}
|
|
444
|
+
if (!fileKey) {
|
|
436
445
|
throw new Error("Invalid Figma URL format. File key not found.");
|
|
437
446
|
}
|
|
438
|
-
const fileKey = fileKeyMatch[1];
|
|
439
447
|
// Extract node-id if present
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
nodeId =
|
|
448
|
+
let nodeId = "";
|
|
449
|
+
try {
|
|
450
|
+
const urlObj = new URL(url.replace(/#/g, "?")); // Handle hash-based node-id
|
|
451
|
+
nodeId = urlObj.searchParams.get("node-id") || urlObj.searchParams.get("m") || "";
|
|
452
|
+
if (!nodeId && url.includes("node-id=")) {
|
|
453
|
+
nodeId = url.split("node-id=")[1].split("&")[0];
|
|
454
|
+
}
|
|
455
|
+
// Normalización y limpieza
|
|
456
|
+
if (nodeId) {
|
|
457
|
+
nodeId = decodeURIComponent(nodeId).replace(/-/g, ":");
|
|
458
|
+
}
|
|
444
459
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
nodeId = nodeId.replace(/%3A/g, ':').replace(/-/g, ':');
|
|
460
|
+
catch (e) {
|
|
461
|
+
// Silent fail for nodeId, might just fetch full file
|
|
448
462
|
}
|
|
449
463
|
// 3. Fetch Data from Figma
|
|
450
|
-
//
|
|
451
|
-
const
|
|
464
|
+
// Use /nodes endpoint if nodeId exists, otherwise /files
|
|
465
|
+
const encodedNodeId = nodeId ? encodeURIComponent(nodeId) : "";
|
|
466
|
+
const figmaApiUrl = nodeId
|
|
467
|
+
? `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${encodedNodeId}`
|
|
468
|
+
: `https://api.figma.com/v1/files/${fileKey}`;
|
|
452
469
|
const figmaResponse = await fetch(figmaApiUrl, {
|
|
453
470
|
headers: { 'X-Figma-Token': figmaToken }
|
|
454
471
|
});
|
|
455
472
|
if (!figmaResponse.ok) {
|
|
456
|
-
|
|
473
|
+
const errorText = await figmaResponse.text();
|
|
474
|
+
throw new Error(`Figma API returned ${figmaResponse.status}: ${errorText} (URL: ${figmaApiUrl})`);
|
|
457
475
|
}
|
|
458
|
-
const
|
|
476
|
+
const rawData = (await figmaResponse.json());
|
|
459
477
|
// 4. Optionally fetch image preview if a node is specified
|
|
460
478
|
let imageUrl = null;
|
|
461
479
|
if (nodeId) {
|
|
462
|
-
const
|
|
480
|
+
const encodedIds = encodeURIComponent(nodeId);
|
|
481
|
+
const imageResponse = await fetch(`https://api.figma.com/v1/images/${fileKey}?ids=${encodedIds}&scale=2&format=png`, {
|
|
463
482
|
headers: { 'X-Figma-Token': figmaToken }
|
|
464
483
|
});
|
|
465
484
|
if (imageResponse.ok) {
|
|
@@ -467,14 +486,15 @@ Instruction: ${ann.message}`
|
|
|
467
486
|
imageUrl = imageData.images?.[nodeId];
|
|
468
487
|
}
|
|
469
488
|
}
|
|
489
|
+
const nodeInfo = nodeId ? rawData.nodes?.[nodeId] : null;
|
|
470
490
|
return {
|
|
471
491
|
content: [{
|
|
472
492
|
type: "text",
|
|
473
493
|
text: JSON.stringify({
|
|
474
|
-
fileName:
|
|
475
|
-
lastModified:
|
|
494
|
+
fileName: rawData.name || "Unknown File",
|
|
495
|
+
lastModified: rawData.lastModified,
|
|
476
496
|
previewUrl: imageUrl,
|
|
477
|
-
nodeName:
|
|
497
|
+
nodeName: nodeInfo ? (nodeInfo.document?.name || 'Selected Component') : 'Full File',
|
|
478
498
|
note: "Design context successfully retrieved from Figma."
|
|
479
499
|
}, null, 2)
|
|
480
500
|
}]
|