Skip to content

Windows TUI: collapsed edit results with long wrapped lines can corrupt transcript layout #9302

Description

@pashifika

Description

A finalized edit result can grow from the bounded streaming preview into an arbitrarily tall collapsed card when the diff contains a small number of very long logical lines. On native Windows/ConPTY this shifts or interleaves the transcript/status rendering instead of settling to a compact … more lines result.

Reproduced on the latest release, omp/17.4.2, in Windows Terminal. The same reporter does not see the display corruption on macOS; there the result settles to the normal compact/more… presentation.

This is not specific to paths outside the project root. I reproduced it with both:

  • a cwd-relative file inside the project;
  • an absolute file under %TEMP% outside the project.

The in-project file alone is sufficient. The fixture is ASCII-only, so this does not require CJK/emoji width handling.

Steps to Reproduce

  1. Start OMP directly in Windows Terminal at approximately 120 columns, with the default collapsed tool-output state (Ctrl+O not enabled) and no terminal multiplexer.

  2. Create a file containing 12 lines of about 255 ASCII columns each:

    $tail = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" * 4
    1..12 | ForEach-Object { "ROW_{0:D2}=$tail" -f $_ } | Set-Content -Encoding utf8 long-lines.txt
  3. Send this prompt:

    Read long-lines.txt, then use one edit call to replace lines 3 through 10 with the same content plus `changed-` immediately after `=`. Do not use shell or scripts.
    
  4. Watch the edit card while its arguments stream and when the tool result finalizes.

I also reproduced the same path in an interactive ConPTY-backed child OMP session by editing eight approximately 260-column lines in one hashline PUT 3.=10 operation. The bounded streaming preview settled into a finalized edit frame exceeding 60 physical rows at 120 columns, and transcript/status rows became interleaved. Four changed long lines are enough to make the finalized collapsed frame exceed a typical viewport.

Expected Behavior

Collapsed finalized edit output should be budgeted by rendered/physical rows, as the streaming edit preview already is. Once the budget is reached, it should show the existing … (N more lines) / expansion hint without corrupting or shifting the surrounding transcript.

Actual Behavior

The streaming preview is visually bounded, but finalization replaces it with a much taller wrapped diff. A few long logical lines become dozens of physical terminal rows. On Windows/ConPTY the surrounding transcript/status display shifts or interleaves instead of remaining stable.

Setting:

tui:
  scrollbackRebuild: true

does not bound the finalized card. It only changes the later scrollback-repair policy and therefore does not address the oversized final render.

Error Output

No process error or exception. This is TUI rendering corruption.

Platform

Windows (native)

  • Windows 11 Pro, build 10.0.26200
  • Windows Terminal 1.24.11911.0
  • Direct terminal; no tmux/screen/Zellij

omp version

omp/17.4.2

Bun version

Not installed separately; reproduced with the official packaged Windows omp.exe release (bun --version is unavailable).

Provider

ChatGPT Plus/Pro (Codex). The failure is in tool-call rendering and does not appear provider-specific.

Area

TUI / Display

Additional context

The released renderer has different budgeting rules for the streaming and finalized phases:

  • packages/coding-agent/src/edit/renderer.ts::formatStreamingDiff() calls sliceStreamingDiffTail() and explicitly budgets visual rows, counting wrapped rows at the frame's inner width.
  • renderDiffSection() truncates collapsed finalized output with truncateDiffByHunk(..., PREVIEW_LIMITS.DIFF_COLLAPSED_LINES), which budgets logical diff lines.
  • renderSingleFileResult() subsequently applies wrapEditRendererLine() to every retained logical line.

Therefore the finalized collapsed height is not bounded: fewer than DIFF_COLLAPSED_LINES logical lines can expand to an arbitrary number of physical rows after wrapping. The streaming phase already contains the visual-row-aware primitive and comments describing the stale-preview/native-scrollback failure this avoids.

The same renderer.ts path is unchanged between v17.4.2 and current main at the time of filing.

Related but not duplicate:

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingplatform:windowsWindows-specificprio:p2Medium: important but not urgenttoolTool behavior and integrationstriagedtuiTerminal UI rendering and display

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions