From 2caccb72860129bc0bfcd099c79e6661e960bb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sil=20Borm=C3=BCller?= Date: Sat, 26 Sep 2026 15:13:31 +0200 Subject: [PATCH] fix: restart the daemon only when it is older than the CLI Two installs of different versions restarted each other's daemon on every command. Now only an older daemon (or one too old to report its version) is replaced, so the newer one wins. Release 2.2.5. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- src/lib/cli-core.js | 21 ++++++++++++++++----- tests/daemon-version.test.js | 11 +++++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 tests/daemon-version.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bd125c6..9a0c91c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2.2.5 (2026-09-26) + +### Fixed + +- The daemon is only restarted when it runs an older version than the CLI. With two installs of different versions (global and project-local) they no longer restart each other on every command; the newer daemon stays + ## 2.2.4 (2026-09-26) ### Fixed diff --git a/package-lock.json b/package-lock.json index 90309e29..c3a068e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "figma-ds-cli", - "version": "2.2.4", + "version": "2.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "figma-ds-cli", - "version": "2.2.4", + "version": "2.2.5", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/package.json b/package.json index d79ed718..6a823c74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "figma-ds-cli", - "version": "2.2.4", + "version": "2.2.5", "description": "CLI for managing Figma design systems. Create variables, components, and more. No API key required.", "author": { "name": "Sil Bormüller", diff --git a/src/lib/cli-core.js b/src/lib/cli-core.js index c84f3ded..efc57658 100644 --- a/src/lib/cli-core.js +++ b/src/lib/cli-core.js @@ -246,16 +246,26 @@ const DAEMON_HEALTH_TTL_MS = 2000; function invalidateDaemonHealthCache() { _daemonHealthCache = { time: 0, value: null }; } let _daemonHealthBody = null; +// true when version a is older than b (plain x.y.z) +function versionOlder(a, b) { + const p = v => String(v || '0').split('-')[0].split('.').map(n => parseInt(n, 10) || 0); + const x = p(a), y = p(b); + for (let i = 0; i < 3; i++) { if ((x[i] || 0) !== (y[i] || 0)) return (x[i] || 0) < (y[i] || 0); } + return false; +} + /** - * True when the running daemon was started from different figma-cli code: - * another version (after npm update) or another install path. render-batch and - * eval run INSIDE the daemon, so a stale one silently serves old behaviour. - * A daemon too old to report its version counts as stale. + * True when the running daemon runs OLDER figma-cli code than this CLI (after + * npm update). render-batch and eval run INSIDE the daemon, so a stale one + * silently serves old behaviour. A daemon too old to report its version counts + * as older. Only older, never merely different: with two installs of different + * versions (global and project-local) "restart on any mismatch" made them + * restart each other on every command; this way the newer one wins and stays. */ function daemonCodeMismatch() { const h = _daemonHealthBody; if (!h || h.status === undefined) return false; - return h.version !== pkg.version || (h.root && h.root !== join(__dirname)); + return !h.version || versionOlder(h.version, pkg.version); } // Check if daemon is running (returns object with details, or false) @@ -991,6 +1001,7 @@ async function isInSafeMode() { } export { + versionOlder, CONFIG_DIR, CONFIG_FILE, DAEMON_PID_FILE, diff --git a/tests/daemon-version.test.js b/tests/daemon-version.test.js new file mode 100644 index 00000000..6004c822 --- /dev/null +++ b/tests/daemon-version.test.js @@ -0,0 +1,11 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { versionOlder } from '../src/lib/cli-core.js'; + +test('only an older daemon counts as stale, so two installs never restart each other', () => { + assert.equal(versionOlder('2.2.3', '2.2.4'), true); + assert.equal(versionOlder('2.2.4', '2.2.4'), false); + assert.equal(versionOlder('2.3.0', '2.2.9'), false); + assert.equal(versionOlder('2.10.0', '2.9.0'), false); + assert.equal(versionOlder(undefined, '2.2.4'), true); +});