Add a MessageDisplay hook for streamed assistant output
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 42/100
Research direction
Start by tracing the shared codex-core response-stream path and the existing Stop hook, then compare it with the app-server item/agentMessage/delta event. The work is done when a configured hook receives coalesced assistant-message updates and a guaranteed final delivery without affecting model execution, with integration coverage for the hook lifecycle.
Written by the indexing model from the issue text.
Description
What variant of Codex are you using?
Codex CLI 0.144.4, primarily the interactive TUI and codex exec. The event should be emitted from the shared codex-core response-stream path so all relevant CLI/app-server/IDE surfaces receive consistent behavior.
What feature would you like to see?
Please add a first-class MessageDisplay hook that fires while assistant text is streaming, before the existing Stop hook.
The primary use case is live local narration/TTS, but the same event also enables incremental logging, telemetry, accessibility tooling, and external display overlays without requiring an app-server client.
A minimal contract could include:
- stable session, turn, and assistant message/item identifiers;
- the assistant text observed so far (either a delta plus sequence index, or cumulative
displayed_text); - an unambiguous final-delivery flag;
- debounced/coalesced mid-stream delivery, with the final delivery guaranteed;
- observational, non-blocking execution that cannot alter model state or delay the turn;
- no streaming-path work when no matching handler is configured.
For example, the reference implementation uses cumulative text:
{
"hook_event_name": "MessageDisplay",
"session_id": "...",
"turn_id": "...",
"item_id": "...",
"displayed_text": "The response so far...",
"is_final": false
}
The precise payload should follow maintainer preference. Claude Code currently uses delta, index, and final; Qwen Code chose cumulative text plus is_final, which makes debounce/coalescing and narration consumers simpler.
Additional information
Codex hooks currently expose lifecycle/tool events and Stop, but no event during assistant-message streaming. The app-server already emits item/agentMessage/delta, so the data exists internally; using it today requires running/connecting an app-server client instead of configuring an ordinary hook.
Concrete motivator: DontSpeak provides local voice narration for coding CLIs. Claude Code can support this through its native MessageDisplay hook. I recently added the equivalent capability to Qwen Code, and it was merged on July 11, 2026.
Prior art and references:
- Claude Code MessageDisplay hook
- Qwen Code implementation, merged PR #6489
- Codex hooks documentation
- Codex app-server streaming API
- Working Codex fork/reference implementation and discussion
- Detailed design proposal
- Adjacent umbrella request: #21753. It asks for broader Claude Code hook parity but does not currently list MessageDisplay or streamed assistant output.
I am filing this issue first in accordance with the repository contribution policy and am not opening an unsolicited upstream PR. The fork is available to make the design concrete; it also contains an implementation audit identifying the process-lifetime, final-delivery, migration, metrics, and integration-test hardening that should be resolved before any upstream merge. I would be happy to adapt the design or contribute code if maintainers invite the work.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·