Repository navigation
feat(cli): give Codex shell searches graph context through a PreToolUse hook - #2719
Merged
Merged
Conversation
DeusData
force-pushed
the
feat/codex-pretooluse-hook
branch
from
October 20, 2026 22:34
f1614ab to
d17aed2
Compare
…se hook Codex runs its hooks with the same contract as Claude Code: its shell tool is named Bash, tool_input.command is a string, and PreToolUse hookSpecificOutput additionalContext reaches the model (openai/codex hooks/src/events/ pre_tool_use.rs, core/src/hook_runtime.rs). Codex only had the SessionStart and SubagentStart reminders (#330), so its grep and rg calls never got the graph context Claude Code's searches get (#715). - config.toml: the managed block adds [[hooks.PreToolUse]] matcher = "Bash" running the same hook-augment command. The previous block (lifecycle pair only, as installs up to v0.12 wrote it) stays recognized as owned, so an upgrade replaces it in place and uninstall removes either generation. - Inline forms (#1432): Codex's inline rewrite of our PreToolUse is replaced. A user's own inline hooks.PreToolUse is kept and our block then leaves PreToolUse out, because TOML cannot hold an inline array and array-of-tables entries for the same key; install says so instead of failing. - hooks.json: the Codex-only PreToolUse Bash entry is added and removed next to the lifecycle pair, touching only the entry whose command is ours. Codex asks users to re-trust changed hook definitions (/hooks). Refs #715, #509 Signed-off-by: Martin Vogel <[email protected]>
…oolUse block config_toml_codex_accepts_v0102_managed_windows_crlf asserted that re-upserting over the v0.10.2 lifecycle-only block left the file byte-identical. That block is now the previous generation: the upsert accepts it as owned and upgrades it in place. The test now pins that upgrade (one PreToolUse table, BOM, CRLF and the surrounding tables kept) and that a second upsert is byte-identical. Refs #715 Signed-off-by: Martin Vogel <[email protected]>
DeusData
force-pushed
the
feat/codex-pretooluse-hook
branch
from
October 25, 2026 16:57
d17aed2 to
18d7273
Compare
taggedzi
pushed a commit
to taggedzi/codebase-memory-mcp
that referenced
this pull request
Oct 27, 2026
…h hooks The Codex CLI row still listed only SessionStart and SubagentStart after the PreToolUse Bash hook landed (DeusData#2719), and the hook section described only Claude Code's search context. The row now names the Codex search hook, and the section says how Codex, Copilot CLI and VS Code's Copilot runtime get search context. Refs DeusData#509 Signed-off-by: Martin Vogel <[email protected]>
DeusData
added a commit
that referenced
this pull request
Nov 4, 2026
Maintainer refresh of #1862 (persistent install-hook opt-out, direction decided in #753) onto main a5b248f. The first refresh is 2577a86 and carries the semantic fixes for shell-free Claude hooks. Textual conflicts, all resolved by keeping both sides: - src/cli/cli.h: main added CBM_CONFIG_DOC_CANDIDATES on the line where the PR added CBM_CONFIG_INSTALL_HOOKS. Both defines are kept, in alphabetical order. - src/cli/cli.c CONFIG_KEYS[]: main added the watch_non_git row where the PR added install_hooks. Main row stays first, followed by the install_hooks row. - src/cli/cli.c Codex hook install: main (#2719) declared pretool_written in front of the hooks.json branch the PR prefixed with its --no-hooks removal branch. The declaration stays first, then the PR removal branch, then main hooks.json and config.toml upsert branches unchanged. Check: for every file the PR touches, the added and removed lines of the merged tree against main equal those of the PR against its old base. No compile-level semantic conflict: no function the PR calls changed its signature, and the PR re-signs no function main calls. The new Codex PreToolUse hook from #2719 is gated by the opt-out in the next commit. Signed-off-by: Martin Vogel <[email protected]>
DeusData
added a commit
that referenced
this pull request
Nov 4, 2026
…-out #2719 added a PreToolUse Bash hook for Codex after this opt-out was written. In config.toml it lives inside the managed block, which the opt-out already removes. In hooks.json it is a separate entry beside the lifecycle pair, and the opt-out removed only the pair, so after install --no-hooks, and on every later bare install or update that respects the stored preference, our PreToolUse hook stayed registered. The --no-hooks branch now also calls cbm_remove_codex_pretool_hooks_json, the exact-command remover that uninstall uses since #2719. A PreToolUse hook the user owns is left alone. Test: cli_no_hooks_removes_codex_pretool_hook drives the real install dispatch through both hook representations. A default install writes ours beside a foreign hook; --no-hooks and a bare install with the stored preference remove ours and keep the foreign hook and the MCP entry; and --hooks restores ours. Without the fix it fails: ours is still in hooks.json after --no-hooks. Signed-off-by: Martin Vogel <[email protected]>
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.
Why
Claude Code's shell searches get graph context from the PreToolUse hook. Codex only had the SessionStart and SubagentStart reminders (#330), so its
rg/grepcalls never did (#715). Codex's hook contract matches Claude Code's for this case. In the openai/codex source:Bash, andtool_input.commandis a string (core/src/hook_runtime.rs).hookSpecificOutput.additionalContextis collected for the model (hooks/src/events/pre_tool_use.rs,hooks/schema/generated/pre-tool-use.command.output.schema.json).So
hook-augment's existing default dialect handles Codex's payload unchanged; only the installer had to wire it.What changes
[[hooks.PreToolUse]]withmatcher = "Bash", running the samehook-augmentcommand. The previous block (the lifecycle pair only, as installs up to v0.12 wrote it) stays recognized as owned, so an upgrade replaces it in place and uninstall removes either generation.hooks.PreToolUseis kept, and our block then leaves PreToolUse out, because TOML can't hold an inline array and array-of-tables entries for the same key. Install says so instead of failing.Bashentry is added and removed next to the lifecycle pair, touching only the entry whose command is ours. The shared lifecycle helper used by Qwen and others is unchanged./hooks).Proof on real output
Built binary, isolated
HOME/CODEX_HOME/cache:install -y --clients=codexBash; outputhooks: SessionStart + SubagentStart + PreToolUse BashBashpayload (session_id,turn_id, nulltranscript_path,model,permission_mode,tool_use_id)hookSpecificOutput.hookEventName = PreToolUsewith the graph symbols inadditionalContextTests
cli_codex_pretooluse_hook_lifecycle. Covers fresh install, idempotence, removal, upgrade of the exact previous block, uninstall of it, a foreign inline PreToolUse that is kept, and our own inline form being replaced.cli_hook_augment_codex_pretooluse_payload. Characterization of Codex's payload shape.cli_codex_migrates_to_single_hook_representation. Thehooks.jsonpath must now carry PreToolUse, and uninstall must leave nohook-augmentbehind.config_toml_codex_accepts_v0102_managed_windows_crlf. Re-upserting over the v0.10.2 lifecycle-only block used to leave it byte-identical. That block is now the previous generation, so the upsert accepts it as owned and upgrades it in place. The test now pins the upgrade (one PreToolUse table, BOM, CRLF and the surrounding tables kept) and that a second upsert is byte-identical.hooks.jsonentry disabled, exactlycli_codex_pretooluse_hook_lifecycle,cli_codex_migrates_to_single_hook_representationandconfig_toml_codex_accepts_v0102_managed_windows_crlffail; with the change, all pass.cli365 passed / 0 failed,config_toml_edit49 / 0,agent_clients38 / 0.Refs #715, #509