On Windows the daemon passes the full multi-line prompt as `-p <prompt>` but
spawns npm's `copilot.cmd`, which we already rewrite to
`powershell -File copilot.ps1`. Neither launcher can carry that argument:
- `copilot.cmd` forwards with `%*`, which cmd.exe expands by re-tokenising
the raw command line.
- `copilot.ps1` ends in `& node.exe npm-loader.js $args`, and PowerShell
re-serialises `$args` onto node's command line. Under Windows PowerShell
5.1 (and pwsh <= 7.2, which default to Legacy native argument passing)
embedded double quotes are not re-escaped, so the prompt is re-tokenised.
Copilot then sees several argv tokens where one was intended and refuses the
run with "It looks like your prompt was not quoted, so the extra words were
treated as separate arguments" — the same defect class already fixed for
cursor-agent in #5649, except Copilot has no stdin prompt channel to escape
through, so the prompt must stay on the command line and the launchers have
to go.
Copilot CLI ships a native per-platform binary and `npm-loader.js` does
nothing but `spawnSync` it with argv untouched, so resolve
`copilot-win32-{x64,arm64}\copilot.exe` out of the npm layout and spawn it
directly. That leaves exactly one hop, Go -> native binary, and Go's
syscall.EscapeArg is the exact inverse of the CRT parsing that binary uses.
This mirrors resolveOpenCodeNativeFromShim / resolveDevecoNativeFromShim.
Both the nested (current npm) and hoisted (older npm) platform-package
locations are probed; when neither resolves, we keep falling back to the
PowerShell launcher, which is still better than cmd.exe.
Co-authored-by: Bohan-J <bohan@devv.ai>
Co-authored-by: multica-agent <github@multica.ai>