Upstream bug report — earendil-works/pi-mono
Package: @earendil-works/pi-coding-agent@0.74.0
File: packages/coding-agent/src/core/package-manager.ts
(compiled: dist/core/package-manager.js)
Platform: Windows
Severity: High — aborts session creation for any working directory
whose absolute path contains a space (very common, e.g.
C:\Users\<name>\Documents\Marketing Advisor).
Summary
PackageManager spawns npm/npx/pnpm/yarn with Node's
child_process.spawn(command, args, { shell: true }) on Windows
(shouldUseWindowsShell() returns true because these resolve to
.cmd shims). Per the Node.js docs, when shell is true the
args array is not quoted/escaped — the command line is handed to
cmd.exe verbatim, which word-splits on whitespace.
Consequently npm install <spec> --prefix <dir> where <dir> has a
space (e.g. the project <cwd>/.pi/npm) is split: npm receives a
truncated --prefix and the remainder as a separate relative arg.
Reproduction
- On Windows, start a session whose working directory path contains a
space, e.g. C:\Users\me\Documents\Marketing Advisor.
- PI auto-installs a project extension:
npm install @dhruv2mars/pi-queue --prefix C:\Users\me\Documents\Marketing Advisor\.pi\npm
- Observed failure:
npm error code ENOENT
npm error path C:\Users\me\Documents\<launchCwd>\Advisor\.pi\npm\package.json
npm error enoent Could not read package.json: ENOENT: no such file or directory,
open 'C:\Users\me\Documents\<launchCwd>\Advisor\.pi\npm\package.json'
Error: npm install @dhruv2mars/pi-queue --prefix C:\Users\me\Documents\Marketing Advisor\.pi\npm
failed with code 4294963238
at ChildProcess.<anonymous> (.../core/package-manager.js)
cmd.exe split --prefix C:\…\Marketing Advisor\.pi\npm into
--prefix C:\…\Marketing + Advisor\.pi\npm; npm resolved the latter
relative to the spawn cwd → ENOENT. Session creation aborts.
Root cause
dist/core/package-manager.js (v0.74.0), three spawn sites:
spawnCommand() — spawn(command, args, { shell: shouldUseWindowsShell(command) })
spawnCaptureCommand() — same
runCommandSync() — spawnSync(command, args, { shell: shouldUseWindowsShell(command) })
args is passed unquoted while shell is true.
Suggested fix
When (and only when) the shell is used, quote args that contain
whitespace before handing them to spawn/spawnSync (passthrough
otherwise so the non-shell argv path is unchanged):
function shellQuote(useShell: boolean, args: string[]): string[] {
if (!useShell) return args;
return args.map((a) => {
const s = String(a);
return /\s/.test(s) ? `"${s.replace(/"/g, '\\"')}"` : s;
});
}
Apply at the three spawn sites. (A more complete escape of cmd.exe
metacharacters — &|<>^()%! — is advisable, but whitespace quoting
alone resolves the reported ENOENT class.) Alternatively, avoid
shell:true by resolving the npm/npx executable to its absolute path
and spawning it directly without a shell.
Workaround (downstream, ally2)
Patched locally via patch-package against
@earendil-works/pi-coding-agent with the shellQuote helper above.
Tracked as ally2 open topic T-077.
Upstream bug report — earendil-works/pi-mono
Package:
@earendil-works/pi-coding-agent@0.74.0File:
packages/coding-agent/src/core/package-manager.ts(compiled:
dist/core/package-manager.js)Platform: Windows
Severity: High — aborts session creation for any working directory
whose absolute path contains a space (very common, e.g.
C:\Users\<name>\Documents\Marketing Advisor).Summary
PackageManagerspawnsnpm/npx/pnpm/yarnwith Node'schild_process.spawn(command, args, { shell: true })on Windows(
shouldUseWindowsShell()returns true because these resolve to.cmdshims). Per the Node.js docs, whenshellistruetheargsarray is not quoted/escaped — the command line is handed tocmd.exeverbatim, which word-splits on whitespace.Consequently
npm install <spec> --prefix <dir>where<dir>has aspace (e.g. the project
<cwd>/.pi/npm) is split: npm receives atruncated
--prefixand the remainder as a separate relative arg.Reproduction
space, e.g.
C:\Users\me\Documents\Marketing Advisor.npm install @dhruv2mars/pi-queue --prefix C:\Users\me\Documents\Marketing Advisor\.pi\npmcmd.exesplit--prefix C:\…\Marketing Advisor\.pi\npminto--prefix C:\…\Marketing+Advisor\.pi\npm; npm resolved the latterrelative to the spawn cwd → ENOENT. Session creation aborts.
Root cause
dist/core/package-manager.js(v0.74.0), three spawn sites:spawnCommand()—spawn(command, args, { shell: shouldUseWindowsShell(command) })spawnCaptureCommand()— samerunCommandSync()—spawnSync(command, args, { shell: shouldUseWindowsShell(command) })argsis passed unquoted whileshellistrue.Suggested fix
When (and only when) the shell is used, quote args that contain
whitespace before handing them to
spawn/spawnSync(passthroughotherwise so the non-shell argv path is unchanged):
Apply at the three spawn sites. (A more complete escape of cmd.exe
metacharacters —
&|<>^()%!— is advisable, but whitespace quotingalone resolves the reported ENOENT class.) Alternatively, avoid
shell:trueby resolving the npm/npx executable to its absolute pathand spawning it directly without a shell.
Workaround (downstream, ally2)
Patched locally via
patch-packageagainst@earendil-works/pi-coding-agentwith theshellQuotehelper above.Tracked as ally2 open topic T-077.