@oh-my-pi/pi-tui 9.1.0 → 9.1.1
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 +2 -2
- package/src/components/box.ts +23 -20
- package/src/components/markdown.ts +2 -6
- package/src/terminal-image.ts +1 -1
- package/src/tui.ts +3 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-tui",
|
|
3
|
-
"version": "9.1.
|
|
3
|
+
"version": "9.1.1",
|
|
4
4
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"bun": ">=1.3.7"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@oh-my-pi/pi-natives": "9.1.
|
|
50
|
+
"@oh-my-pi/pi-natives": "9.1.1",
|
|
51
51
|
"@types/mime-types": "^3.0.1",
|
|
52
52
|
"chalk": "^5.6.2",
|
|
53
53
|
"marked": "^17.0.1",
|
package/src/components/box.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { Component } from "../tui";
|
|
2
2
|
import { applyBackgroundToLine, visibleWidth } from "../utils";
|
|
3
3
|
|
|
4
|
+
type Cache = {
|
|
5
|
+
key: string[];
|
|
6
|
+
width: number;
|
|
7
|
+
bgSample: string | undefined;
|
|
8
|
+
result: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
4
11
|
/**
|
|
5
12
|
* Box component - a container that applies padding and background to all children
|
|
6
13
|
*/
|
|
@@ -11,10 +18,7 @@ export class Box implements Component {
|
|
|
11
18
|
private bgFn?: (text: string) => string;
|
|
12
19
|
|
|
13
20
|
// Cache for rendered output
|
|
14
|
-
private
|
|
15
|
-
private cachedChildLines?: string;
|
|
16
|
-
private cachedBgSample?: string;
|
|
17
|
-
private cachedLines?: string[];
|
|
21
|
+
private cached?: Cache;
|
|
18
22
|
|
|
19
23
|
constructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {
|
|
20
24
|
this.paddingX = paddingX;
|
|
@@ -46,10 +50,18 @@ export class Box implements Component {
|
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
private invalidateCache(): void {
|
|
49
|
-
this.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
this.cached = undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {
|
|
57
|
+
const cache = this.cached;
|
|
58
|
+
return (
|
|
59
|
+
!!cache &&
|
|
60
|
+
cache.width === width &&
|
|
61
|
+
cache.bgSample === bgSample &&
|
|
62
|
+
cache.key.length === childLines.length &&
|
|
63
|
+
cache.key.every((key, index) => key === childLines[index])
|
|
64
|
+
);
|
|
53
65
|
}
|
|
54
66
|
|
|
55
67
|
invalidate(): void {
|
|
@@ -84,14 +96,8 @@ export class Box implements Component {
|
|
|
84
96
|
const bgSample = this.bgFn ? this.bgFn("test") : undefined;
|
|
85
97
|
|
|
86
98
|
// Check cache validity
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.cachedLines &&
|
|
90
|
-
this.cachedWidth === width &&
|
|
91
|
-
this.cachedChildLines === childLinesKey &&
|
|
92
|
-
this.cachedBgSample === bgSample
|
|
93
|
-
) {
|
|
94
|
-
return this.cachedLines;
|
|
99
|
+
if (this.matchCache(width, childLines, bgSample)) {
|
|
100
|
+
return this.cached!.result;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
// Apply background and padding
|
|
@@ -113,10 +119,7 @@ export class Box implements Component {
|
|
|
113
119
|
}
|
|
114
120
|
|
|
115
121
|
// Update cache
|
|
116
|
-
this.
|
|
117
|
-
this.cachedChildLines = childLinesKey;
|
|
118
|
-
this.cachedBgSample = bgSample;
|
|
119
|
-
this.cachedLines = result;
|
|
122
|
+
this.cached = { key: childLines, width, bgSample, result };
|
|
120
123
|
|
|
121
124
|
return result;
|
|
122
125
|
}
|
|
@@ -134,7 +134,7 @@ export class Markdown implements Component {
|
|
|
134
134
|
const wrappedLines: string[] = [];
|
|
135
135
|
for (const line of renderedLines) {
|
|
136
136
|
// Skip wrapping for image protocol lines (would corrupt escape sequences)
|
|
137
|
-
if (
|
|
137
|
+
if (TERMINAL_INFO.isImageLine(line)) {
|
|
138
138
|
wrappedLines.push(line);
|
|
139
139
|
} else {
|
|
140
140
|
wrappedLines.push(...wrapTextWithAnsi(line, contentWidth));
|
|
@@ -149,7 +149,7 @@ export class Markdown implements Component {
|
|
|
149
149
|
|
|
150
150
|
for (const line of wrappedLines) {
|
|
151
151
|
// Image lines must be output raw - no margins or background
|
|
152
|
-
if (
|
|
152
|
+
if (TERMINAL_INFO.isImageLine(line)) {
|
|
153
153
|
contentLines.push(line);
|
|
154
154
|
continue;
|
|
155
155
|
}
|
|
@@ -761,10 +761,6 @@ export class Markdown implements Component {
|
|
|
761
761
|
return lines;
|
|
762
762
|
}
|
|
763
763
|
|
|
764
|
-
private containsImage(line: string): boolean {
|
|
765
|
-
return line.includes("\x1b_G") || line.includes("\x1b]1337;File=");
|
|
766
|
-
}
|
|
767
|
-
|
|
768
764
|
/**
|
|
769
765
|
* Render a mermaid image using terminal graphics protocol.
|
|
770
766
|
* Returns array of lines (image placeholder rows) or null if rendering fails.
|
package/src/terminal-image.ts
CHANGED
package/src/tui.ts
CHANGED
|
@@ -541,10 +541,6 @@ export class TUI extends Container {
|
|
|
541
541
|
return result;
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
-
static containsImage(line: string): boolean {
|
|
545
|
-
return TERMINAL_INFO.isImageLine(line);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
544
|
/**
|
|
549
545
|
* Resolve overlay layout from options.
|
|
550
546
|
* Returns { width, row, col, maxHeight } for rendering.
|
|
@@ -766,7 +762,7 @@ export class TUI extends Container {
|
|
|
766
762
|
const reset = TUI.SEGMENT_RESET;
|
|
767
763
|
for (let i = 0; i < lines.length; i++) {
|
|
768
764
|
const line = lines[i];
|
|
769
|
-
if (!
|
|
765
|
+
if (!TERMINAL_INFO.isImageLine(line)) {
|
|
770
766
|
lines[i] = line + reset;
|
|
771
767
|
}
|
|
772
768
|
}
|
|
@@ -845,7 +841,7 @@ export class TUI extends Container {
|
|
|
845
841
|
overlayWidth: number,
|
|
846
842
|
totalWidth: number,
|
|
847
843
|
): string {
|
|
848
|
-
if (
|
|
844
|
+
if (TERMINAL_INFO.isImageLine(baseLine)) return baseLine;
|
|
849
845
|
|
|
850
846
|
// Single pass through baseLine extracts both before and after segments
|
|
851
847
|
const afterStart = startCol + overlayWidth;
|
|
@@ -1087,7 +1083,7 @@ export class TUI extends Container {
|
|
|
1087
1083
|
if (i > firstChanged) buffer += "\r\n";
|
|
1088
1084
|
buffer += "\x1b[2K"; // Clear current line
|
|
1089
1085
|
const line = newLines[i];
|
|
1090
|
-
const isImageLine =
|
|
1086
|
+
const isImageLine = TERMINAL_INFO.isImageLine(line);
|
|
1091
1087
|
if (!isImageLine && visibleWidth(line) > width) {
|
|
1092
1088
|
// Log all lines to crash file for debugging
|
|
1093
1089
|
const crashLogPath = path.join(os.homedir(), ".omp", "agent", "omp-crash.log");
|