From 3bcd55ccfd84bbaf6932817f8158c98c929904eb Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Sun, 5 Apr 2026 11:33:03 -0700 Subject: [PATCH 1/2] fix(cli): show latest version and bypass npm cache in update check --- src/update-cmd.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/update-cmd.ts b/src/update-cmd.ts index ac16a8209..9534fd9f6 100644 --- a/src/update-cmd.ts +++ b/src/update-cmd.ts @@ -14,18 +14,21 @@ export async function runUpdate(): Promise { process.stdout.write(`${dim}Current version:${reset} v${current}\n`) process.stdout.write(`${dim}Checking npm registry...${reset}\n`) - // Fetch latest version + // Fetch latest version — bypass npm client cache to avoid stale results (#3445) let latest: string try { - latest = execSync(`npm view ${NPM_PACKAGE} version`, { + latest = execSync(`npm view ${NPM_PACKAGE} version --fetch-retry-mintimeout=3000`, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], + env: { ...process.env, npm_config_cache: '' }, }).trim() } catch { process.stderr.write(`${yellow}Failed to reach npm registry.${reset}\n`) process.exit(1) } + process.stdout.write(`${dim}Latest version:${reset} v${latest}\n`) + if (compareSemver(latest, current) <= 0) { process.stdout.write(`${green}Already up to date.${reset}\n`) return From 469acf53af778a0304dd27c080b838a111204f8a Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Sun, 5 Apr 2026 11:57:25 -0700 Subject: [PATCH 2/2] test(cli): add update diagnostics regression test --- src/tests/update-cmd-diagnostics.test.ts | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/tests/update-cmd-diagnostics.test.ts diff --git a/src/tests/update-cmd-diagnostics.test.ts b/src/tests/update-cmd-diagnostics.test.ts new file mode 100644 index 000000000..71fff7b36 --- /dev/null +++ b/src/tests/update-cmd-diagnostics.test.ts @@ -0,0 +1,27 @@ +/** + * Regression test for #3445: gsd update must print both current and latest + * versions for diagnostics, and bypass npm cache. + */ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +test("update-cmd prints latest version before comparison (#3445)", () => { + const src = readFileSync(join(__dirname, "..", "update-cmd.ts"), "utf-8"); + const latestPrintIdx = src.indexOf("Latest version:"); + const comparisonIdx = src.indexOf("compareSemver(latest, current)"); + assert.ok(latestPrintIdx !== -1, "Must print latest version"); + assert.ok(latestPrintIdx < comparisonIdx, "Must print latest BEFORE comparison"); +}); + +test("update-cmd bypasses npm cache (#3445)", () => { + const src = readFileSync(join(__dirname, "..", "update-cmd.ts"), "utf-8"); + assert.ok( + src.includes("npm_config_cache"), + "Must clear npm cache env to bypass stale registry data", + ); +});