@oh-my-pi/pi-tui 8.12.10 → 8.13.0

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-tui",
3
- "version": "8.12.10",
3
+ "version": "8.13.0",
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": "8.12.10",
50
+ "@oh-my-pi/pi-natives": "8.13.0",
51
51
  "@types/mime-types": "^3.0.1",
52
52
  "chalk": "^5.6.2",
53
53
  "marked": "^17.0.1",
@@ -1,9 +1,10 @@
1
1
  export type ImageProtocol = "kitty" | "iterm2" | null;
2
2
 
3
3
  export interface TerminalCapabilities {
4
- images: ImageProtocol;
5
- trueColor: boolean;
6
- hyperlinks: boolean;
4
+ readonly images: ImageProtocol;
5
+ readonly trueColor: boolean;
6
+ readonly hyperlinks: boolean;
7
+ containsImage(line: string): boolean;
7
8
  }
8
9
 
9
10
  export interface CellDimensions {
@@ -35,37 +36,72 @@ export function setCellDimensions(dims: CellDimensions): void {
35
36
  cellDimensions = dims;
36
37
  }
37
38
 
39
+ const kBaseCaps: TerminalCapabilities = {
40
+ images: null,
41
+ trueColor: false,
42
+ hyperlinks: true,
43
+ containsImage() {
44
+ return false;
45
+ },
46
+ };
47
+
48
+ function createTerminalCaps(parts: Partial<TerminalCapabilities>): TerminalCapabilities {
49
+ return Object.freeze({ ...kBaseCaps, ...parts });
50
+ }
51
+
52
+ const kKittyCaps = createTerminalCaps({
53
+ images: "kitty",
54
+ trueColor: true,
55
+ hyperlinks: true,
56
+ containsImage(line: string) {
57
+ return line.includes("\x1b_G");
58
+ },
59
+ });
60
+ const kGhosttyCaps = kKittyCaps;
61
+ const kWeztermCaps = kKittyCaps;
62
+
63
+ const kIterm2Caps = createTerminalCaps({
64
+ images: "iterm2",
65
+ trueColor: true,
66
+ hyperlinks: true,
67
+ containsImage(line: string) {
68
+ return line.includes("\x1b]1337;File=");
69
+ },
70
+ });
71
+
72
+ const kTrueColorCaps = createTerminalCaps({
73
+ ...kBaseCaps,
74
+ trueColor: true,
75
+ });
76
+
77
+ const kVscodeCaps = kTrueColorCaps;
78
+ const kAlacrittyCaps = kTrueColorCaps;
79
+
38
80
  export function detectCapabilities(): TerminalCapabilities {
39
81
  const termProgram = process.env.TERM_PROGRAM?.toLowerCase() || "";
40
82
  const term = process.env.TERM?.toLowerCase() || "";
41
83
  const colorTerm = process.env.COLORTERM?.toLowerCase() || "";
42
84
 
43
85
  if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") {
44
- return { images: "kitty", trueColor: true, hyperlinks: true };
86
+ return kKittyCaps;
45
87
  }
46
-
47
88
  if (termProgram === "ghostty" || term.includes("ghostty") || process.env.GHOSTTY_RESOURCES_DIR) {
48
- return { images: "kitty", trueColor: true, hyperlinks: true };
89
+ return kGhosttyCaps;
49
90
  }
50
-
51
91
  if (process.env.WEZTERM_PANE || termProgram === "wezterm") {
52
- return { images: "kitty", trueColor: true, hyperlinks: true };
92
+ return kWeztermCaps;
53
93
  }
54
-
55
94
  if (process.env.ITERM_SESSION_ID || termProgram === "iterm.app") {
56
- return { images: "iterm2", trueColor: true, hyperlinks: true };
95
+ return kIterm2Caps;
57
96
  }
58
-
59
97
  if (termProgram === "vscode") {
60
- return { images: null, trueColor: true, hyperlinks: true };
98
+ return kVscodeCaps;
61
99
  }
62
-
63
100
  if (termProgram === "alacritty") {
64
- return { images: null, trueColor: true, hyperlinks: true };
101
+ return kAlacrittyCaps;
65
102
  }
66
-
67
103
  const trueColor = colorTerm === "truecolor" || colorTerm === "24bit";
68
- return { images: null, trueColor, hyperlinks: true };
104
+ return trueColor ? kTrueColorCaps : kBaseCaps;
69
105
  }
70
106
 
71
107
  export function getCapabilities(): TerminalCapabilities {
package/src/tui.ts CHANGED
@@ -541,8 +541,8 @@ export class TUI extends Container {
541
541
  return result;
542
542
  }
543
543
 
544
- private containsImage(line: string): boolean {
545
- return line.includes("\x1b_G") || line.includes("\x1b]1337;File=");
544
+ static containsImage(line: string): boolean {
545
+ return getCapabilities().containsImage(line);
546
546
  }
547
547
 
548
548
  /**
@@ -764,7 +764,13 @@ export class TUI extends Container {
764
764
 
765
765
  private applyLineResets(lines: string[]): string[] {
766
766
  const reset = TUI.SEGMENT_RESET;
767
- return lines.map(line => (this.containsImage(line) ? line : line + reset));
767
+ for (let i = 0; i < lines.length; i++) {
768
+ const line = lines[i];
769
+ if (!TUI.containsImage(line)) {
770
+ lines[i] = line + reset;
771
+ }
772
+ }
773
+ return lines;
768
774
  }
769
775
 
770
776
  /**
@@ -839,7 +845,7 @@ export class TUI extends Container {
839
845
  overlayWidth: number,
840
846
  totalWidth: number,
841
847
  ): string {
842
- if (this.containsImage(baseLine)) return baseLine;
848
+ if (TUI.containsImage(baseLine)) return baseLine;
843
849
 
844
850
  // Single pass through baseLine extracts both before and after segments
845
851
  const afterStart = startCol + overlayWidth;
@@ -1081,7 +1087,7 @@ export class TUI extends Container {
1081
1087
  if (i > firstChanged) buffer += "\r\n";
1082
1088
  buffer += "\x1b[2K"; // Clear current line
1083
1089
  const line = newLines[i];
1084
- const isImageLine = this.containsImage(line);
1090
+ const isImageLine = TUI.containsImage(line);
1085
1091
  if (!isImageLine && visibleWidth(line) > width) {
1086
1092
  // Log all lines to crash file for debugging
1087
1093
  const crashLogPath = path.join(os.homedir(), ".omp", "agent", "omp-crash.log");