mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
* fix(pi-tui): make the viewport anchor follow above-viewport content shifts The anchor pins a buffer row index, but an above-viewport length change shifts the content living at every index below it. The pinned window then suddenly showed content further along (visible upward creep), and the rows that slid above the window top were lost: never committed to scrollback, which holds older bytes at those indices. During streaming, every above-viewport net shrink (a finished agent row collapsing, a merged step, a spinner line disappearing) permanently swallowed that many rows, and the blank area under the input box kept growing. doRender now scores two hypotheses for such frames — window stayed put vs window content shifted by the length delta — and when the shift explains the frame strictly better, moves the anchor with the content: a pure shift re-anchors with no painting at all (the screen already shows exactly that content), and a shift with local in-window changes (spinner/timer rows) repaints the window at the shifted anchor. Commit order stays continuous, so the exactly-once scrollback invariant is preserved: no loss, no duplication. Covered by e2e case07 (above-viewport shift), which fails on the previous revision; the stale-content unit test now asserts the follow-the-content window instead of the old swallowed-row behavior. * revert(pi-tui): restore upstream differential rendering behavior The fork's viewport/scrollback rendering patches (clamping the diff to the visible viewport, viewport re-anchoring on collapse, the pinned anchor with commit-on-advance, cursor visibility guarding, and the content-shift anchor follow) accumulated interacting edge cases faster than they could be stabilized: blank screens, duplicated scrollback spans, vanished rows, and a growing blank area under the input box. Revert src/tui.ts to the upstream 0.80.2 differential rendering behavior: a change above the viewport triggers a destructive full redraw again. Verified line-by-line against the upstream source — the only remaining divergences are the TypeScript strict-mode syntax adaptations and the narrow-terminal fixes (Container width clamping and overwide-line truncation replacing the upstream crash-and-throw), which are kept. Also remove the rendering-bug e2e ledger and the shrink test suite that specified the reverted behavior, restore the pre-fork rendering tests (the transient-content test asserts the upstream full-redraw behavior again), and drop the e2e glob from the test script. Editor input-history and paste-burst changes are untouched. Known trade-off, accepted for now: the original scroll-position yank during streaming (destructive redraws emitting ESC[3J) returns; the rendering rework will restart from this clean baseline. * chore: downgrade the web thinking-effort changeset to patch
3.5 KiB
3.5 KiB
pi-tui Agent Guide
packages/pi-tui is a vendored copy of pi-tui from the upstream pi-mono project (baseline: upstream 0.80.2, see commit 7859b0af). It is no longer patched via pnpm patches — all local fixes are applied directly to the source. The differential-rendering behavior in src/tui.ts matches upstream: the fork's viewport/scrollback rendering patches were reverted; the only remaining divergences are listed below.
Local divergences from upstream (must be preserved on every re-vendor)
Never overwrite this directory wholesale when syncing from upstream. Each of the following local fixes must be re-verified after a sync; all of them are guarded by tests:
src/components/editor.ts—wordWrapLinesingle-grapheme recursion guard: when a segment cannot be split further (a single grapheme) and is wider thanmaxWidth, do not recurse (upstream recurses infinitely and overflows the stack at maxWidth=1 with CJK). The guard must be based on grapheme count (graphemeSegmenter.segment(...)), not code-unit length —grapheme.lengthmisjudges ZWJ emoji. Guarding tests: "wordWrapLine narrow width" and "Editor narrow width rendering" intest/editor.test.ts.src/tui.ts—Container.renderwidth clamp:width = Math.max(1, width)at the entry point. Guarding test: "Container width clamping" intest/tui-render.test.ts.src/tui.ts— truncate overwide lines instead of throwing:doRendertruncates overwide lines withsliceByColumnbeforeapplyLineResets; the upstream "write crash log + throw" block in the differential render path has been removed — do not bring it back when syncing. Performance constraint: the truncation check scans every line every frame, so it must go through theasciiVisibleWidthfast path inutils.tsfirst (ANSI-aware ASCII scan with an early exit past the limit) and only fall back tovisibleWidthfor non-ASCII lines;WIDTH_CACHE_SIZEis 4096 to match. Known boundary: with more than 4096 distinct non-ASCII lines the width cache FIFO thrashes (~30ms/frame); the real fix is a prepared-frame per-row cache, tracked as follow-up work. Guarding tests: "TUI overwide line handling" intest/tui-render.test.ts(exact viewport assertions) and "asciiVisibleWidth" intest/truncate-to-width.test.ts.src/components/text.ts/markdown.ts/truncated-text.ts/editor.ts— negative-widthrepeatguards: therepeatcounts for blank lines, horizontal rules, and the editor's top/bottom borders are clamped to ≥ 0 (two editor border sites; markdown's emptyLine and hr — the hr site is currently unreachable from the render entry and is purely defensive). Guarding tests: the "negative width safety" cases — Text's lives intest/tui-render.test.ts(Text has no dedicated test file), Markdown's and TruncatedText's live in their own test files; the editor's is "does not throw at zero or negative widths" inside the "Editor narrow width rendering" group intest/editor.test.ts.
Acceptance after syncing from upstream
pnpm --filter @moonshot-ai/pi-tui testmust pass in full; any failure among the guarding tests above means a local divergence was overwritten and lost.
Testing
- This package's tests run with
node --test(pnpm --filter @moonshot-ai/pi-tui test), not vitest; the rootvitest rundoes not execute them — CI covers them through the dedicatedtest-pi-tuijob in.github/workflows/ci.yml. - Prefer adding new narrow-width tests to the existing test file of the corresponding component.