feat(kimi-code): re-baseline pi-tui on upstream v0.84.1 and add fullscreen tui_mode - #2830
Conversation
…creen tui_mode Re-baseline the vendored pi-tui fork on upstream @earendil-works/pi-tui v0.84.1, keeping all local patches: narrow-terminal hardening, processed-line render caching (re-implemented into TuiMainScreen), editor history hooks, the paste-burst fallback, and multi-root @ completion. Upstream highlights absorbed: the renderer splits into TuiMainScreen and TuiAltScreen behind a TUI interface, the Markdown component gains opt-out LaTeX rendering (disabled on the kimi-code side), paste-registry repair on delete/undo, Windows input-latency and Shift+Enter fixes, and Kitty image layout fixes. Editor.setText gains a preservePasteRegistry option so paste-marker expansion survives wholesale text replacement. New tui_mode = "fullscreen" preference mounts TuiAltScreen: the transcript lives in a primary ScrollView with follow-end, the chrome docks at the bottom, mouse selection and scrollbar come from the renderer, and full-screen viewers (tasks browser, output viewer, approval preview) swap the layout root via screen-takeover. Viewport navigation keys fall through to the focused component when the primary scroll view cannot scroll.
Bring in upstream's merged-but-unreleased changes on top of the v0.84.1 re-baseline: - Fullscreen transcript search (ctrl+shift+f, next/previous navigation) - Alternate-screen render-churn reduction (9-18x less per-frame allocation by painting full-width rows as direct line references) - Unbound single-line scroll actions (tui.altScreen.lineUp/lineDown), wired into the fork's canScroll gating like the other viewport keys - SSH-aware escape-timeout default and PI_TUI_ESC_TIMEOUT override - Search snapping and SGR-mouse fragmentation fixes; LaTeX newline argument fix Conflicts resolved by union: upstream's search/line scroll bindings stay ungated, fork's primaryScrollable guard applies to all scroll actions.
The fullscreen layout gave the transcript ScrollView its intrinsic content height as basis and let the dock participate in shrink distribution with no minSize. Once the transcript exceeded the screen, the VStack shrink pass crushed the dock to a couple of rows, and the editor (3 rows: top border / input / bottom border) lost its bottom border row to clipping. Adopt pi's sizing contract: the ScrollView starts from basis 0 and grows, the dock keeps its intrinsic height, the editor never shrinks below 3 rows, and the footer below 1. Adds a VirtualTerminal-level regression test that replays a full streaming cycle in fullscreen.
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3d388e981
ℹ️ 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".
TuiAltScreen's viewport input listener consumed FOCUS_IN/FOCUS_OUT reports. Since the renderer installs that listener at construction — before any app-level listeners — terminal focus tracking and clipboard-image hints never saw focus transitions in fullscreen mode (notification_condition = "unfocused" went blind, refocus clipboard hints stopped). Keep the selection cleanup but stop consuming, matching the main-screen fan-out. Addresses Codex review on PR #2830.
🦋 Changeset detectedLatest commit: d69db9a The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
Mouse capture in the alternate screen intercepts the terminal's native link activation, leaving OSC 8 hyperlinks (like the footer's PR link) unclickable in fullscreen. Route renderer link clicks to the app's openUrl, and on Windows feed right-clicks to the focused component as a bracketed paste read from the clipboard.
…resync - Mark user/assistant transcript messages with OSC 133 zones (start / end / final) so the fullscreen renderer's Ctrl-Shift-Up/Down prompt jumps work; GutterContainer keeps the markers at byte 0 when prefixing its gutter, and message render caches store already-marked lines. - On exit from fullscreen, preserve the frame and replay the transcript through a fresh main-screen renderer so native scrollback gets the regular inline layout (pi's "transcript" exit form). - Re-sync the OSC 9;4 progress indicator after a stop/start cycle: terminal.stop() clears it, and the cached progressActive flag used to suppress the re-send when returning from the external editor mid-turn.
…opt-out Align with the upstream pi-tui default: LaTeX math in Markdown messages renders as Unicode text. The explicit renderLatex:false we set during the re-baseline becomes a shared Markdown options helper fed by a new tui.toml preference (render_latex, default true), wired at startup and refreshed on /reload.
Drop the public tui_mode preference from tui.toml before release; the fullscreen UI is experimental, so enable it with the KIMI_CODE_TUI_FULL_SCREEN=1 env var instead. Docs move from the config-file reference to the env-vars page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2146c00e1f
ℹ️ 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".
Codex review on PR #2830: applyReloadedTuiConfig set the shared LaTeX toggle after applyTheme(), but theme application invalidates transcript components and their rebuilt Markdown children copy the options at construction — so a /reload that only flipped render_latex kept the old value until some later invalidation. Move the setter before applyTheme and pin the ordering with a test.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8397ae261
ℹ️ 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".
Codex review on PR #2830: currentTuiConfig omitted renderLatex, so saving an unrelated preference (theme/editor/upgrade/cache-hint) serialized render_latex as the default true and silently reset a user's opt-out. Carry the appState value through the shared save payload.
Tag startup_perf and exit events with the active renderer mode (regular/fullscreen) so fullscreen adoption is measurable while it is gated behind KIMI_CODE_TUI_FULL_SCREEN.
Related Issue
No linked issue — the problem is explained in the next section.
Problem
Our vendored
@moonshot-ai/pi-tuifork was snapshotted from upstream@earendil-works/pi-tui0.80.2 (2026-06-23). Upstream has since shipped v0.84.1 plus further main-branch work that we want:TUIinterface; the alternate screen brings an application-owned scrollable viewport, a layout engine (VStack/HStack/ScrollView), mouse text selection, scrollbars, and transcript search.Separately, kimi-code's inline viewport cannot offer wheel scrolling, drag selection, or in-transcript search without leaving the native-scrollback model.
What changed
pi-tui re-baseline (
packages/pi-tui)40a3d85(2026-08-11) via a three-way merge against the pristine 0.80.2 fork point. All local patches retained: narrow-terminal hardening, processed-line render caching (re-implemented into the splitTuiMainScreen), editor history hooks, the paste-burst fallback, and multi-root@completion.Editor.setText(text, { preservePasteRegistry })— upstream resets the paste registry on everysetText, which would orphan our paste-marker expansion (Ctrl-V on a paste marker).ScrollView.canScroll,TuiAltScreen.getLayoutRoot(), and viewport navigation keys now fall through to the focused component when the primary scroll view cannot scroll (so full-screen viewers keep their own PageUp/PageDown/Home/End handling).Fullscreen mode (
apps/kimi-code)tui_modepreference intui.toml:regular(default, unchanged behavior) orfullscreen. Fullscreen mountsTuiAltScreen: the transcript lives in a primaryScrollView(follow-end, transient scrollbar), the chrome docks at the bottom, mouse selection/copy comes from the renderer, and Ctrl-Shift-F opens transcript search.screen-takeoverhelper; the previous root-children snapshot trick is never painted in fullscreen.preserveScreenin fullscreen so the transcript is not replayed into the main screen on exit/entry.renderLatex: false) to keep current rendering behavior.ScrollViewstarts frombasis: 0, editorminSize: 3, footerminSize: 1) so a tall transcript cannot crush the dock and clip the editor's bottom border.Docs:
tui_modeadded to thetui.tomlreference indocs/enanddocs/zh.Verification
packages/pi-tui: 959/959 tests,tscclean (fork adapted to the repo's strict flags).apps/kimi-code: 2726/2726 tests, typecheck and oxlint clean. New coverage: renderer/layout selection,tui_modeconfig parsing, screen-takeover (regular/fullscreen/nested), paste-registry preservation, alt-screen key gating, and a VirtualTerminal-level regression test replaying a full streaming cycle in fullscreen.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.