Files
superpowers/docs/windows/polyglot-hooks.md

310 lines
7.6 KiB
Markdown
Raw Normal View History

# Cross-Platform Polyglot Hooks
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
Superpowers plugin hooks need to work on Windows, macOS, and Linux across the
agent harnesses that support startup hooks. This document explains the
polyglot wrapper technique that makes this possible.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
## The Problem
Hook commands may run through the system's default shell:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- **Windows**: CMD.exe
- **macOS/Linux**: bash or sh
This creates several challenges:
1. **Script execution**: Windows CMD can't execute shell scripts directly.
2. **Path format**: Windows uses backslashes (`C:\path`), Unix uses forward slashes (`/path`).
3. **Environment variables**: `$VAR` syntax doesn't work in CMD.
4. **No `bash` in PATH**: Even with Git Bash installed, `bash` isn't always in the PATH when CMD runs.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
## The Solution: Polyglot `run-hook.cmd` Wrapper
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
A polyglot script is valid syntax in multiple languages simultaneously. Our
wrapper is valid in both CMD and bash. Manifests point to `run-hook.cmd` and
pass the extensionless hook script name:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```cmd
: << 'CMDBLOCK'
@echo off
if "%~1"=="" (
echo run-hook.cmd: missing script name >&2
exit /b 1
)
set "HOOK_DIR=%~dp0"
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%
)
where bash >nul 2>nul
if %ERRORLEVEL% equ 0 (
bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
exit /b %ERRORLEVEL%
)
exit /b 0
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
CMDBLOCK
# Unix: run the named script directly
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPT_NAME="$1"
shift
exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```
### How It Works
#### On Windows (CMD.exe)
1. `: << 'CMDBLOCK'` - CMD sees `:` as a label and ignores `<< 'CMDBLOCK'`.
2. `@echo off` - Suppresses command echoing.
3. The bash.exe command runs the requested hook script next to the wrapper.
4. `exit /b` - Exits the batch script, stopping CMD here.
5. Everything after `CMDBLOCK` is never reached by CMD.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
#### On Unix (bash/sh)
1. `: << 'CMDBLOCK'` - `:` is a no-op, `<< 'CMDBLOCK'` starts a heredoc.
2. Everything until `CMDBLOCK` is consumed by the heredoc and ignored.
3. `# Unix shell runs from here` - Comment.
4. The requested hook script runs directly with the Unix path.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
## File Structure
```text
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
hooks/
|-- hooks.json
|-- hooks-codex.json
|-- hooks-cursor.json
|-- run-hook.cmd
`-- session-start
```
### `hooks/hooks.json` (Claude Code)
`hooks/hooks.json` is the Claude Code manifest:
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear|compact",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start",
"async": false
}
]
}
]
}
}
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```
### `hooks/hooks-codex.json` (Codex)
`hooks/hooks-codex.json` is the Codex-specific manifest. Codex uses the
verified `${PLUGIN_ROOT}` placeholder and the `startup|resume|clear` matcher:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear",
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
"hooks": [
{
"type": "command",
"command": "\"${PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start",
"async": false
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
}
]
}
]
}
}
```
Note: The path must be quoted because plugin roots may contain spaces on
Windows, for example `C:\Program Files\...`.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
## Requirements
### Windows
- **Git for Windows** must be installed if no other Bash is available.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- Default installation path: `C:\Program Files\Git\bin\bash.exe`
- If Git is installed elsewhere, `run-hook.cmd` also tries `bash` on PATH.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Unix (macOS/Linux)
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- Standard bash or sh shell
- `run-hook.cmd` must have execute permission (`chmod +x`)
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
## Writing Cross-Platform Hook Scripts
Your actual hook logic goes in the extensionless hook script. To ensure it
works on Windows via Git Bash:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Do:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- Use pure bash builtins when possible
- Use `$(command)` instead of backticks
- Quote all variable expansions: `"$VAR"`
- Use `printf` or here-docs for output
### Avoid:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- External commands that may not be in PATH (sed, awk, grep)
- If you must use them, they're available in Git Bash but ensure PATH is set up
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Example: JSON Escaping Without sed/awk
Instead of:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```bash
escaped=$(echo "$content" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | awk '{printf "%s\\n", $0}')
```
Use pure bash:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```bash
escape_for_json() {
local input="$1"
local output=""
local i char
for (( i=0; i<${#input}; i++ )); do
char="${input:$i:1}"
case "$char" in
$'\\') output+='\\' ;;
'"') output+='\"' ;;
$'\n') output+='\n' ;;
$'\r') output+='\r' ;;
$'\t') output+='\t' ;;
*) output+="$char" ;;
esac
done
printf '%s' "$output"
}
```
## Reusable Wrapper Pattern
For plugins with multiple hooks, use the generic wrapper with the script name
as an argument:
### `run-hook.cmd`
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```cmd
: << 'CMDBLOCK'
@echo off
if "%~1"=="" (
echo run-hook.cmd: missing script name >&2
exit /b 1
)
set "HOOK_DIR=%~dp0"
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%
)
where bash >nul 2>nul
if %ERRORLEVEL% equ 0 (
bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
exit /b %ERRORLEVEL%
)
exit /b 0
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
CMDBLOCK
# Unix: run the named script directly
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
SCRIPT_NAME="$1"
shift
exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```
### Manifest using the reusable wrapper
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" validate-bash"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
}
]
}
]
}
}
```
## Troubleshooting
### "bash is not recognized"
CMD can't find bash. The wrapper checks common Git for Windows paths and then
tries `bash` on PATH. If Bash is installed elsewhere, update the path.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### "cygpath: command not found" or "dirname: command not found"
Bash isn't running in the environment you expected. Make sure the wrapper is
calling the intended Bash installation.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Path has weird `\/` in it
`${CLAUDE_PLUGIN_ROOT}` expanded to a Windows path ending with backslash, then
`/hooks/...` was appended. Route through `run-hook.cmd` so the Windows branch
uses the wrapper directory directly.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Script opens in text editor instead of running
The manifest is pointing directly to the shell script. Point to `run-hook.cmd`
instead.
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
### Works in terminal but not as hook
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
Claude Code may run hooks differently. Test by simulating the hook environment:
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```powershell
$env:CLAUDE_PLUGIN_ROOT = "C:\path\to\plugin"
cmd /c "C:\path\to\plugin\hooks\run-hook.cmd session-start"
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
```
## Related Issues
- [anthropics/claude-code#9758](https://github.com/anthropics/claude-code/issues/9758) - shell scripts open in editor on Windows
Add Windows support for plugin hooks (#134) * feat: Add Windows support for session-start hook - Create polyglot session-start.cmd that works in both CMD and bash - Update hooks.json to use the .cmd polyglot launcher - Replace sed/awk with pure bash for JSON escaping (Windows compatibility) The polyglot script uses a heredoc trick: - CMD sees the @echo off block and runs bash.exe with cygpath conversion - Bash sees a heredoc and skips to the Unix section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Add execute permission to session-start.cmd for Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Add comprehensive polyglot hooks documentation - Add docs/windows/polyglot-hooks.md explaining the cross-platform technique - Add reusable run-hook.cmd wrapper for parameterized hook execution - Document how the polyglot works in CMD vs bash - Include troubleshooting section and related GitHub issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test: Add polyglot hook test script for macOS/Linux Run ./test-polyglot.sh from repo root to verify: - Required files exist with execute permissions - Simple wrapper (session-start.cmd) produces valid JSON - Parameterized wrapper (run-hook.cmd) works - Heredoc correctly skips CMD block on Unix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use direct pipe to jq in test to avoid variable escaping issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Use single reusable run-hook.cmd for all hooks - Remove session-start.cmd in favor of run-hook.cmd - Update hooks.json to use: run-hook.cmd session-start.sh - Simplify test script to only test run-hook.cmd This makes it easy to add more hooks - just create the .sh file and add a line to hooks.json pointing to run-hook.cmd with the script name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Simplify run-hook.cmd CMD block Pass path directly to bash instead of using cygpath in a subshell. The complex quoting was causing issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Remove test-polyglot.sh Testing complete - polyglot hooks work on Windows and macOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:42:12 -08:00
- [anthropics/claude-code#3417](https://github.com/anthropics/claude-code/issues/3417) - Hooks don't work on Windows
- [anthropics/claude-code#6023](https://github.com/anthropics/claude-code/issues/6023) - CLAUDE_PROJECT_DIR not found