[Feature request] Extend PreToolUse hooks beyond Bash + implement updatedInput rewrite
Summary
The PreToolUse hook in ~/.codex/hooks.json currently fires for Bash/shell tool calls only. Two related requests that together unlock full-parity middleware integrations:
- Expand
PreToolUseto all tool calls — specificallyread_fileandgrep, which are the other high-volume tools with the highest potential to overflow context when left unconstrained (apply_patchis now fixed — see progress below) - Implement
updatedInputin the hook response — the runtime currently rejects it with"PreToolUse hook returned unsupported updatedInput". Implementing this would let hooks enforce programmatic budgets (e.g. caplimiton a file read, caphead_limiton a grep) rather than relying on model compliance
Motivation
I'm the author of squeez, an external compression middleware that integrates with Claude Code, Copilot CLI, OpenCode, Gemini CLI, and Codex CLI via their respective hook systems.
For Codex specifically, I can compress Bash output via the existing PreToolUse + PostToolUse hooks — that part works today. But read_file / grep results routinely push sessions past the context budget, and without a hook surface on those tools the only fallback is a prose hint in AGENTS.md, which the model may or may not honour.
If the hook surface expanded, middleware could uniformly enforce output-size budgets across every tool call, the same way Claude Code's PreToolUse + tool-input rewrite does today.
Progress
✅ Fixed in 0.123.0 (PR #18391, 2026-04-23)
apply_patchnow emitsPreToolUseandPostToolUsehook eventstool_namein hook stdin is now handler-supplied (no longer always"Bash")
❌ Still blocked
read_fileandgrephave noToolHandlerwithpre_tool_use_payload/post_tool_use_payload— only test files exist, no hook dispatchupdatedInputis explicitly rejected byoutput_parser.rs:
````
if output.updated_input.is_some() {
Some("PreToolUse hook returned unsupported updatedInput".to_string())
}
Suggested acceptance criteria
PreToolUsefires forread_fileandgrepin addition to Bash/shell andapply_patch- A hook emitting
{"decision":"allow","updatedInput":{...}}has the rewritten input passed to the tool - Documentation updated to reflect both
Downstream tracker
squeez CodexCliAdapter stays at BUDGET_SOFT (prose hints in AGENTS.md) until both remaining items land. Will flip to BUDGET_HARD once confirmed. Happy to test a dev branch.
Additional context
Related discussion: openai/codex#2150
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Status update — 2026-05-05
Following up with findings from a detailed audit of the upstream source and release history.
What shipped
openai/codex#18391 (merged 2026-04-22, released in 0.123.0 on 2026-04-23) fixed
apply_patch:ApplyPatchHandlernow implementspre_tool_use_payload()andpost_tool_use_payload()tool_namein hook stdin is now handler-supplied instead of always hardcoded as"Bash"".*"or"apply_patch"matchers will now fire for apply_patch callsThis is a real, meaningful improvement — thank you to @fcoury-oai and the reviewers.
What is still blocked
Two of the three asks in the original issue remain unresolved:
read_fileandgrephook surface — these tools still have noToolHandlerimplementation withpre_tool_use_payload/post_tool_use_payload. Only test files exist (read_file_tests.rs,grep_files_tests.rs); no hook dispatch for these tools.updatedInputrewrite —output_parser.rsexplicitly rejects this today:``
`if output.updated_input.is_some() {
Some("PreToolUse hook returned unsupported updatedInput".to_string())
}
{"decision":"allow","updatedInput":{...}}So a hook emitting
will produce an error, not a rewrite. This is the critical gate for hard budget enforcement on input parameters (e.g. cappinglimit` on a file read).Downstream impact
The squeez
CodexCliAdapterremains atBUDGET_SOFT— prose hints inAGENTS.md— becauseupdatedInput+read_file/grephooks are still needed to flip toBUDGET_HARD. The adapter comments have been updated to reflect the current upstream state accurately (including the 0.123.0 apply_patch win).Leaving this issue open until both remaining items land. Happy to test a dev branch when available.
Indexed this hook ticket in the umbrella tracker: #21753
Goal: collect the scattered Codex hook requests and bugs into one parity matrix for Full Claude Code Hook Parity (29+), while preserving this issue as the detailed thread for its specific behavior.
Please we need this asap
Status update — 2026-07-09
Re-audited against current
main(Codexv0.144.0, released today) by reading the shipped source directly, since I don't have a working local Codex install to test live right now (unrelated broken npm vendor binary on my end).Both blockers from the original issue appear resolved upstream
1.
updatedInputrewrite — no longer rejected forPreToolUse.updatedInputbeyond Bash: Bash-like tools,apply_patch, and MCP tools now all accept the rewrite.CoreToolRuntimenow provides a defaultpre_tool_use_payload/post_tool_use_payload/with_updated_hook_inputimplementation for every ordinary local function tool, not just the ones with bespoke wiring. Explicit exceptions are hosted tools and code-modewait/write_stdin.codex-rs/hooks/src/engine/output_parser.rs: the validation forPreToolUseonly rejectsupdatedInputwhen it's not paired withhookSpecificOutput.permissionDecision: "allow"— the exact combination the issue originally needed now round-trips cleanly. The literal error string quoted in this issue's original report ("PreToolUse hook returned unsupported updatedInput") no longer exists forPreToolUsein current source (a similarly-worded rejection still exists for the separatePermissionRequesthook type, which is a different code path).2.
read_file/grephook surface — the premise may be moot rather than fixed.I went looking for the
read_file/greptool handlers this issue originally referenced (read_file_tests.rs,grep_files_tests.rs) incodex-rs/core/src/tools/on currentmainand couldn't find them — there's no dedicatedread_fileorgrepmodel-facing tool in the current tree. File access appears to route through the shell/exec tool (hooked since day one) or through MCP servers (hooked since #20527/#23757). If those handlers existed back in April and were since removed/consolidated, or if I'm missing something, please correct me — but as far as I can tell readingmaintoday, this specific gap doesn't reproduce.What I haven't done
I have not runtime-tested this — only static-read the source. If someone can confirm live that a
PreToolUsehook withhookSpecificOutput.permissionDecision: "allow"+updatedInputactually rewrites a non-Bash/non-apply_patch/non-MCP local tool call end-to-end on a current build, that would close the loop.Downstream
@danzaio — the fix you're waiting on has very likely already shipped (0.131.0–0.133.0 range, currently at 0.144.0). Worth updating and retesting on your end.
For squeez: I'm holding off flipping
CodexCliAdapterfromBUDGET_SOFTtoBUDGET_HARDuntil I get a live confirmation (my local Codex install is broken and unrelated to this issue). Will close this out once that's confirmed, either by me or by anyone else who can verify on a working install.