diff --git a/.changeset/windows-npm-shell-fix.md b/.changeset/windows-npm-shell-fix.md new file mode 100644 index 000000000..f33c5d5e6 --- /dev/null +++ b/.changeset/windows-npm-shell-fix.md @@ -0,0 +1,5 @@ +--- +type: Fixed +--- + +**Windows update-check no longer silently fails** — `gsd-check-update-worker` now passes `shell: true` only on Windows, allowing `execFileSync('npm', ...)` to resolve `npm.cmd` via PATHEXT. POSIX path (Linux/macOS) is unchanged. Without this fix, the worker failed with ENOENT, `latest` stayed `null`, `update_available` became `null`, and the statusline `⬆ /gsd-update` indicator never rendered for Windows users. Fixes #3103. diff --git a/hooks/gsd-check-update-worker.js b/hooks/gsd-check-update-worker.js index e6b7f6d58..ff5a16f7e 100644 --- a/hooks/gsd-check-update-worker.js +++ b/hooks/gsd-check-update-worker.js @@ -93,11 +93,13 @@ try { encoding: 'utf8', timeout: 10000, windowsHide: true, - // shell:true is required on Windows so 'npm' resolves to npm.cmd via PATHEXT. - // Without it, execFileSync looks for a literal 'npm' binary, fails with ENOENT, - // the catch swallows the error, latest stays null, and the statusline never shows - // the "⬆ /gsd-update" indicator on Windows. - shell: true, + // On Windows, 'npm' is distributed as npm.cmd. Node's execFileSync does + // not apply PATHEXT resolution and looks for a literal 'npm' binary, + // failing with ENOENT. Setting shell:true on Windows routes through + // cmd.exe which resolves npm.cmd via PATHEXT. + // POSIX (Linux/macOS) is left untouched — no shell spawn, no extra + // signal/exit-code semantics, no overhead. + shell: process.platform === 'win32', }).trim(); } catch (e) {}