Skip to content

SessionStart additionalContext does not preserve multiline hook context in TUI #24529

@sdwolf4103

Description

@sdwolf4103

What issue are you seeing?

SessionStart.hookSpecificOutput.additionalContext preserves multiline text in the model/context path, but the Codex TUI does not preserve that line structure when rendering the completed hook output in history.

The completed hook history cell appears to render each HookOutputEntry as one TUI Line. As a result, explicit newline characters inside hook output do not become separate TUI rows, making structured hook context hard to inspect.

This affects multiline output for completed hook entries such as:

  • Context
  • Warning
  • Error
  • Stop
  • Feedback

Concrete example from a local SessionStart working-memory hook:

SessionStart hook (completed)
hook context: ## Working Memory Recall

Source: Codex compaction
Scope: Durable workspace memory

### Feedback
- ...

The model receives the intended multiline content, but the visible TUI history does not render it as a readable multiline block.

What steps can reproduce the bug?

  1. Register a SessionStart hook that returns multiline additionalContext.

  2. Example hook output:

    {
      "hookSpecificOutput": {
        "hookEventName": "SessionStart",
        "additionalContext": "## Working Memory Recall\n\nSource: Codex compaction\nScope: Durable workspace memory\n\n### Feedback\n- Example preference"
      }
    }
  3. Start Codex TUI with hooks enabled.

  4. Observe the completed hook output in the transcript/history area.

Minimal behavior to inspect:

  • the model-side injection path preserves the raw multiline string
  • the TUI-side completed hook notification path does not render that structure as separate rows

What is the expected behavior?

The TUI should preserve explicit newline structure in completed hook output. For example:

• SessionStart hook (completed)
  hook context: ## Working Memory Recall

    Source: Codex compaction
    Scope: Durable workspace memory

    ### Feedback
    - Example preference

At minimum:

  • hook authors should not need to flatten multiline context purely for display
  • the TUI-visible hook output should preserve the same line structure that is sent to the model
  • hook parsing, protocol payloads, and model injection behavior should remain unchanged

Additional information

Related issue: #16486 reports the same TUI rendering issue for UserPromptSubmit.additionalContext. This issue tracks the same root cause as observed through SessionStart.additionalContext.

I tested a small TUI-only fix against current main:

8a94430bb273623be42b68f144f1ab1df343bb53

Patch direction:

  • split completed hook entry.text on \n in codex-rs/tui/src/history_cell/hook_cell.rs
  • keep the hook output prefix (hook context: , warning: , etc.) on the first physical line only
  • indent non-empty continuation lines by four spaces
  • preserve explicit blank lines
  • leave hook parsing, protocol, and model injection behavior unchanged

Patch shape:

let prefix = hook_output_prefix(entry.kind);
for (index, text) in entry.text.split('\n').enumerate() {
    if index == 0 {
        lines.push(format!("  {prefix}{text}").into());
    } else if text.is_empty() {
        lines.push("".into());
    } else {
        lines.push(format!("    {text}").into());
    }
}

Coverage added locally:

  • unit test for multiline Context, including an explicit blank line, asserting both display_lines() and raw_lines()
  • unit test for multiline Warning, asserting the prefix stays on the first line and continuation lines are indented
  • existing chatwidget snapshot updated so a SessionStart context containing session context\nsecond line renders on two rows

Local verification:

PATH=/opt/homebrew/opt/rustup/bin:$PATH just fix -p codex-tui
# exit 0

PATH=/opt/homebrew/opt/rustup/bin:$PATH CARGO_NET_GIT_FETCH_WITH_CLI=true just test -p codex-tui
# 2635 tests run: 2635 passed, 4 skipped
# bench-smoke completed with exit 0

PATH=/opt/homebrew/opt/rustup/bin:$PATH cargo insta pending-snapshots
# No pending snapshots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLITUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal displaybugSomething isn't workinghooksIssues related to event hooks

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions