Skip to content

Proposal: add PreToolUse/PostToolUse lifecycle hooks to Codex hooks engine #14882

Closed as duplicate

Description

@pengjunfeng11

Summary

I'd like to propose adding first-class tool lifecycle hooks to the new hooks engine, specifically:

  • PreToolUse
  • PostToolUse

This would extend the current lifecycle coverage beyond SessionStart and Stop and make it possible to observe, validate, or block tool execution before and after a tool call runs.

I reviewed the recent hooks work in PR #13276 and built a prototype locally using the same overall architecture.

Motivation

The current lifecycle hooks cover session boundaries, but not the most important execution boundary in Codex: tool calls.

Tool-use hooks would enable workflows like:

  • validating tool arguments before execution
  • blocking risky tool invocations with feedback to the model
  • logging tool usage for project memory / learning workflows
  • post-tool verification, auditing, and automatic warnings
  • Claude-style PreToolUse / PostToolUse compatibility for users migrating workflows

Proposed design

Following the direction of the new hooks engine introduced in PR #13276, the proposal is:

  • add new hook event names:
    • PreToolUse
    • PostToolUse
  • support them in hooks.json
  • define explicit input/output schemas for both events
  • route them through the same hook engine / dispatcher / output parser path as the existing lifecycle hooks
  • emit HookStarted / HookCompleted events for these hooks as well
  • invoke them from the core tool dispatch path

Matching

Use the existing matcher-group pattern and match on tool_name, for example:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "shell_command|exec_command",
        "hooks": [
          {
            "type": "command",
            "command": "python my_pre_hook.py"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "shell_command",
        "hooks": [
          {
            "type": "command",
            "command": "python my_post_hook.py"
          }
        ]
      }
    ]
  }
}

Semantics

  • PreToolUse
    • runs before the tool executes
    • can block execution and provide feedback
  • PostToolUse
    • runs after the tool executes
    • receives execution metadata such as success, duration, and output preview

Example input fields

In the prototype, tool hook payloads include fields like:

  • sessionId
  • turnId
  • cwd
  • transcriptPath
  • model
  • permissionMode
  • callId
  • toolName
  • toolKind
  • toolInput

And for post-tool hooks additionally:

  • executed
  • success
  • durationMs
  • outputPreview

Local prototype status

I implemented this locally against the current hooks architecture and verified:

  • cargo check -p codex-core
  • cargo test -p codex-hooks
  • a focused integration test that confirms both PreToolUse and PostToolUse are actually triggered around a real shell_command

The integration test verifies that:

  • HookStarted / HookCompleted are emitted for both events
  • the hook commands are executed
  • the hook payloads contain the expected tool metadata
  • the wrapped tool still executes normally

Question

Would the maintainers be open to this feature?

I saw the contribution policy in docs/contributing.md and understand that external PRs are only accepted when invited. If this direction makes sense, I'd be happy to open a PR from my prototype branch after maintainer guidance on:

  • event naming / semantics
  • expected schema shape
  • whether PostToolUse should support blocking vs warning-only behavior
  • whether this should coexist with legacy after_tool_use hooks or replace them over time

Activity

  1. added
    enhancementNew feature or request
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 17, 2026
  2. pengjunfeng11 commented on Mar 17, 2026

    @pengjunfeng11
    Author

    Additional context: my main reason for wanting tool-use hooks is usage analysis.

    I want to track which tools I use most, which tool sequences repeat in real work, and which tools tend to be used together. I am mainly using this as a foundation for lightweight workflow analysis and continuous learning.

    A big reference for me is the everything-claude-code project. What is useful there is not just session memory, but observing tool behavior over time and learning from repeated patterns.

    That is why PreToolUse / PostToolUse matter more than session-only hooks for my use case. If I want to understand real Codex workflows, the important signals are around tool boundaries:

    • which tool was used
    • with what input
    • whether it succeeded
    • how long it took
    • what tool came next

    So for me, this feature is mainly about tool statistics and workflow learning, not just blocking or policy enforcement.

  3. added
    agentIssues related to the core agent loop
    and removed
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 17, 2026
  4. JuncongHe commented on Mar 19, 2026

    @JuncongHe

    This hook would be a very valuable addition, and a concrete use case is RTK: https://github.com/rtk-ai/rtk

    Specifically:

    • RTK rewrites common development commands to reduce LLM token consumption by roughly 60–90%.
    • RTK already supports Claude Code and OpenCode, because Claude Code provides a PreToolUse hook and OpenCode provides tool.execute.before.
    • Codex currently supports neither of these. Because of that, I previously added an experimental RTK integration that relies on Codex subprocess configuration to rewrite commands instead: feat(init): add experimental Codex adapter via subprocess-local PATH shims rtk-ai/rtk#642

    Native support for a PreToolUse-style hook in Codex would be much cleaner.

    If this is not something you plan to support, I would still appreciate guidance on whether it makes sense for me to continue maintaining the experimental RTK workaround.

  5. pengjunfeng11 commented on Mar 20, 2026

    @pengjunfeng11
    Author

    @etraut-openai I'm very excited to submit this PR!!! Could you consider opening permissions, or are there other options?

  6. who96 commented on Mar 20, 2026

    @who96

    I read the merged hooks work, the current codex-rs/hooks implementation, and the open proposals. I think the narrowest useful proposal to discuss here is smaller than a full PreToolUse + PostToolUse expansion plus a separate PermissionRequest hook.

    What seems already true:

    • the merged hooks engine already has the right shape for synchronous lifecycle hooks
    • the current Stop and UserPromptSubmit hooks already show how blocking / feedback semantics are encoded at the hook layer
    • #15211 shows that a shell-focused PreToolUse path is implementable with the current plumbing
    • #13498 is useful context, but it is an open PR aimed at broader lifecycle coverage and is explicitly narrower than the broader Claude-compatible hooks line

    If the goal is to land something practical first, the smallest cut that still looks useful to me is:

    1. add blocking PreToolUse
    2. keep the first version to shell-like tools only
    3. make it deny-only for v1
    4. defer PostToolUse, PermissionRequest, persistent allow rules, and non-shell tool coverage

    I think that version is easier to review because it fits the current hooks engine, solves an obvious use case, and keeps the schema and test surface much smaller than a combined Pre/Post/PermissionRequest feature.

    It would still cover a lot of real workflows, including the command-gating cases described in #14754, while leaving room for a later step toward #15311 if maintainers want a dedicated approval-oriented hook after PreToolUse exists.

    If this direction sounds right, I’d expect the next step to be one of:

    • evolve #15211 toward the agreed MVP shape
    • open a new invited PR with this narrower scope
    • or narrow it even further before code

    I’m not posting code here because docs/contributing.md is explicit that external code contributions are by invitation only and unsolicited PRs will be closed. I wanted to sanity-check the scope here before going further.

  7. oxysoft commented on May 8, 2026

    @oxysoft

    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.

  8. Ar9av commented on Jun 13, 2026

    @Ar9av

    For design reference: agent-manual (https://github.com/Ar9av/agent-manual) documents how Claude Code and Gemini CLI implement these hooks today.

    Claude Code fires PreToolUse before every tool call with a JSON stdin payload (session_id, transcript_path, hook_event_name, tool_name, tool_input). Exit code 2 blocks the call and sends stderr back to the model as context. PostToolUse runs after with the same fields plus tool_response. Both support a matcher field so hooks can target specific tools (e.g. only Bash, or mcp__github__*).

    Gemini CLI calls them BeforeTool and AfterTool. Same general pattern but with hook_event_name instead of event, and AfterTool can suppress the tool output from reaching the model via decision: deny — which Claude Code's PostToolUse doesn't support.

    The biggest divergence is blocking on PostToolUse/AfterTool: Claude Code treats it as observe-only; Gemini CLI lets you intercept. Worth deciding which way Codex goes before shipping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentIssues related to the core agent loopenhancementNew feature or requesthooksIssues related to event hooks

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions