@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 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.10",
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.10",
40
- "@gajae-code/utils": "0.18.10",
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
- const minimumLineCount = preserveLiveFrontier ? prevViewportTop + height : height;
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;