fix(tui): stabilize dynamic-height UI components to reduce jitter#1365
fix(tui): stabilize dynamic-height UI components to reduce jitter#1365liruifengv wants to merge 2 commits into
Conversation
Add FixedHeightWindow and stabilize heights of AgentGroup, Thinking, ShellRun, Todo, and ToolCall previews. Force full render on dialog/autocomplete/BTW close and AgentSwarm removal to clear scrollback residue.
🦋 Changeset detectedLatest commit: fd476e8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3282ae14fd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const window = new FixedHeightWindow({ | ||
| height: RUNNING_TAIL_LINES, | ||
| tail: true, | ||
| lines: allLines, |
There was a problem hiding this comment.
Keep finished shell output accessible
When a ! shell command finishes with more than five lines, this fixed window keeps only the tail. The status line says ctrl+o to expand, but ShellRunComponent does not implement setExpanded, and KimiTUI.toggleToolOutputExpansion() only updates transcript children that pass isExpandable, so the earlier output can no longer be viewed in the TUI; before this change the final view rendered the full formatBashOutputForDisplay output. Please either preserve the full final output or add real expansion support for this component.
Useful? React with 👍 / 👎.
| if (this.wasShowingAutocomplete && !showing) { | ||
| // Autocomplete dropdown just closed: the editor returned fewer lines, | ||
| // which would pull the footer up and leave stale rows in scrollback. | ||
| this.tui.requestRender(true); |
There was a problem hiding this comment.
Move the forced autocomplete redraw out of render
This call runs from inside CustomEditor.render(), while TUI.doRender() is already rendering the frame. requestRender(true) mutates the TUI diff state synchronously (clearing previousLines and changing previous dimensions), so on the ordinary autocomplete-close path the current render can take the first-render/full-frame path without clearing and then overwrite the scheduled forced render state, leaving the intended cleanup ineffective or duplicating the UI. Trigger the forced redraw from the close/input path after the current render instead of mutating TUI state during render.
Useful? React with 👍 / 👎.
Short thinking content (<=2 lines) was padded to a fixed 4-row skeleton, leaving trailing blank rows. Restore natural height for short content while keeping the 4-row shape for long content so live and finalized stay aligned.
Related Issue
N/A — this addresses visual jitter observed during TUI rendering without a prior issue.
Problem
Several TUI components change height during their lifecycle (start tall, then collapse). Because pi-tui re-renders the whole screen, a collapsing component shifts all subsequent content up, producing visible jitter. Examples include the thinking panel finalizing, subagent groups finishing, tool-call progress clearing on result, the todo panel clearing, and the slash-command autocomplete closing.
What changed
FixedHeightWindowprimitive so components return a stable row count across running/finished transitions.AgentGroup,ThinkingComponent,ShellRunComponent, and the Todo panel at a stable height.ToolCallComponentprogress lines to a fixed window and capped the Edit preview at args finalize (with tail mode) so long diffs do not snap on result.Checklist
gen-changesetsskill.gen-docsskill, or this PR needs no doc update. (No user-facing doc change.)