v1.6.28
fix(hook): cmd.exe-safe quoting for codex on Windows
Closes operator-reported regression against v1.6.25–v1.6.27:
@superbased/observer 1.6.27 + Codex CLI 0.133.0 on Windows
generates hooks.json entries wrapped in POSIX single quotes:
"command": "'C:\\Users\\...\\observer.exe' hook codex SessionStart --config 'C:\\Users\\...\\config.toml'"
Codex on Windows spawns each hook through cmd.exe, which doesn't
recognise '...' as a quoting style — the literal ' becomes part
of the argument, cmd.exe fails to find a binary whose name starts
with a single-quote, and every hook fires exit 1. PreToolUse,
PostToolUse, SessionStart, Stop, UserPromptSubmit, and
PermissionRequest were all affected.
Root cause: the v1.6.25 Git-Bash-on-Windows fix wrapped every Linux/
default registrar's binary path + --config path via
shellQuoteIfNeeded (POSIX single-quote). That was correct for
Claude Code, which always invokes hooks through Git Bash. It was
wrong for Codex, which spawns hooks through whatever the host's
default shell is (/bin/sh on Linux, cmd.exe on Windows).
Fix (internal/hook/register.go): the codex registrar now uses
a new shape-aware quoter, codexCmdQuoteIfNeeded, that picks
between POSIX single-quote (for Linux/macOS paths — codex spawns
via /bin/sh) and cmd.exe-safe double-quote (for Windows-shaped
paths — codex spawns via cmd.exe). Path-shape detection
(isWindowsPath = contains backslash) rather than runtime.GOOS
so cross-platform tests can exercise both shapes without OS
mocking. configFlagSuffix gets a Quoted variant so codex's
--config path picks up the same shape-aware quoting.
Post-fix, the operator's reported path renders as the exact
unquoted shape their workaround already showed working:
"command": "C:\\Users\\...\\observer.exe hook codex SessionStart --config C:\\Users\\...\\config.toml"
A path with spaces (e.g. C:\Program Files\observer\observer.exe)
gets cmd.exe-safe double-quoted instead of POSIX single-quoted:
"C:\Program Files\observer\observer.exe" hook codex ….
Scope of fix: codex registrar only. Claude Code stays on
shellQuoteIfNeeded (single-quote) because Claude Code always
uses Git Bash on Windows — that quoting is correct there. Cursor
stays on shellQuoteIfNeeded because the operator hasn't reported
a regression there and we don't have authoritative info on what
shell Windows-native Cursor uses to spawn hooks; if a regression
surfaces, applying the same codexCmdQuoteIfNeeded pattern is a
~5-line follow-up.
Tests: 4 new pinning the post-fix shape.
TestRegisterCodexUsesCmdSafeQuotingForWindowsBinaryPath asserts
clean Windows paths render unwrapped (no POSIX 'D:\…' wrapper).
TestRegisterCodexWrapsWindowsPathWithSpacesInDoubleQuotes
asserts Windows paths with spaces wrap in cmd.exe "…".
TestRegisterCodexLinuxPathStaysPosixQuoted confirms the Linux
single-quote behaviour is preserved (no regression for non-Windows
codex installs). TestRegisterCodexHonoursCmdSafeConfigPath
covers the --config flag path through the same quoter.
go vet ./... clean; go test ./... -count=1 51/51 green.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.6.28-linux-x64.tar.gz |
| Linux arm64 | observer-v1.6.28-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.6.28-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.6.28-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.6.28-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.6.28