Skip to content

fix(installer): drop shell:IS_WINDOWS from version-probe spawns to silence DEP0190 on Node 22 (closes #2941)#3046

Open
rodboev wants to merge 4 commits into
thedotmack:mainfrom
rodboev:fix/2941-dep0190-npxcli-shell
Open

fix(installer): drop shell:IS_WINDOWS from version-probe spawns to silence DEP0190 on Node 22 (closes #2941)#3046
rodboev wants to merge 4 commits into
thedotmack:mainfrom
rodboev:fix/2941-dep0190-npxcli-shell

Conversation

@rodboev

@rodboev rodboev commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Every npx claude-mem command on Windows with Node ≥ 22 prints [DEP0190] DeprecationWarning because seven spawnSync/spawn call sites in the npx-cli source pass both a truthy shell option and a separate args array. Node 22 made this a named deprecation. This PR removes the shell option from each call site by invoking cmd.exe /c explicitly on Windows for commands that require shell dispatch (bun, uv, npm, and arbitrary bin names in the doctor probe) and where.exe (a native binary) for the PATH-lookup probe.

Closes #2941

Why

src/npx-cli/utils/bun-resolver.ts:25, setup-runtime.ts:76,98,111,133, npm-install-helper.ts:59, and doctor.ts:30 all pass shell: IS_WINDOWS plus an args array. Node 22+ warns on this pattern (DEP0190) because args are concatenated into the shell command string without escaping, which can lead to injection. PR #1677 fixed scripts/bun-runner.js but the same pattern persisted in the npx-cli source bundle.

The fix: use spawnSync('cmd.exe', ['/c', executable, ...args]) on Windows instead of the shell: option. This lets cmd.exe handle .cmd shims and .exe binaries alike — without passing the shell option to Node's spawn, so DEP0190 is not triggered. For the where/which probe in bun-resolver.ts, where.exe is a native binary (C:\Windows\System32\where.exe) that spawns directly without any shell.

Scope

This PR covers the seven shell: + args sites in the npx-cli source. It does not address:

  • installBun() / installUv() execSync calls: they run shell pipelines (irm ... | iex, curl ... | bash) which are inherently shell constructs with no separate args array — not DEP0190 triggers.
  • installPluginDependencies() execSync call: same — command-string form, no args array.
  • Hook shell scripts or the dist/ bundle: npm run build regenerates the bundle from the fixed source.

Verification

  • npm run build — bundle within size guardrail; TypeScript compiles clean
  • npm run lint:spawn-env — all spawn sites pass discipline check
  • npm run lint:hook-io && npm run strip-comments:check — clean
  • Manual on Windows Node 22: NODE_OPTIONS=--trace-deprecation npx claude-mem doctor — no DEP0190 lines

Closes #2941

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes deprecated Windows shell usage from npx-cli version and install probes. The main changes are:

  • Uses explicit cmd.exe /d /c wrappers for Windows command dispatch.
  • Runs where.exe directly for Bun PATH lookup.
  • Bypasses cmd.exe for absolute Bun and uv version probes.

Confidence Score: 4/5

The change addresses the deprecation warning path, but one Windows install command still mishandles Bun paths containing command metacharacters.

The affected code is narrow and review coverage focused on the modified Windows command-dispatch behavior; runtime evidence confirmed the remaining quoting issue for metacharacter-containing paths.

src/npx-cli/install/setup-runtime.ts

T-Rex T-Rex Logs

What T-Rex did

  • Ran a targeted Node harness to reproduce how an ampersand in the bunPath affects command execution when IS_WINDOWS is forced, which showed the generated command left the metacharacter path unquoted, caused the shell to split at the ampersand and fail to locate the bun executable, and, per logs, indicated cmd.exe was unavailable in this Linux container so /bin/sh acted as the nearest metacharacter-splitting surface.
  • Performed a Linux-hosted win32 simulation to compare pre- and post-artifact shell-args behavior, confirming that after the artifact the system uses cmd.exe /d /c, bun-resolver uses where.exe, and all stubbed commands report status 0 with version/path outputs, noting that this was not a real Windows Node 22 DEP0190 run.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. src/npx-cli/install/setup-runtime.ts, line 418 (link)

    P1 Quote Bun command paths

    The latest version probe fix handles absolute Windows paths with metacharacters, but the same bunPath is later interpolated into a cmd.exe command string here and only quoted when it contains a space. When Bun is installed under a profile like C:\Users\A&B\.bun\bin\bun.exe, ensureBun() can now return that path successfully, then bun install fails because cmd.exe treats & as a command separator. This leaves the Windows install path broken for the same usernames the version-probe fix was meant to handle.

    Artifacts

    Repro: generated command-splitting harness

    • Contains supporting evidence from the run (text/javascript; charset=utf-8).

    Repro: harness output showing unquoted ampersand command splitting

    • Keeps the command output available without making the summary code-heavy.

    View artifacts

    T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "Skip cmd.exe wrapper for absolute runtim..." | Re-trigger Greptile

Comment thread src/npx-cli/commands/doctor.ts
Comment thread src/npx-cli/install/npm-install-helper.ts
Comment thread src/npx-cli/install/setup-runtime.ts
Comment thread src/npx-cli/install/setup-runtime.ts Outdated
Comment thread src/npx-cli/install/setup-runtime.ts
Comment thread src/npx-cli/install/setup-runtime.ts Outdated
Comment thread src/npx-cli/install/setup-runtime.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DEP0190 still reproducible on 13.6.1 (regression of #1503 / #438 / #433): args + shell in the npx-cli bundle

1 participant