@f5xc-salesdemos/pi-tui 17.1.2 → 17.1.4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/pi-tui",
4
- "version": "17.1.2",
4
+ "version": "17.1.4",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://github.com/f5xc-salesdemos/xcsh",
7
7
  "author": "Can Boluk",
@@ -37,8 +37,8 @@
37
37
  "fmt": "biome format --write ."
38
38
  },
39
39
  "dependencies": {
40
- "@f5xc-salesdemos/pi-natives": "17.1.2",
41
- "@f5xc-salesdemos/pi-utils": "17.1.2",
40
+ "@f5xc-salesdemos/pi-natives": "17.1.4",
41
+ "@f5xc-salesdemos/pi-utils": "17.1.4",
42
42
  "marked": "^17.0"
43
43
  },
44
44
  "devDependencies": {
package/src/tui.ts CHANGED
@@ -113,7 +113,9 @@ function isTermuxSession(): boolean {
113
113
  }
114
114
 
115
115
  /** Detect terminal multiplexers where scrollback clearing and height-change redraws are hostile. */
116
- const isMultiplexer = Boolean(Bun.env.TMUX || Bun.env.STY || Bun.env.ZELLIJ);
116
+ function isMultiplexer() {
117
+ return Boolean(Bun.env.TMUX || Bun.env.STY || Bun.env.ZELLIJ);
118
+ }
117
119
 
118
120
  /**
119
121
  * Options for overlay positioning and sizing.
@@ -1011,7 +1013,7 @@ export class TUI extends Container {
1011
1013
  this.#fullRedrawCount += 1;
1012
1014
  let buffer = "\x1b[?2026h"; // Begin synchronized output
1013
1015
  // Skip clearing scrollback (3J) in multiplexers — users actively navigate scrollback history
1014
- if (clear) buffer += isMultiplexer ? "\x1b[2J\x1b[H" : "\x1b[2J\x1b[H\x1b[3J";
1016
+ if (clear) buffer += isMultiplexer() ? "\x1b[2J\x1b[H" : "\x1b[2J\x1b[H\x1b[3J";
1015
1017
  const reset = SEGMENT_RESET;
1016
1018
  for (let i = 0; i < newLines.length; i++) {
1017
1019
  if (i > 0) buffer += "\r\n";
@@ -1060,7 +1062,7 @@ export class TUI extends Container {
1060
1062
  // Height changes normally need a full re-render to keep the visible viewport aligned,
1061
1063
  // but Termux changes height when the software keyboard shows or hides.
1062
1064
  // In that environment, a full redraw causes the entire history to replay on every toggle.
1063
- if (heightChanged && !isTermuxSession() && !isMultiplexer) {
1065
+ if (heightChanged && !isTermuxSession() && !isMultiplexer()) {
1064
1066
  logRedraw(`terminal height changed (${this.#previousHeight} -> ${height})`);
1065
1067
  fullRender(true);
1066
1068
  return;
package/src/utils.ts CHANGED
@@ -24,8 +24,22 @@ export function truncateToWidth(
24
24
  return nativeTruncateToWidth(text, maxWidth, ellipsisKind, pad, getDefaultTabWidth());
25
25
  }
26
26
 
27
+ const OSC8_RE = /\x1b\]8;;([^\x07]*)\x07/g;
28
+
29
+ function fixOsc8Boundaries(lines: string[]): string[] {
30
+ let activeUrl: string | null = null;
31
+ return lines.map(line => {
32
+ const prefix = activeUrl !== null ? `\x1b]8;;${activeUrl}\x07` : "";
33
+ for (const match of line.matchAll(OSC8_RE)) {
34
+ activeUrl = match[1] === "" ? null : match[1];
35
+ }
36
+ const suffix = activeUrl !== null ? `\x1b]8;;\x07` : "";
37
+ return prefix + line + suffix;
38
+ });
39
+ }
40
+
27
41
  export function wrapTextWithAnsi(text: string, width: number): string[] {
28
- return nativeWrapTextWithAnsi(text, width, getDefaultTabWidth());
42
+ return fixOsc8Boundaries(nativeWrapTextWithAnsi(text, width, getDefaultTabWidth()));
29
43
  }
30
44
 
31
45
  export function extractSegments(