figma-rust-mcp 8.0.1 → 8.0.2
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/bin/figma-rust-mcp.js +47 -17
- package/package.json +1 -1
package/bin/figma-rust-mcp.js
CHANGED
|
@@ -253,6 +253,13 @@ async function findOrDownloadBinary() {
|
|
|
253
253
|
* - Windows: Task Scheduler XML via schtasks
|
|
254
254
|
*/
|
|
255
255
|
async function installService(binPath) {
|
|
256
|
+
// An outdated CLI (e.g. an old global install run via plain `npx figma-rust-mcp`) must not replace a newer service.
|
|
257
|
+
const running = await serverVersion(Number(process.env.FIGMA_RUST_MCP_PORT) || 41730);
|
|
258
|
+
if (running && isNewer(running, pkgVersion)) {
|
|
259
|
+
console.log(` ${yellow('!')} Service runs v${running}, newer than this CLI (v${pkgVersion}); left it unchanged.`);
|
|
260
|
+
note('Use the latest CLI: npx -y figma-rust-mcp@latest --init');
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
256
263
|
removeLegacyService();
|
|
257
264
|
await stopRunningServer();
|
|
258
265
|
const platform = process.platform;
|
|
@@ -340,26 +347,51 @@ WantedBy=default.target
|
|
|
340
347
|
console.error(`\x1b[31mUnsupported platform: ${platform}\x1b[0m`);
|
|
341
348
|
process.exit(1);
|
|
342
349
|
}
|
|
350
|
+
pruneOldBinaries(binPath);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Delete cached binaries of versions older than the one the service now runs. A process still
|
|
355
|
+
* running an old binary keeps working on macOS/Linux; on Windows a locked file is skipped.
|
|
356
|
+
*/
|
|
357
|
+
function pruneOldBinaries(binPath) {
|
|
358
|
+
const root = path.dirname(getCacheDir(pkgVersion));
|
|
359
|
+
const current = path.basename(path.dirname(binPath)).match(/^v(\d+\.\d+\.\d+)$/)?.[1] || pkgVersion;
|
|
360
|
+
let entries;
|
|
361
|
+
try { entries = fs.readdirSync(root); } catch (_) { return; }
|
|
362
|
+
let freed = 0, removed = 0;
|
|
363
|
+
for (const name of entries) {
|
|
364
|
+
const version = name.match(/^v(\d+\.\d+\.\d+)$/)?.[1];
|
|
365
|
+
if (!version || !isNewer(current, version)) continue;
|
|
366
|
+
const dir = path.join(root, name);
|
|
367
|
+
try {
|
|
368
|
+
const size = fs.readdirSync(dir).reduce((sum, file) => sum + fs.statSync(path.join(dir, file)).size, 0);
|
|
369
|
+
fs.rmSync(dir, { recursive: true });
|
|
370
|
+
freed += size; removed++;
|
|
371
|
+
} catch (_) {}
|
|
372
|
+
}
|
|
373
|
+
if (removed) note(`Removed ${removed} old binar${removed === 1 ? 'y' : 'ies'} (${(freed / 1048576).toFixed(0)} MB freed)`);
|
|
343
374
|
}
|
|
344
375
|
|
|
345
376
|
async function serviceInstalled(where) {
|
|
346
377
|
const port = Number(process.env.FIGMA_RUST_MCP_PORT) || 41730;
|
|
347
378
|
const deadline = Date.now() + 10000;
|
|
348
|
-
while (!(await
|
|
349
|
-
if (await
|
|
379
|
+
while (!(await serverVersion(port)) && Date.now() < deadline) await new Promise(resolve => setTimeout(resolve, 300));
|
|
380
|
+
if (await serverVersion(port)) ok('Background service running', `http://127.0.0.1:${port}`);
|
|
350
381
|
else console.log(` ${yellow('!')} Service installed but not answering on port ${port} yet`);
|
|
351
382
|
note(`Starts on login · ${where}`);
|
|
352
383
|
}
|
|
353
384
|
|
|
354
|
-
|
|
385
|
+
/** Version of the figma-rust-mcp answering on `port`, or null. */
|
|
386
|
+
function serverVersion(port) {
|
|
355
387
|
return new Promise(resolve => {
|
|
356
388
|
const req = http.get({ host: '127.0.0.1', port, path: '/plugin/version', timeout: 500 }, res => {
|
|
357
389
|
let body = '';
|
|
358
390
|
res.on('data', chunk => { body += chunk; });
|
|
359
|
-
res.on('end', () => { try {
|
|
391
|
+
res.on('end', () => { try { const v = JSON.parse(body); resolve(v.name === 'figma-rust-mcp' ? v.version || '0.0.0' : null); } catch (_) { resolve(null); } });
|
|
360
392
|
});
|
|
361
|
-
req.on('error', () => resolve(
|
|
362
|
-
req.on('timeout', () => { req.destroy(); resolve(
|
|
393
|
+
req.on('error', () => resolve(null));
|
|
394
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
363
395
|
});
|
|
364
396
|
}
|
|
365
397
|
|
|
@@ -382,7 +414,7 @@ async function stopRunningServer() {
|
|
|
382
414
|
}
|
|
383
415
|
const port = Number(process.env.FIGMA_RUST_MCP_PORT) || 41730;
|
|
384
416
|
const deadline = Date.now() + 10000;
|
|
385
|
-
while (await
|
|
417
|
+
while (await serverVersion(port)) {
|
|
386
418
|
if (Date.now() > deadline) {
|
|
387
419
|
console.log(` ${yellow('!')} An old figma-rust-mcp still answers on port ${port}; stop it, then rerun setup.`);
|
|
388
420
|
return;
|
|
@@ -559,19 +591,17 @@ function checkForUpdatesAsync() {
|
|
|
559
591
|
}
|
|
560
592
|
|
|
561
593
|
async function upgrade() {
|
|
562
|
-
|
|
594
|
+
const major = pkgVersion.split('.')[0];
|
|
595
|
+
console.log(`${tag(36)} Upgrading figma-rust-mcp v${major}.x…`);
|
|
563
596
|
try {
|
|
564
|
-
const major = pkgVersion ? pkgVersion.split('.')[0] : 'latest';
|
|
565
597
|
execSync(`npm install -g figma-rust-mcp@${major}`, { stdio: 'inherit' });
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const binPath = await findOrDownloadBinary();
|
|
571
|
-
await installService(binPath);
|
|
572
|
-
}
|
|
598
|
+
// This process still runs the old code and version; let the new package refresh the plugin and service.
|
|
599
|
+
const args = ['-y', `figma-rust-mcp@${major}`, isServiceInstalled() ? '--install-service' : '--setup-plugin'];
|
|
600
|
+
execFileSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', args, { stdio: 'inherit', shell: process.platform === 'win32' });
|
|
601
|
+
ok(`Upgraded figma-rust-mcp (v${major}.x)`);
|
|
573
602
|
} catch (err) {
|
|
574
|
-
console.log('
|
|
603
|
+
console.log(` ${yellow('!')} Upgrade failed: ${err.message}`);
|
|
604
|
+
note('Run the latest version directly: npx -y figma-rust-mcp@latest --init');
|
|
575
605
|
}
|
|
576
606
|
}
|
|
577
607
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-rust-mcp",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.2",
|
|
4
4
|
"description": "Claude Code to Figma — Bidirectional MCP bridge. AI draws UI on Figma canvas, reads designs back. Works with Claude, Cursor, VS Code, Windsurf, Antigravity. No API key needed.",
|
|
5
5
|
"mcpName": "io.github.BuiHung1612/figma-rust-mcp",
|
|
6
6
|
"type": "module",
|