@gajae-code/tui 0.18.10 → 0.18.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +3 -3
- package/src/tui.ts +27 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.18.11] - 2026-10-12
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed the viewport going blank above the status line and input box when a tall live block (task output, streaming tool output) collapsed with `clearOnShrink` off: the TUI now replays the frame when padding to the committed frontier would leave no transcript row on screen.
|
|
10
|
+
|
|
5
11
|
## [0.18.10] - 2026-10-12
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/tui",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.11",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"fmt": "biome format --write ."
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gajae-code/natives": "0.18.
|
|
40
|
-
"@gajae-code/utils": "0.18.
|
|
39
|
+
"@gajae-code/natives": "0.18.11",
|
|
40
|
+
"@gajae-code/utils": "0.18.11",
|
|
41
41
|
"lru-cache": "11.3.6",
|
|
42
42
|
"marked": "18.0.6"
|
|
43
43
|
},
|
package/src/tui.ts
CHANGED
|
@@ -5240,6 +5240,7 @@ export class TUI extends Container {
|
|
|
5240
5240
|
let usedWindowNormalize = false;
|
|
5241
5241
|
let stitched = false;
|
|
5242
5242
|
let frontierSpacerLineCount = 0;
|
|
5243
|
+
let strandedContractionReplay = false;
|
|
5243
5244
|
if (reusedAnchor !== null && layoutPrefixEligible && !layoutPrefixBlocked) {
|
|
5244
5245
|
const reused = this.#reuseCachedLayoutPrefix(
|
|
5245
5246
|
width,
|
|
@@ -5288,7 +5289,24 @@ export class TUI extends Container {
|
|
|
5288
5289
|
!transcriptRebuildPending &&
|
|
5289
5290
|
frontierPreviousWidth === width &&
|
|
5290
5291
|
(frontierPreviousHeight === height || this.#viewportRepaintHost());
|
|
5291
|
-
|
|
5292
|
+
// Padding to the committed frontier keeps scrollback rows from being
|
|
5293
|
+
// repainted, but when the contraction ends the transcript at or above that
|
|
5294
|
+
// frontier the padded viewport holds nothing but spacer rows. Replay the
|
|
5295
|
+
// frame instead of leaving a blank screen above the pinned component. A
|
|
5296
|
+
// pinned suffix that already fills the viewport hides the spacers, so it
|
|
5297
|
+
// keeps the frontier and its scrollback.
|
|
5298
|
+
strandedContractionReplay =
|
|
5299
|
+
preserveLiveFrontier &&
|
|
5300
|
+
!heightChanged &&
|
|
5301
|
+
frontierPreviousHeight === height &&
|
|
5302
|
+
this.overlayStack.length === 0 &&
|
|
5303
|
+
prevViewportTop > 0 &&
|
|
5304
|
+
sourceTranscriptLineCount > 0 &&
|
|
5305
|
+
sourceTranscriptLineCount <= prevViewportTop &&
|
|
5306
|
+
newLines.length < prevViewportTop + height &&
|
|
5307
|
+
newLines.length - sourceTranscriptLineCount < height;
|
|
5308
|
+
const minimumLineCount =
|
|
5309
|
+
preserveLiveFrontier && !strandedContractionReplay ? prevViewportTop + height : height;
|
|
5292
5310
|
const padded = this.#padBeforeBottomPinnedComponent(
|
|
5293
5311
|
newLines,
|
|
5294
5312
|
minimumLineCount,
|
|
@@ -5873,6 +5891,14 @@ export class TUI extends Container {
|
|
|
5873
5891
|
fullRender(true, "clearOnShrink", true);
|
|
5874
5892
|
return;
|
|
5875
5893
|
}
|
|
5894
|
+
// Default (clearOnShrink off) still replays when frontier padding would leave the
|
|
5895
|
+
// viewport with no transcript row, e.g. a tall live block collapsing back into
|
|
5896
|
+
// history. Same scrollback erase as above, for the same duplication reason.
|
|
5897
|
+
if (strandedContractionReplay) {
|
|
5898
|
+
logRedraw(`stranded contraction (prev=${this.#previousLines.length}, new=${newLines.length})`);
|
|
5899
|
+
fullRender(true, "stranded contraction", true);
|
|
5900
|
+
return;
|
|
5901
|
+
}
|
|
5876
5902
|
|
|
5877
5903
|
// Find first and last changed lines
|
|
5878
5904
|
let firstChanged = -1;
|