Problem
When using Codex hooks (Stop, UserPromptSubmit), the TUI always renders ephemeral status messages:
• Running UserPromptSubmit hook
UserPromptSubmit hook (completed)
• Running Stop hook
Stop hook (completed)
These messages are not part of the conversation history — they don't persist in the JSONL session transcript. They're purely transient TUI artifacts. But there's no way to suppress them.
What we've tried
1. suppressOutput in hook JSON output
The hook output schema defines suppress_output: bool in HookUniversalOutputWire, but every event handler explicitly discards the value:
let _ = parsed.universal.suppress_output;
So outputting {"suppressOutput": true} from a hook script is parsed correctly but has zero effect.
2. Omitting statusMessage in hooks.json
The non-interactive CLI renderer (event_processor_with_human_output.rs) correctly suppresses hooks with status_message: None via should_print_hook_started. But the TUI renders HookStarted/HookCompleted notifications regardless — the suppression logic only exists in the non-interactive path.
3. Config options
No config.toml setting exists for this. hide_agent_reasoning, tui.animations, etc. don't apply to hook messages.
Expected behavior
At least one of these should work:
suppressOutput: true in hook JSON output should suppress the TUI message (the plumbing is already there — just needs to be wired up)
statusMessage: null (omitted) in hooks.json should suppress the "Running X hook" message in the TUI, matching the non-interactive CLI behavior
- A config option like
tui.hide_hook_status = true
Use case
We embed Codex in a terminal inside a desktop app. Hooks are used for internal status signaling (task lifecycle) and have no user-facing relevance. The status messages create visual noise that we can't control without fragile PTY output stripping.
Environment
- Codex CLI (latest)
- macOS / Linux
features.codex_hooks = true
Problem
When using Codex hooks (
Stop,UserPromptSubmit), the TUI always renders ephemeral status messages:These messages are not part of the conversation history — they don't persist in the JSONL session transcript. They're purely transient TUI artifacts. But there's no way to suppress them.
What we've tried
1.
suppressOutputin hook JSON outputThe hook output schema defines
suppress_output: boolinHookUniversalOutputWire, but every event handler explicitly discards the value:So outputting
{"suppressOutput": true}from a hook script is parsed correctly but has zero effect.2. Omitting
statusMessagein hooks.jsonThe non-interactive CLI renderer (
event_processor_with_human_output.rs) correctly suppresses hooks withstatus_message: Noneviashould_print_hook_started. But the TUI rendersHookStarted/HookCompletednotifications regardless — the suppression logic only exists in the non-interactive path.3. Config options
No
config.tomlsetting exists for this.hide_agent_reasoning,tui.animations, etc. don't apply to hook messages.Expected behavior
At least one of these should work:
suppressOutput: truein hook JSON output should suppress the TUI message (the plumbing is already there — just needs to be wired up)statusMessage: null(omitted) inhooks.jsonshould suppress the "Running X hook" message in the TUI, matching the non-interactive CLI behaviortui.hide_hook_status = trueUse case
We embed Codex in a terminal inside a desktop app. Hooks are used for internal status signaling (task lifecycle) and have no user-facing relevance. The status messages create visual noise that we can't control without fragile PTY output stripping.
Environment
features.codex_hooks = true