singularity-forge/packages/pi-coding-agent/src/utils
Matt Haynes c557aea8de fix(windows): prevent EINVAL by disabling detached process groups on Win32 (#2744)
On Windows, `spawn()` with `detached: true` sets the
CREATE_NEW_PROCESS_GROUP flag in CreateProcess. In certain terminal
contexts — notably VSCode's integrated terminal (ConPTY), Windows
Terminal, and some MSYS2/Git Bash configurations — this flag conflicts
with the parent process group hierarchy and causes a synchronous EINVAL
from libuv, making *every* bash/async_bash/bg_shell command fail
immediately with `spawn EINVAL`.

The bg-shell extension already guards against this with
`detached: process.platform !== "win32"` (process-manager.ts:109),
but three other spawn sites were missed:

- `packages/pi-coding-agent/src/core/tools/bash.ts` (bash tool)
- `packages/pi-coding-agent/src/core/bash-executor.ts` (RPC executor)
- `src/resources/extensions/async-jobs/async-bash-tool.ts` (async_bash)

This commit aligns all spawn sites with the bg-shell pattern.

Additionally fixes two related issues:

1. `killProcessTree()` in shell.ts used `detached: true` on its own
   `taskkill` spawn call — unnecessary and potentially problematic
   in the same terminal contexts. Removed.

2. `killTree()` in async-bash-tool.ts used Unix-only
   `process.kill(-pid)` with no Windows fallback. On Windows, negative
   PIDs (process group kill) are not supported, so orphaned child
   processes could survive timeout kills. Now uses `taskkill /F /T`
   on Windows, matching the bg-shell and shell.ts implementations.

Includes a regression test that statically verifies no spawn site
uses unconditional `detached: true`, plus a smoke test confirming
the platform-guarded pattern works on all platforms.

Reproduction: Run GSD v2.42-v2.51 inside VSCode on Windows 11 with
Git Bash as the shell. Any bash tool call fails with `spawn EINVAL`.
The error is 100% reproducible and affects all shell operations
(bash, async_bash, bg_shell start).

Co-authored-by: Matt Haynes <matt@auroraventures.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 16:08:03 -06:00
..
changelog.ts refactor: remove dead code (unused exports) (#1486) 2026-03-19 15:33:32 -06:00
clipboard-image.ts refactor: remove dead code (unused exports) (#1486) 2026-03-19 15:33:32 -06:00
clipboard-native.ts feat: replace clipboard implementations with native @gsd/native module 2026-03-13 13:31:22 -06:00
clipboard.ts feat: replace clipboard implementations with native @gsd/native module 2026-03-13 13:31:22 -06:00
error.ts refactor: extract retry handler and compaction orchestrator from agent-session 2026-03-19 16:46:14 -03:00
frontmatter.ts feat: vendor Pi source into workspace monorepo 2026-03-12 21:55:17 -06:00
git.ts feat: vendor Pi source into workspace monorepo 2026-03-12 21:55:17 -06:00
image-convert.ts feat: wire native Rust image module into image processing pipeline 2026-03-13 13:41:53 -06:00
image-resize.ts feat: wire native Rust image module into image processing pipeline 2026-03-13 13:41:53 -06:00
mime.ts feat: vendor Pi source into workspace monorepo 2026-03-12 21:55:17 -06:00
path-display.ts fix: normalize Windows paths in LLM-visible text to prevent bash failures (#874) (#884) 2026-03-17 09:02:23 -06:00
photon.ts refactor: remove dead code (unused exports) (#1486) 2026-03-19 15:33:32 -06:00
shell.ts fix(windows): prevent EINVAL by disabling detached process groups on Win32 (#2744) 2026-03-26 16:08:03 -06:00
sleep.ts feat: vendor Pi source into workspace monorepo 2026-03-12 21:55:17 -06:00
tools-manager.ts refactor: remove dead code (unused exports) (#1486) 2026-03-19 15:33:32 -06:00