From b276a98ae0961ba91cf7dd6ecbc0967fb1015af5 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 2 Jul 2026 20:00:43 -0700 Subject: [PATCH] fix(dashboard): spawn npm with a shell on Windows for CLI install button The CLI-binary panel's "Install with npm" button (POST /system/fn-binary/install) ran `spawn("npm", ["install","-g","runfusion.ai"], { shell: false })`. On Windows npm resolves to npm.cmd, which Node refuses to spawn without a shell (spawn npm ENOENT / EINVAL, CVE-2024-27980), so the button failed with "spawn npm ENOENT". Use shell on win32; the command/args are fixed constants with no caller input, so shell quoting is safe. (The npx spawns in cli skills/extension already set shell:true.) Verified on Windows: spawn("npm",["--version"],{shell:false}) -> ENOENT; {shell:true} -> ok. Co-Authored-By: Claude Opus 4.8 --- .../dashboard/src/routes/register-fn-binary-routes.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/dashboard/src/routes/register-fn-binary-routes.ts b/packages/dashboard/src/routes/register-fn-binary-routes.ts index 577e0b43e4..17980a0e1b 100644 --- a/packages/dashboard/src/routes/register-fn-binary-routes.ts +++ b/packages/dashboard/src/routes/register-fn-binary-routes.ts @@ -73,9 +73,16 @@ function runNpmInstall(): Promise { let stdout = ""; let stderr = ""; let timedOut = false; + /* + * FNXC:CliBinaryInstall 2026-07-03-03:00: + * On Windows `npm` resolves to `npm.cmd`; Node refuses to spawn a .cmd/.bat without a shell + * (spawn npm ENOENT / EINVAL since CVE-2024-27980), so the CLI-banner "Install with npm" button + * failed with `spawn npm ENOENT`. Use a shell on win32. The command/args are fixed constants + * (`npm install -g runfusion.ai`) with no caller-supplied input, so shell quoting is safe. + */ const child = spawn("npm", ["install", "-g", FN_NPM_PACKAGE], { stdio: ["ignore", "pipe", "pipe"], - shell: false, + shell: process.platform === "win32", }); const timer = setTimeout(() => { timedOut = true;