diff --git a/hooks/hooks.json b/hooks/hooks.json index 17e0ac87b..2533e92d1 100644 --- a/hooks/hooks.json +++ b/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh" + "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start" } ] } diff --git a/hooks/run-hook.cmd b/hooks/run-hook.cmd index b2a8b3acc..636f4acb5 100755 --- a/hooks/run-hook.cmd +++ b/hooks/run-hook.cmd @@ -1,7 +1,7 @@ : << 'CMDBLOCK' @echo off REM ============================================================================ -REM DEPRECATED: This polyglot wrapper is no longer used as of Claude Code 2.1.x +REM Polyglot wrapper to run .sh scripts cross-platform REM ============================================================================ REM REM Claude Code 2.1.x changed the Windows execution model for hooks: @@ -18,26 +18,40 @@ REM became: REM bash "run-hook.cmd" session-start.sh REM ...and bash cannot execute a .cmd file. REM -REM The fix: hooks.json now calls session-start.sh directly. Claude Code 2.1.x -REM handles the bash invocation automatically on Windows. +REM Solution: Pass script names WITHOUT the .sh suffix in hooks.json, and +REM auto-append .sh inside this wrapper. This avoids Claude Code's +REM .sh detection while maintaining cross-platform compatibility. REM -REM This file is kept for reference and potential backward compatibility. +REM Usage: run-hook.cmd [args...] +REM Example: run-hook.cmd session-start (will execute session-start.sh) REM ============================================================================ -REM -REM Original purpose: Polyglot wrapper to run .sh scripts cross-platform -REM Usage: run-hook.cmd [args...] -REM The script should be in the same directory as this wrapper if "%~1"=="" ( echo run-hook.cmd: missing script name >&2 exit /b 1 ) -"C:\Program Files\Git\bin\bash.exe" -l "%~dp0%~1" %2 %3 %4 %5 %6 %7 %8 %9 +set "SCRIPT_NAME=%~1" +shift +REM Auto-append .sh suffix to avoid Claude Code 2.1.x auto-detecting .sh and prepending bash +REM Disable MSYS2 path conversion to prevent corruption of forwarded arguments +set "MSYS2_ARG_CONV_EXCL=*" +REM Use CLAUDE_BASH_EXE if set, otherwise default to Git Bash +REM Note: %* is not affected by shift in batch, so we use shift inside bash -c to skip the script name +if defined CLAUDE_BASH_EXE ( + "%CLAUDE_BASH_EXE%" -l -c "shift; \"$(cygpath -u \"$CLAUDE_PLUGIN_ROOT\")/hooks/%SCRIPT_NAME%.sh\" \"$@\"" -- %* +) else ( + "C:\Program Files\Git\bin\bash.exe" -l -c "shift; \"$(cygpath -u \"$CLAUDE_PLUGIN_ROOT\")/hooks/%SCRIPT_NAME%.sh\" \"$@\"" -- %* +) exit /b CMDBLOCK # Unix shell runs from here SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_NAME="$1" +if [ -z "$SCRIPT_NAME" ]; then + echo "run-hook.cmd: missing script name" >&2 + exit 1 +fi shift -"${SCRIPT_DIR}/${SCRIPT_NAME}" "$@" +# Auto-append .sh suffix to match Windows behavior +"${SCRIPT_DIR}/${SCRIPT_NAME}.sh" "$@"