openai / openai/codex

iTerm2 viewport jumps to top when a long rich-output response completes

Open
#37,777 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI TUI
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.147.0

What subscription do you have?

API key authentication through a custom Responses-compatible provider.

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Darwin 25.5.0 arm64 arm
macOS 26.5.2 (Build 25F84)

What terminal emulator and version are you using?

iTerm2 3.6.11
TERM=xterm-256color
Terminal size during codex doctor: 80x24
No tmux, screen, or zellij

The following iTerm2 settings are already enabled:

  • Save lines to scrollback in alternate screen mode
  • Save lines to scrollback when an app status bar is present

Codex doctor report

Relevant redacted fields from codex doctor --json:

{
  "overallStatus": "warning",
  "codexVersion": "0.147.0",
  "runtime": {
    "platform": "macos-aarch64",
    "installMethod": "npm"
  },
  "terminal": {
    "name": "iTerm2",
    "version": "3.6.11",
    "term": "xterm-256color",
    "size": "80x24"
  },
  "config": {
    "terminal_resize_reflow": "enabled",
    "raw_output_mode": false
  },
  "auth": {
    "mode": "api_key",
    "provider": "custom Responses-compatible provider"
  }
}

The full report contained local filesystem paths and provider details, so those fields were redacted.

What issue are you seeing?

While a long assistant response is streaming, I scroll upward in iTerm2 to inspect earlier output. When the response finishes, the terminal viewport jumps to the top of the replayed transcript instead of preserving the position I was reading.

This is reproducible in rich output mode. It still happens when the response contains no Markdown pipe table and no Markdown hard-break trailing spaces.

The same workflow did not jump in my /raw on test.

Observed A/B results:

  • Rich output with a long Markdown pipe table: viewport jumped upward or to the top.
  • Rich output without any pipe table: viewport still jumped to the top.
  • /raw on: no viewport jump in the same manual scrolling workflow.

Thread ID: 019fe996-b190-79f0-9d87-c88516253b3c

What steps can reproduce the bug?

  1. Start Codex CLI in iTerm2 with the default rich output mode. Confirm /raw off.
  2. Ask Codex to produce a long Markdown response containing headings, blockquotes, lists, fenced code blocks, and enough lines to exceed the terminal height. Do not include a Markdown pipe table.
  3. While the response is still streaming, scroll upward and remain above the latest output.
  4. Wait for the response to finish.
  5. Observe that iTerm2 jumps to the top of the replayed transcript.
  6. Run /raw on and repeat with another long response.
  7. Observe that the viewport remains where the user was reading in the raw-mode test.

What is the expected behavior?

Completing an assistant response should preserve the user's current scrollback viewport anchor. Codex should not force the viewport to the beginning or latest output when the user has manually scrolled away from the live tail.

If transcript consolidation requires replaying rendered history, it should avoid purging terminal scrollback or should explicitly restore the previous viewport anchor afterward.

Additional information

This appears related to #22936, but that report is for WSL and Windows Terminal. This report reproduces the same symptom on macOS and iTerm2 and adds a rich-mode versus raw-mode comparison.

The rust-v0.147.0 source has two completion-time paths that can require transcript reflow:

  • chatwidget/streaming.rs:26-43 selects ConsolidationScrollbackReflow::Required when had_live_tail or completed_message_differs is true.
  • resize_reflow.rs:267-277 clears the visible screen and, outside the alternate screen, clears scrollback before resetting viewport_area.y to zero.
  • resize_reflow.rs:469-479 clears pending history, clears the terminal, and then re-inserts reflowed transcript lines.

Raw mode only forces the Markdown table tail budget to zero in streaming/controller.rs:392-404. It does not disable the completed_message_differs reflow path. Therefore, the successful raw-mode test is useful evidence but does not yet isolate whether the rich-mode reproduction came from a completion difference or a resize reflow that ran during streaming.

A useful regression test would simulate a user-scrolled viewport, finalize a long rich-output stream, and assert that transcript consolidation does not emit destructive scrollback clearing or reset the user's viewport anchor.

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

Read codex-rs/tui/src/chatwidget/streaming.rs:26-43 and codex-rs/tui/src/app/resize_reflow.rs:267-277,469-479 to trace completion-time transcript reflow and scrollback handling. Compare the rich and raw paths, then add a regression test that simulates a user-scrolled viewport while finalizing a long rich-output stream. Done means the test verifies that consolidation preserves the viewport anchor without destructive scrollback clearing.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.