fix(installer): drop shell:IS_WINDOWS from version-probe spawns to silence DEP0190 on Node 22 (closes #2941)#3046
Conversation
…lence DEP0190 on Node 22 (closes thedotmack#2941)
…wns without shell
Greptile SummaryThis PR removes deprecated Windows
Confidence Score: 4/5The 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
What T-Rex did
|
Summary
Every
npx claude-memcommand on Windows with Node ≥ 22 prints[DEP0190] DeprecationWarningbecause sevenspawnSync/spawncall sites in the npx-cli source pass both a truthyshelloption and a separateargsarray. Node 22 made this a named deprecation. This PR removes theshelloption from each call site by invokingcmd.exe /cexplicitly on Windows for commands that require shell dispatch (bun, uv, npm, and arbitrary bin names in the doctor probe) andwhere.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, anddoctor.ts:30all passshell: IS_WINDOWSplus 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 fixedscripts/bun-runner.jsbut the same pattern persisted in the npx-cli source bundle.The fix: use
spawnSync('cmd.exe', ['/c', executable, ...args])on Windows instead of theshell:option. This letscmd.exehandle.cmdshims and.exebinaries alike — without passing theshelloption to Node's spawn, so DEP0190 is not triggered. For thewhere/whichprobe inbun-resolver.ts,where.exeis 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()execSynccalls: they run shell pipelines (irm ... | iex,curl ... | bash) which are inherently shell constructs with no separate args array — not DEP0190 triggers.installPluginDependencies()execSynccall: same — command-string form, no args array.dist/bundle:npm run buildregenerates the bundle from the fixed source.Verification
npm run build— bundle within size guardrail; TypeScript compiles cleannpm run lint:spawn-env— all spawn sites pass discipline checknpm run lint:hook-io && npm run strip-comments:check— cleanNODE_OPTIONS=--trace-deprecation npx claude-mem doctor— no DEP0190 linesCloses #2941