fix: document the Codex PreToolUse hook as an intentional no-op - #2185
Closed
Souptik96 wants to merge 1 commit into
Closed
fix: document the Codex PreToolUse hook as an intentional no-op#2185Souptik96 wants to merge 1 commit into
Souptik96 wants to merge 1 commit into
Conversation
…hify-Labs#2165) `graphify codex install` registers `graphify hook-check` in .codex/hooks.json, and Graphify-Labs#2165 reported that as a stale/unrecognized subcommand producing a silent no-op. `hook-check` is in fact a real, deliberate no-op command: Codex Desktop rejects hookSpecificOutput.additionalContext on PreToolUse, so the Codex hook intentionally does nothing and AGENTS.md carries the always-on guidance (cli.py dispatches `hook-check`; __main__.py lists it in _silent_cmds). Repointing the installer at `hook-guard` would reintroduce the Graphify-Labs#522-class breakage on Codex Desktop, so the behavior is left as is. What actually misled the report was the documentation and the installer's own output, which both describe the Codex hook as if it enforced graph usage: - README: the Codex row claimed a PreToolUse hook that "fires before every Bash tool call, same always-on mechanism as Claude Code". It now states that the hook is a deliberate no-op, why (Codex Desktop rejects additionalContext), and that AGENTS.md is the always-on mechanism on this platform. - `_install_codex_hook` printed "PreToolUse hook registered (... hook-check)" with no hint that the entry is inert. It now says so inline. Also adds the regression guard the issue implicitly asks for: a test that reads the command out of the generated .codex/hooks.json and asserts its subcommand is one the CLI actually dispatches. A genuinely renamed/stale hook command now fails the suite instead of shipping a permanently dead hook. Note: contrary to the report, an unrecognized subcommand already exits non-zero (`graphify totally-bogus-subcommand` -> "error: unknown command", exit 1), so no change was needed there.
Collaborator
|
Thanks @Souptik96. Shipped in v0.9.27 (cherry-picked to v8). Closed-unmerged here, but it's in the release: https://github.com/Graphify-Labs/graphify/releases/tag/v0.9.27 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2165
What I found (the report's diagnosis is not quite right)
hook-checkis a real command, and its no-op behavior is deliberate — not a stalesubcommand falling through. Verified against
v8(0.9.26):graphify/cli.pydispatches it explicitly, with the reason inline:"Codex Desktop rejects hookSpecificOutput.additionalContext on PreToolUse. Keep this as a
cross-platform no-op so installed hooks never break Bash tool calls. Graph guidance reaches
the agent via AGENTS.md / skill instead."
graphify/__main__.pylistshook-checkin_silent_cmds("runs on every editor tool useand must be silent"), and CHANGELOG has a past fix specifically for its silence.
__main__.pyalso states the split directly: "Claude Code accepts additionalContext onPreToolUse (Codex Desktop does not — that path stays a no-op via
hook-check)."Two of the report's other points also don't reproduce on 0.9.26:
So an unrecognized subcommand already exits non-zero;
hook-checkreturning instantlywith exit 0 is it working as designed, not falling through. And because
hook-checknever reads stdin, it can't hang the wayhook-guarddoes — so the missingtimeoutfield isn't a hazard on this entry.I therefore did not repoint the Codex installer at
hook-guard. That's what the issuesuggests, but
hook-guardemitsadditionalContext, which is exactly what Codex Desktoprejects — it would reintroduce the #522-class breakage this no-op exists to avoid.
The real problem: the docs and the installer over-promise
What legitimately misleads users (and produced this report) is that both the README and the
installer's own output describe the Codex hook as if it enforced graph usage:
mechanism as Claude Code" — it is not the same mechanism; on Codex the hook is inert and
AGENTS.mddoes the work. Now stated accurately, with the reason._install_codex_hookprintedPreToolUse hook registered (... hook-check)with no hintthe entry is intentionally inert. It now says so.
Plus the guard the issue implicitly asks for
New test
test_codex_hook_command_is_a_real_cli_subcommandreads the command back out of thegenerated
.codex/hooks.jsonand asserts its subcommand is one the CLI actually dispatches.If a hook command is ever renamed out from under an installer, the suite fails instead of
shipping a permanently dead hook.
Verified it actually catches that (temporarily pointed the installer at
hook-check-BOGUS):Testing
Real installer output after the change:
On those 12 failures — they are pre-existing on Windows, not caused by this PR. My
baseline
uv run pytest tests/ -qon unmodifiedv8(66d8110) gives 45 failed, 3578passed, 15 skipped, of which exactly 12 are in these four files (
test_install.py2,test_install_references.py1,test_install_roundtrip.py1,test_hooks.py8) — the same12, mostly
WinError 2/32and POSIX path-separator assertions. I did not touch them, sincethey're outside this issue's scope. I don't have a Linux/macOS box to confirm they're green
there, so please read that count in that light.