Address cubic and oracle review feedback to make the Node/Electron
fallback faithful to Bun.spawn behavior so cross-runtime callers
behave identically.
Changes:
- resolveStdio() default stdio is now ["ignore", "pipe", "inherit"]
to match Bun.spawn defaults (was ["pipe", "pipe", "pipe"]).
Prevents hangs in dispatcher and on-complete-hook callers that
did not explicitly set stdin and would otherwise wait forever
for input on Node.
- spawn-with-windows-hide.ts uses the same defaults so the Windows
Node helper aligns with the rest of the shim.
- wrapNodeProcess now rejects proc.exited with the original error
on "error" events (previously swallowed the error and resolved
to exit code 1, hiding ENOENT and friends).
- spawnSync result returns the real result.pid instead of -1 and
exposes stdout/stderr as Buffer | undefined to match Node's
spawnSync result shape when those streams are not piped.
Tests cover the new defaults, real pid surfacing, and missing
executable error propagation.
Refs cubic review and oracle audit on #3798.
Root cause: bun build --target bun inlines top-level
var { spawn } = globalThis.Bun;
for every file that contains 'import { spawn } from "bun"'. On Node/Electron
where globalThis.Bun is undefined, this crashes with
Cannot destructure property 'spawn' of 'globalThis.Bun' as it is undefined.
26 source files had this import; the bundled output had 25 top-level destructures.
Fix:
- Add src/shared/bun-spawn-shim.ts: a thin wrapper that
- delegates to Bun.spawn/spawnSync when globalThis.Bun is present (real Bun)
- falls back to static ESM imports of node:child_process otherwise
- uses static 'import { spawn } from "node:child_process"' so Bun bundler
does NOT emit any globalThis.Bun destructures for this module
- Replace all 26 'from "bun"' spawn/spawnSync imports with relative paths to shim
- Replace 4 direct Bun.spawn() call sites with shim's spawn()
- Remove src/electron-compat.ts and script/prepend-electron-shim.ts (no longer needed)
- Update src/electron-compat.test.ts to assert 0 top-level globalThis.Bun destructures
Verification: grep -c '} = globalThis.Bun;' dist/index.js → 0 (was 25)
All 5921 tests pass (1 pre-existing timeout failure unrelated to this change).
Fixes#3797