mirror of
https://github.com/obra/superpowers.git
synced 2026-06-11 13:19:05 +08:00
Stock Windows 10/11 ships C:\Windows\System32\bash.exe (the WSL
launcher) as the first match for `where bash`. WSL's bash cannot
execute Windows-style script paths, so when Git Bash is installed
outside the two standard system locations -- specifically the
per-user "Only for me" Git for Windows installer
(%LOCALAPPDATA%\Programs\Git) or a Scoop install
(%USERPROFILE%\scoop\apps\git\current\usr\bin) -- run-hook.cmd
silently fails: WSL prints "Windows Subsystem for Linux must be
updated", the script returns 0, and Superpowers' SessionStart
bootstrap is never injected. From the user's perspective skills
auto-trigger inconsistently or not at all, with no surfaced error.
Add explicit probes for both locations between the existing system-
wide Git for Windows checks and the `where bash` fallback. Also add
a comment to the fallback documenting the WSL-launcher trap so future
maintainers understand why the explicit probes must come first.
Verified on a Windows 11 VM (dockur/windows 11, Git Bash 2.x, Node
22):
- System Git present: existing probe still matches (no regression)
- System Git absent, per-user Git present via junction: new probe
matches, hook produces valid 6422-byte JSON, exit 0
- All Git probes absent: confirmed WSL trap fires
("Windows Subsystem for Linux must be updated") and the hook exits 0
silently, demonstrating the original bug
Existing tests/hooks/test-session-start.sh still passes on macOS (7/7).
Reported by @ytchenak in #1607.
Co-authored-by: ytchenak <ytchenak@users.noreply.github.com>
Closes #1607.
60 lines
2.1 KiB
Batchfile
Executable File
60 lines
2.1 KiB
Batchfile
Executable File
: << 'CMDBLOCK'
|
|
@echo off
|
|
REM Cross-platform polyglot wrapper for hook scripts.
|
|
REM On Windows: cmd.exe runs the batch portion, which finds and calls bash.
|
|
REM On Unix: the shell interprets this as a script (: is a no-op in bash).
|
|
REM
|
|
REM Hook scripts use extensionless filenames (e.g. "session-start" not
|
|
REM "session-start.sh") so Claude Code's Windows auto-detection -- which
|
|
REM prepends "bash" to any command containing .sh -- doesn't interfere.
|
|
REM
|
|
REM Usage: run-hook.cmd <script-name> [args...]
|
|
|
|
if "%~1"=="" (
|
|
echo run-hook.cmd: missing script name >&2
|
|
exit /b 1
|
|
)
|
|
|
|
set "HOOK_DIR=%~dp0"
|
|
|
|
REM Try Git for Windows bash in standard locations
|
|
if exist "C:\Program Files\Git\bin\bash.exe" (
|
|
"C:\Program Files\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
exit /b %ERRORLEVEL%
|
|
)
|
|
if exist "C:\Program Files (x86)\Git\bin\bash.exe" (
|
|
"C:\Program Files (x86)\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
exit /b %ERRORLEVEL%
|
|
)
|
|
REM Per-user Git for Windows installer ("Only for me" / winget user scope)
|
|
if exist "%LOCALAPPDATA%\Programs\Git\bin\bash.exe" (
|
|
"%LOCALAPPDATA%\Programs\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
exit /b %ERRORLEVEL%
|
|
)
|
|
REM Scoop user install (`scoop install git`)
|
|
if exist "%USERPROFILE%\scoop\apps\git\current\usr\bin\bash.exe" (
|
|
"%USERPROFILE%\scoop\apps\git\current\usr\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
exit /b %ERRORLEVEL%
|
|
)
|
|
|
|
REM Try bash on PATH (e.g. user-installed Git Bash, MSYS2, Cygwin). Note that
|
|
REM on stock Windows 10/11 `where bash` resolves to C:\Windows\System32\bash.exe
|
|
REM (the WSL launcher), which fails on Windows-style script paths. The explicit
|
|
REM probes above must therefore be exhausted first.
|
|
where bash >nul 2>nul
|
|
if %ERRORLEVEL% equ 0 (
|
|
bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
exit /b %ERRORLEVEL%
|
|
)
|
|
|
|
REM No bash found - exit silently rather than error
|
|
REM (plugin still works, just without SessionStart context injection)
|
|
exit /b 0
|
|
CMDBLOCK
|
|
|
|
# Unix: run the named script directly
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
SCRIPT_NAME="$1"
|
|
shift
|
|
exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
|