openai / openai/codex

Hooks: expose one quiescence-aware terminal event per tool call

Open
#43,184 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

CLI enhancement hooks
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What variant of Codex are you using?

CLI (codex-cli 0.153.3; unchanged in 0.153.4)

What feature would you like to see?

Codex CLI 0.153.3 (unchanged in 0.153.4, released 2026-09-04) documents PreToolUse and PostToolUse hooks that carry a tool_use_id, but user hooks have no exact terminal notification for every tool call.

Missing public cases include: a call blocked by a PreToolUse hook (no further hook fires for that tool_use_id), cancellation without a PostToolUse payload, and interruption while a unified-exec process remains alive (no PostToolUse until a later write_stdin observes termination — a detached process may never get one). At Stop, a blocked call and a live detached command are indistinguishable to a hook that audits filesystem effects per tool_use_id.

Core already contains useful primitives (as read in the main branch around early September 2026): ToolFinishInput { call_id, outcome } with Completed, Blocked, Failed { handler_executed } and Aborted; and an asynchronous ExecCommandEnd { call_id, turn_id, process_id, ... } emitted when a host-managed process exits. ToolFinish alone is not a quiescence guarantee: dispatch may finish while a detached process remains alive.

Related issues (this request is narrower and complementary): #24907 and #34289 ask for a failure branch or failure fields on PostToolUse; #32505 asks for structured terminal status on the terminal event of nested code-mode calls; #21753 tracks parity with Claude Code hooks. None of them covers a call blocked by PreToolUse, a cancellation that produces no PostToolUse, or a detached unified-exec process still alive after dispatch — the three cases where an exactly-once terminal event with an explicit quiescence claim is needed.

Request: expose one exactly-once public hook event per tool_use_id, for example:

{
  "hook_event_name": "ToolTerminal",
  "session_id": "...",
  "turn_id": "...",
  "tool_use_id": "...",
  "outcome": "blocked|completed|failed|cancelled",
  "executed": true,
  "writers_quiesced": true,
  "quiescence_scope": "host_managed"
}

Required semantics: calls blocked before execution terminate with executed: false; detached commands terminate only after the managed process exits and output is drained; cancellation/interruption never claim quiescence while a managed process remains alive; the event is emitted exactly once per tool_use_id; unmanaged descendants are an explicit exclusion (quiescence_scope).

Suggested regression matrix: blocked PreToolUse; cancellation before/after handler start; detached completion without write_stdin; interruption while the process remains alive, followed by managed-process termination.

Motivation: a post-condition hook that snapshots a watched tree before each tool call and compares after it needs to know when a given call can no longer write. Claude Code's PostToolBatch (lists every tool_use_id of the batch, including blocked ones) and PostToolUseFailure close this gap on the other engine; a PostToolUse made universal with the fields above would be equivalent.

Additional information

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the mentioned ToolFinishInput and ExecCommandEnd primitives through PreToolUse, PostToolUse, Stop, and unified-exec handling. Use the suggested regression matrix to check blocked, cancelled, detached, and interrupted calls; done means one terminal event per tool_use_id with accurate outcome, execution, and quiescence fields.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.