Skip to content

Allow hook additionalContext to be model-visible but hidden from TUI #21696

Open

Description

@bdteo

Problem

Codex hooks are extremely useful for temporal awareness, but the TUI currently renders every hook context entry that is injected into the model. This makes it hard to use hooks for high-value background context without also filling the visible transcript with hook cards.

Concrete example: bdteo/code-now is a small temporal-awareness plugin for Claude Code and Codex. It injects precise current time / elapsed-time context on events such as SessionStart, UserPromptSubmit, and PostToolUse.

That context is genuinely useful. In ops, DevOps, incident response, and QA work, timing often changes the answer:

  • Did this deploy finish before or after the failed request?
  • How long has a queue/pod/test run been stuck?
  • Did a verification happen immediately after a change or several minutes later?
  • Are we looking at fresh logs, stale logs, or a tool result from earlier in a long turn?
  • In QA, did a save/reload/wait happen in the intended sequence, or did timing make the result ambiguous?

So this is not a request to disable hooks or hide "noise" by losing the context. The hook output is valuable to the model. The issue is that model-visible temporal context and user-visible TUI history are currently coupled.

Current behavior

If a hook emits additionalContext, Codex injects useful context into the session, but the TUI also renders a persistent completed hook card such as:

PostToolUse hook (completed)
  hook context: [11:03:04] mcp__atme__search_mentions completed

This is especially visible with PostToolUse, because a long ops/QA turn may call many tools. The result is a transcript full of hook cards even though the user usually only needs the hook context to guide the model.

The current TUI code already has a good concept of "quiet successful hooks": fast hooks with no output can disappear. But a hook that emits context has output entries, so it becomes persistent history.

Related prior issue: #15497 discussed suppressing hook status messages in the TUI. This request is slightly different: keep hook context model-visible while allowing it to be TUI-hidden.

Desired behavior

Please add a supported way for hook authors/users to say:

inject this hook output into the model/session context, but do not render it as a TUI transcript/history card.

Possible designs:

  1. Honor suppressOutput: true for TUI rendering while still recording additionalContext for the model.
  2. Add a hook output field such as visibility: "model" / display: "hidden" / tuiVisible: false.
  3. Add a hook config option such as hideInTui: true per hook handler.
  4. Add a global TUI setting such as tui.hide_hook_context = true, ideally with per-hook override support.

The important semantic distinction is:

  • additionalContext: should still affect the model.
  • TUI rendering: should be optional.

Why this matters

Temporal awareness is not just decorative. It materially improves Codex's usefulness in real operational workflows:

  • Production deploys and rollbacks
  • Kubernetes/log/queue investigations
  • CI and release verification
  • Browser QA flows where order and waiting matter
  • Long-running tool-heavy debugging sessions

CodeNow is a concrete working use case: https://github.com/bdteo/code-now

It would be great if Codex could support this class of hook cleanly: always available to the model, unobtrusive to the human operator.

Activity

  1. added
    enhancementNew feature or request
    CLIIssues related to the Codex CLI
    hooksIssues related to event hooks
    TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal display
    on May 8, 2026
  2. github-actions commented on May 8, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. 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.

  4. hangaoke1 commented on May 27, 2026

    @hangaoke1

    mark

  5. zxfxpower commented on May 27, 2026

    @zxfxpower

    I ran into the same problem with a SessionStart hook that injects a large hookSpecificOutput.additionalContext payload (from a context-management hook).

    The key distinction I need is the same one described here: keep the context model-visible, but do not render the full context payload in the TUI/history.

    Current user-visible behavior:

    SessionStart hook (completed)
      hook context: <large additionalContext payload>
    

    This becomes very noisy because the payload is meant as startup context for the model, not as something the human operator needs to read on every session start.

    I checked the current source locally and it looks like the model-visible context and TUI-visible hook output are currently coupled:

    • codex-rs/hooks/src/events/common.rs: append_additional_context pushes the text into both entries as HookOutputEntryKind::Context and additional_contexts_for_model.
    • codex-rs/hooks/src/events/session_start.rs: suppress_output is parsed but effectively ignored for SessionStart (let _ = parsed.universal.suppress_output;).
    • codex-rs/tui/src/history_cell/hook_cell.rs: quiet successful hooks only disappear when run.status == Completed && run.entries.is_empty(); since additionalContext creates a context entry, the hook becomes persistent history.
    • codex-rs/tui/src/history_cell/hook_cell.rs: completed hooks render all entries, including HookOutputEntryKind::Context as hook context:.

    So a useful fix would be to either honor suppressOutput: true for TUI/history rendering while still appending to additional_contexts_for_model, or otherwise split model-visible additionalContext from TUI-visible hook output.

    Environment where reproduced:

    • Codex CLI: codex-cli 0.134.0
    • Platform: macOS
    • Hook event: SessionStart
    • Hook output: hookSpecificOutput.additionalContext with a large model-context payload
  6. jeanmonet commented on Jun 27, 2026

    @jeanmonet

    I can reproduce the same behavior with Codex CLI 0.142.3 and context-mode 1.0.168.

    The important distinction for this use case is exactly the one described here: hook-provided additionalContext should remain model-visible, but should not be rendered in full in the TUI/operator transcript by default.

    Concrete shape:

    • a SessionStart hook returns hookSpecificOutput.additionalContext
    • Codex injects that context correctly for the model
    • the TUI also renders the full payload under SessionStart hook (completed) / hook context:

    For context-management hooks this payload is background prompt material, not human-facing output. The desired behavior would be one of:

    • hidden from the TUI by default while still injected for the model
    • or collapsed to a short receipt such as SessionStart hook context injected (N KB)
    • ideally controlled by a hook/output visibility field or config, so warning/error/stop/feedback output can remain visible while routine context injection stays quiet

    This looks related to #16933, #20766, and #25403. From an integration perspective, honoring something like suppressOutput for additionalContext, or adding an explicit hidden | collapsed | full presentation mode, would solve the issue without disabling hooks or reducing the context the model receives.

  7. cowwoc commented on Jul 8, 2026

    @cowwoc

    This seems to be fixed for me in v0.143.0. The output still renders to the user but using … +1044 lines (ctrl + t to view transcript) to hide long output.

  8. attila commented on Jul 13, 2026

    @attila

    Checking in on this after some upstream movement over the past two weeks — it looks like both staff-led attempts at this have now been shelved, and it would help downstream integrators to know the intended direction:

    The UserInstructions stack (#30138 / #30139 / #30141), which added a TUI-hidden, model-visible hook context path, was closed on 2026-07-09 ("shelving this approach for now").

    The async hook stack (#31885 / #31886 / #31887), where async additionalContext entered model history without emitting TUI HookCompleted events, was opened 2026-07-09 and closed unmerged the next day.

    On the related bug #16933, a community patch (suppressOutput: true + record_model_context_items, with test coverage) was posted on 2026-07-06 and hasn't had a response yet.

    The v0.143.0 truncation change (#31252) improves the default rendering but doesn't resolve this issue: the full context is still exposed via Ctrl+T / raw history.

    Question for maintainers: with both PR stacks shelved, is one of the approaches proposed in this issue (honoring suppressOutput for TUI rendering only, or an explicit visibility / tuiVisible field) still the intended design, or is a different mechanism planned? Even a rough signal on direction would let integrators build against the right shape instead of waiting.

    Our use case, for concreteness: we inject per-turn project conventions via UserPromptSubmit additionalContext. The injected text is written for the model, not the human — rendering it in the transcript is enough of a UX problem that we've had to park our Codex integration entirely on this issue. Happy to test a branch or adapt to whichever design you choose.

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

    TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal displayenhancementNew 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