From 764e5937a5e3f3ddfa373e53eb80529aaf47ca8b Mon Sep 17 00:00:00 2001 From: XuHaoran <3230105281@zju.edu.cn> Date: Wed, 3 Jun 2026 01:19:24 +0800 Subject: [PATCH] fix(dev-launcher): spawn npm through shell on Windows On Windows the npm executable is a npm.cmd shim. `npm run dev` (which runs scripts/dev-launcher.mjs) crashed immediately with `spawn npm ENOENT`, and switching to the `npm.cmd` name alone then failed with `spawn EINVAL` because recent Node.js releases refuse to spawn .cmd/.bat files without a shell (hardening from CVE-2024-27980). Use `npm.cmd` plus `shell: true` on win32 and keep the plain, shell-free spawn on macOS/Linux. The spawn arguments are fixed literals with no user input, so enabling the shell carries no injection risk. This makes `npm run dev` work out of the box on Windows. --- scripts/dev-launcher.mjs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/dev-launcher.mjs b/scripts/dev-launcher.mjs index 58b260a3..a613a054 100644 --- a/scripts/dev-launcher.mjs +++ b/scripts/dev-launcher.mjs @@ -119,10 +119,19 @@ async function main() { PILOTDECK_SKIP_DEFAULT_PROJECT: '1', }; + // On Windows the npm executable is a `npm.cmd` shim. Recent Node.js releases + // refuse to spawn `.cmd`/`.bat` files without a shell (they throw EINVAL, a + // hardening change from CVE-2024-27980), and the bare `npm` name cannot be + // resolved by `spawn` at all (ENOENT). Launch through the platform shell on + // Windows so `npm run dev` works out of the box; other platforms keep the + // plain, shell-free spawn. The arguments here are fixed literals with no + // user input, so enabling the shell carries no injection risk. + const isWindows = process.platform === 'win32'; + const npmCommand = isWindows ? 'npm.cmd' : 'npm'; const child = spawn( - 'npm', + npmCommand, ['--workspace', 'ui', 'run', 'dev:concurrent'], - { cwd: repoRoot, env, stdio: 'inherit' }, + { cwd: repoRoot, env, stdio: 'inherit', shell: isWindows }, ); const forward = (signal) => {