My Electron app starts other command-line tools: coding agents, git, gh. On a Mac, spawn('claude', args) just works. On Windows, the same line failed in two different ways.
First, most CLIs installed through npm aren't executables on Windows. They're .cmd shims. Since the April 2024 security fix (CVE-2024-27980), Node refuses to start a .cmd without shell: true. With the shell on, every argument goes through cmd.exe, which needs its own escaping and can't carry a line break inside an argument: a multi-line first message to an agent got cut off after the first line. What fixed it: read the npm shim, find the JavaScript file it wraps, and run that with node directly. Other .cmd files go through cross-spawn, which escapes arguments for cmd.exe.
Second, stopping things. When the CLI is a shim, the process you spawned is cmd.exe, and child.kill() ends only that one process. The agent it started keeps running in the background. taskkill /pid <pid> /T /F takes down the whole tree.
Both fixes now live in one helper that every spawn goes through, so nobody on the project (human or agent) calls spawn directly any more.
If you ship a Node or Electron tool that starts other CLIs, test it on Windows early. What else has bitten you there?
Top comments (0)