From cb0293e86c42878ee99351b249b030ce6022910c Mon Sep 17 00:00:00 2001 From: affaan Date: Tue, 30 Jun 2026 22:13:04 +0000 Subject: [PATCH] fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- pyproject.toml | 1 + scripts/hooks/plugin-hook-bootstrap.js | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8b5864258..2b7448267 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dev = [ "pytest-mock>=3.12", "ruff>=0.4", "mypy>=2.1.0", + "pyyaml>=6.0", ] [project.urls] diff --git a/scripts/hooks/plugin-hook-bootstrap.js b/scripts/hooks/plugin-hook-bootstrap.js index 7a787ec2f..fd31a6930 100644 --- a/scripts/hooks/plugin-hook-bootstrap.js +++ b/scripts/hooks/plugin-hook-bootstrap.js @@ -97,7 +97,10 @@ function findShellBinary() { windowsHide: true, timeout: 30000, }); - if (!probe.error) { + // A candidate is only usable if it both spawns AND exits cleanly. The + // Windows System32 bash.exe WSL launcher spawns without error but exits + // non-zero when no distro is installed, so !probe.error alone is not enough. + if (!probe.error && probe.status === 0) { _cachedShell = candidate; return _cachedShell; } @@ -118,7 +121,9 @@ function findBashBinary() { for (const candidate of candidates) { const probe = spawnSync(candidate, ['-c', ':'], { stdio: 'ignore', windowsHide: true, timeout: 30000 }); - if (!probe.error) { + // Require a clean exit, not just a successful spawn: the Windows System32 + // bash.exe WSL stub spawns fine but exits non-zero with no distro installed. + if (!probe.error && probe.status === 0) { _cachedBash = candidate; return _cachedBash; }