aaif-goose / aaif-goose/goose

Windows npx.cmd should check for an existing system Node.js/npx before downloading its own portable copy

Aperta
#11,314 2 commenti 0 reazioni 1 assegnatario Rivendicata da @jbg Vedi su GitHub
Lingua principale
Rust
Stelle
54.2k
Fork
6.2k
Merge medio
3g 2h
PR unite (30g)
262

Descrizione

**What problem would this solve?**

On Windows, Goose ships a portable-Node bootstrapper at `resources\bin\npx.cmd` (also copied to `%LOCALAPPDATA%\Goose\bin\npx.cmd`), used as the `cmd` for stdio MCP extensions configured with `cmd: npx` (e.g. `gptimagemcp`, `azure-mcp`, `chromedevtools`, and any community npm-based MCP server).

This script unconditionally downloads a private copy of Node.js v22.14.0 from `nodejs.org` the first time it runs. It only checks for its own marker file (`%LOCALAPPDATA%\Goose\node\node-v22.14.0.installed`) — it never checks whether a working Node.js/npx already exists on the machine (via `PATH`, `where node`, or standard install locations like `C:\Program Files\nodejs`).

This affects any Windows user who already has Node.js installed system-wide (likely the majority of developers), and is especially painful in corporate environments with SSL-inspecting proxies (Zscaler, Netskope, etc.): the ~35MB zip download from `nodejs.org` frequently fails with `ECONNRESET` mid-stream (proxy DLP/AV inspection interrupting large binary downloads), even when the intercepting root CA is otherwise trusted via `NODE_EXTRA_CA_CERTS`. This causes every `npx`-based stdio extension to fail to start with an unhelpful error, even though a perfectly working system Node.js (e.g. v24.11.0 in our case) is sitting right there in `PATH`.

Related prior reports of npx/Node resolution pain on Windows: #6010, #1954, #8046.

**What would a good outcome look like?**

When a stdio extension needs to run via `npx`, Goose should prefer an already-installed, working system Node.js/npx over downloading its own pinned copy (`$PATH`). The private/portable download should only kick in as a fallback when no usable system Node.js is found (or it fails a minimal sanity check).

Concretely: a user with Node.js already installed and in `PATH` should never see a network download attempt at all when enabling an `npx`-based extension — it should just work immediately using the existing installation.

**Possible approaches**

- In `npx.cmd`, before the download branch, check `where node` (and/or `where.exe npx`) and optionally validate with `node --version` (with a minimum version guard, since some MCP servers require a modern Node). If a working system Node is found, use it directly instead of falling through to the download logic.
- Make the preference configurable via an env var (e.g. `GOOSE_PREFER_SYSTEM_NODE`, defaulting to true) for users who want the pinned/portable version for reproducibility regardless of what's installed locally.
- The same underlying issue likely applies to the macOS/Linux Hermit-based bootstrap path (see #8046), though the mechanism there is different (Hermit environment activation vs. a plain batch download) and may need a separate fix.
- Consider surfacing a clearer error/log line distinguishing "no system Node found, attempting portable download" vs. the current opaque failure, to help users self-diagnose faster.

**Additional context**

Current relevant excerpt from `npx.cmd`:

```bat
if not defined GOOSE_NODE_DIR (
SET "GOOSE_NODE_DIR=%LOCALAPPDATA%\Goose\node"
)
SET "NODE_VERSION=22.14.0"

REM === Check for previously downloaded portable Node.js (matching version) ===
if exist "%GOOSE_NODE_DIR%\node-v%NODE_VERSION%.installed" (
SET "PATH=%GOOSE_NODE_DIR%;!PATH!"
"%GOOSE_NODE_DIR%\npx.cmd" %*
exit /b !errorlevel!
)

REM === Download portable Node.js ===
echo [Goose] Node.js not found. Downloading portable Node.js v%NODE_VERSION%... 1>&2
...
```

Observed failure on a machine with Node v24.11.0 already installed and working (`node --version`, `npx --version` both succeed in a fresh shell), behind a Zscaler SSL-inspecting proxy:

```
process quit before initialization: stderr = [Goose] Node.js not found. Downloading portable Node.js v22.14.0...
... Invoke-WebRequest ... : Impossible de lire les données de la connexion de transport : Une connexion existante a dû être fermée par l'hôte distant.
[Goose] ERROR: Failed to download Node.js. Please install manually from https://nodejs.org/
```

Current manual workaround: editing `config.yaml` to point the extension's `cmd` at the full system npx path directly, e.g.:
```yaml
gptimagemcp:
cmd: C:\Program Files\nodejs\npx.cmd
```
This works but is manual, per-extension, and easy to lose across config resets/updates (see #6010, where a similar manual full-path edit "doesn't help (config gets reset)").

- [x] I have verified this does not duplicate an existing feature request

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.