From 807ad6f4d97c57b6b851dae6678cd0c140d9441b Mon Sep 17 00:00:00 2001 From: omartelo Date: Thu, 13 Aug 2026 10:50:36 -0300 Subject: [PATCH] fix: report from a Codex session on Windows Every hook failed there: `hook exited with code 1` on each event, plus `invalid stop hook JSON output`, because cmd.exe writes its own error to stdout and Codex reads a Stop hook's stdout as a decision. Two causes, both on this side. Codex substitutes `${KEY}` and nothing else before handing the line to a shell, so the bare $CLAUDE_PLUGIN_ROOT the Codex registration used only worked because the Unix shell expanded what Codex had left alone -- `cmd.exe /C` does not. And cmd.exe cannot execute a .sh at all. The registration now spells the braced form, the one the Claude Code registration has always used, and each hook gained a `commandWindows` handing the same script and the same argument to hooks/win-run.cmd, which finds Git Bash -- on PATH, then at its default install -- and exits 0 whether or not it does. Codex prefers `commandWindows` on Windows and ignores it elsewhere, so one registration still serves both and nothing about a Unix run changes. --- .gitattributes | 2 ++ CHANGELOG.md | 18 ++++++++++++++++++ CLAUDE.md | 1 + docs/providers.md | 12 ++++++++++++ hooks/codex-hooks.json | 27 ++++++++++++++++++--------- hooks/win-run.cmd | 13 +++++++++++++ tests/hooks.test.mjs | 28 ++++++++++++++++++++++++++++ 7 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 .gitattributes create mode 100755 hooks/win-run.cmd diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..879f00d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# cmd.exe reads a batch file line by line; keep the CRLF endings it expects. +*.cmd text eol=crlf diff --git a/CHANGELOG.md b/CHANGELOG.md index c7dab69..da9859a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- **A Codex session on Windows reports again.** Every hook failed there — + `hook exited with code 1` on each event, and `invalid stop hook JSON output` + on top of it, because cmd.exe writes its own error to stdout and Codex reads + a Stop hook's stdout as a decision. Two causes, both on this side. Codex + substitutes `${KEY}` and nothing else before handing the line to a shell, so + the bare `$CLAUDE_PLUGIN_ROOT` the Codex registration used only ever worked + because the Unix shell expanded what Codex had left alone — `cmd.exe /C` does + not, and the hook ran a path that does not exist. The registration now spells + the braced form, the one Claude Code's has always used. And cmd.exe cannot + execute a `.sh` at all, so each hook gained a `commandWindows` handing the + same script and the same argument to `hooks/win-run.cmd`, a wrapper that + finds Git Bash — on `PATH`, then at its default install — and exits 0 + whether or not it does. Codex prefers `commandWindows` on Windows and ignores + it everywhere else, so one registration still serves both, and nothing about + a Unix run changes. + ## [0.9.2] - 2026-08-12 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index 5da6912..901fe97 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,6 +13,7 @@ hooks/hooks.json # hook registration, Claude Code hooks/codex-hooks.json # hook registration, Codex hooks/crush-hooks.json # hook registration, Crush (hand-merged into crush.json) hooks/ # hook scripts ($CLAUDE_PLUGIN_ROOT/hooks/