@oh-my-pi/pi-tui 17.2.8 → 17.2.10
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 +16 -0
- package/README.md +1 -1
- package/dist/types/desktop-notify.d.ts +4 -3
- package/package.json +3 -6
- package/src/autocomplete.ts +3 -1
- package/src/components/cancellable-loader.ts +1 -1
- package/src/components/loader.ts +1 -1
- package/src/components/markdown.ts +18 -5
- package/src/desktop-notify.ts +9 -3
- package/src/terminal.ts +16 -3
- package/src/tui.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.2.10] - 2026-08-06
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed a startup crash (EIO error) in multiplexer or SSH sessions when a revoked pty leaves stdin.isTTY active.
|
|
10
|
+
- Fixed prompt autocomplete to support Windows drive-absolute paths (e.g., C:/ or C:\).
|
|
11
|
+
- Fixed desktop notifications in systemd, tmux, or SSH-attached Linux sessions when DBUS_SESSION_BUS_ADDRESS is unset.
|
|
12
|
+
- Fixed an issue where Shift+letter and shifted symbol inputs (such as capital letters, ?, and !) were silently dropped on Windows and WSL terminals using ConPTY (e.g., WezTerm).
|
|
13
|
+
|
|
14
|
+
## [17.2.9] - 2026-08-05
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Fixed table borders (and adjacent cells) inheriting an open inline-code color when a cell's content wraps mid-code-span, by terminating each wrapped cell line's SGR state before the border glyphs ([#7575](https://github.com/can1357/oh-my-pi/issues/7575)).
|
|
19
|
+
- Fixed inline images not rendering under WSL + Windows Terminal: the SIXEL capability probe gated on `process.platform === "win32"`, but WSL reports `linux`, so the probe never ran and images fell back to the text placeholder even on Sixel-capable Windows Terminal. The probe now runs on any ConPTY host (native win32 or WSL) ([#6009](https://github.com/can1357/oh-my-pi/issues/6009)).
|
|
20
|
+
|
|
5
21
|
## [17.2.5] - 2026-08-03
|
|
6
22
|
|
|
7
23
|
### Fixed
|
package/README.md
CHANGED
|
@@ -640,7 +640,7 @@ class MyComponent implements Component {
|
|
|
640
640
|
- `wrapTextWithAnsi()` preserves ANSI codes while word-wrapping and trimming line ends
|
|
641
641
|
|
|
642
642
|
```typescript
|
|
643
|
-
import chalk from "chalk";
|
|
643
|
+
import chalk from "@oh-my-pi/pi-utils/chalk";
|
|
644
644
|
|
|
645
645
|
const styled = chalk.red("Hello") + " " + chalk.blue("World");
|
|
646
646
|
const width = visibleWidth(styled); // 11 (not counting ANSI codes)
|
|
@@ -7,10 +7,11 @@ export interface DesktopNotifier {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Whether the current process can reach a freedesktop notification daemon:
|
|
10
|
-
* Linux platform
|
|
11
|
-
*
|
|
10
|
+
* Linux platform plus either a session bus address in env or the
|
|
11
|
+
* systemd user-bus socket at `$XDG_RUNTIME_DIR/bus`. Caller is still responsible for
|
|
12
|
+
* resolving a delivery binary via {@link resolveDesktopNotifier}.
|
|
12
13
|
*/
|
|
13
|
-
export declare function hasLinuxDesktopSession(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): boolean;
|
|
14
|
+
export declare function hasLinuxDesktopSession(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv, fileExists?: (path: string) => boolean): boolean;
|
|
14
15
|
/**
|
|
15
16
|
* Whether `sendNotification` should also dispatch a D-Bus toast for this
|
|
16
17
|
* terminal. Returns true only when (1) the chosen `notifyProtocol` is BEL,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "17.2.
|
|
4
|
+
"version": "17.2.10",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -37,13 +37,10 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-natives": "17.2.
|
|
41
|
-
"@oh-my-pi/pi-utils": "17.2.
|
|
42
|
-
"lru-cache": "11.5.2",
|
|
43
|
-
"marked": "^18.0.6"
|
|
40
|
+
"@oh-my-pi/pi-natives": "17.2.10",
|
|
41
|
+
"@oh-my-pi/pi-utils": "17.2.10"
|
|
44
42
|
},
|
|
45
43
|
"devDependencies": {
|
|
46
|
-
"chalk": "^5.6.2",
|
|
47
44
|
"ghostty-web": "^0.4.0"
|
|
48
45
|
},
|
|
49
46
|
"engines": {
|
package/src/autocomplete.ts
CHANGED
|
@@ -687,7 +687,9 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
687
687
|
pathPrefix.startsWith("/") ||
|
|
688
688
|
pathPrefix.startsWith("./") ||
|
|
689
689
|
pathPrefix.startsWith("../") ||
|
|
690
|
-
pathPrefix.startsWith("~/")
|
|
690
|
+
pathPrefix.startsWith("~/") ||
|
|
691
|
+
// Windows drive-absolute paths (C:/Users, C:\Users).
|
|
692
|
+
/^[A-Za-z]:[\\/]/.test(pathPrefix)
|
|
691
693
|
) {
|
|
692
694
|
return pathPrefix;
|
|
693
695
|
}
|
package/src/components/loader.ts
CHANGED
|
@@ -55,7 +55,7 @@ export class Loader extends Text {
|
|
|
55
55
|
this.start();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
render(width: number): readonly string[] {
|
|
58
|
+
override render(width: number): readonly string[] {
|
|
59
59
|
const source = super.render(width);
|
|
60
60
|
if (source !== this.#layoutSource) {
|
|
61
61
|
const paddingX = getPaddingX(1);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { LRUCache } from "
|
|
2
|
-
import {
|
|
1
|
+
import { LRUCache } from "@oh-my-pi/pi-utils/lru";
|
|
2
|
+
import {
|
|
3
|
+
Lexer,
|
|
4
|
+
Marked,
|
|
5
|
+
type Token,
|
|
6
|
+
Tokenizer,
|
|
7
|
+
type TokenizerAndRendererExtension,
|
|
8
|
+
type Tokens,
|
|
9
|
+
} from "@oh-my-pi/pi-utils/marked";
|
|
3
10
|
import { latexToBlock } from "../latex-block";
|
|
4
11
|
import { inlineMathSpanEnd, isBareMathEnvironment, latexToUnicode } from "../latex-to-unicode";
|
|
5
12
|
import type { SymbolTheme } from "../symbols";
|
|
@@ -804,11 +811,11 @@ markdownParser.use({
|
|
|
804
811
|
// (no `m` flag), and stickiness only removes the futile later attempts. The
|
|
805
812
|
// flags/anchor guard below skips any rule a future marked version changes.
|
|
806
813
|
class AnchoredAtZero extends RegExp {
|
|
807
|
-
exec(str: string): RegExpExecArray | null {
|
|
814
|
+
override exec(str: string): RegExpExecArray | null {
|
|
808
815
|
this.lastIndex = 0; // sticky matches set lastIndex; rules are shared
|
|
809
816
|
return super.exec(str);
|
|
810
817
|
}
|
|
811
|
-
test(str: string): boolean {
|
|
818
|
+
override test(str: string): boolean {
|
|
812
819
|
this.lastIndex = 0;
|
|
813
820
|
return super.test(str);
|
|
814
821
|
}
|
|
@@ -2816,7 +2823,13 @@ export class Markdown implements Component, NativeScrollbackCommittedRows, Nativ
|
|
|
2816
2823
|
while (wrapped.length > 1 && wrapped[wrapped.length - 1] === "") {
|
|
2817
2824
|
wrapped.pop();
|
|
2818
2825
|
}
|
|
2819
|
-
|
|
2826
|
+
// The native wrap deliberately leaves fg color and bold/italic open at
|
|
2827
|
+
// line ends so continuation lines can re-open them. Table rows splice
|
|
2828
|
+
// every cell line between unstyled border glyphs, so an open style
|
|
2829
|
+
// (e.g. mdCode) would bleed into the "│" and the following cells.
|
|
2830
|
+
// Terminate each line at default fg, clearing bold/italic but keeping
|
|
2831
|
+
// any ambient background (message-bg rendering) intact.
|
|
2832
|
+
return wrapped.map(line => `${line}\x1b[22m\x1b[23m\x1b[39m`);
|
|
2820
2833
|
}
|
|
2821
2834
|
|
|
2822
2835
|
/**
|
package/src/desktop-notify.ts
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
// iTerm2, WezTerm, …) keep working unchanged and the BEL emission still fires
|
|
21
21
|
// for tmux `monitor-bell`, X11 urgency hints, and audible-bell handlers.
|
|
22
22
|
|
|
23
|
+
import * as fs from "node:fs";
|
|
24
|
+
import * as path from "node:path";
|
|
23
25
|
import { $which } from "@oh-my-pi/pi-utils";
|
|
24
26
|
import type { TerminalId, TerminalNotification } from "./terminal-capabilities";
|
|
25
27
|
|
|
@@ -36,15 +38,19 @@ export interface DesktopNotifier {
|
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
40
|
* Whether the current process can reach a freedesktop notification daemon:
|
|
39
|
-
* Linux platform
|
|
40
|
-
*
|
|
41
|
+
* Linux platform plus either a session bus address in env or the
|
|
42
|
+
* systemd user-bus socket at `$XDG_RUNTIME_DIR/bus`. Caller is still responsible for
|
|
43
|
+
* resolving a delivery binary via {@link resolveDesktopNotifier}.
|
|
41
44
|
*/
|
|
42
45
|
export function hasLinuxDesktopSession(
|
|
43
46
|
platform: NodeJS.Platform = process.platform,
|
|
44
47
|
env: NodeJS.ProcessEnv = Bun.env,
|
|
48
|
+
fileExists: (path: string) => boolean = fs.existsSync,
|
|
45
49
|
): boolean {
|
|
46
50
|
if (platform !== "linux") return false;
|
|
47
|
-
|
|
51
|
+
if (env.DBUS_SESSION_BUS_ADDRESS) return true;
|
|
52
|
+
const runtimeDir = env.XDG_RUNTIME_DIR;
|
|
53
|
+
return Boolean(runtimeDir && fileExists(path.join(runtimeDir, "bus")));
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
/**
|
package/src/terminal.ts
CHANGED
|
@@ -717,10 +717,17 @@ export class ProcessTerminal implements Terminal {
|
|
|
717
717
|
// stderr-guard in pi-utils (mirrors openai/codex#24459).
|
|
718
718
|
suppressTerminalStderr();
|
|
719
719
|
|
|
720
|
-
//
|
|
720
|
+
// A multiplexer or SSH disconnect can leave isTTY true after its pty has
|
|
721
|
+
// been revoked. Raw mode is then impossible, so take the normal terminal
|
|
722
|
+
// disconnect path rather than letting Bun abort startup with EIO.
|
|
721
723
|
this.#wasRaw = process.stdin.isRaw || false;
|
|
722
724
|
if (process.stdin.setRawMode) {
|
|
723
|
-
|
|
725
|
+
try {
|
|
726
|
+
process.stdin.setRawMode(true);
|
|
727
|
+
} catch (err) {
|
|
728
|
+
this.#markTerminalDisconnected("stdin raw mode setup failed", err);
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
724
731
|
}
|
|
725
732
|
process.stdin.setEncoding("utf8");
|
|
726
733
|
process.stdin.on("end", this.#stdinEndHandler);
|
|
@@ -1100,7 +1107,13 @@ export class ProcessTerminal implements Terminal {
|
|
|
1100
1107
|
const reportedFlags = parseInt(match[1]!, 10);
|
|
1101
1108
|
this.#kittyProtocolActive = true;
|
|
1102
1109
|
setKittyProtocolActive(true);
|
|
1103
|
-
if ((
|
|
1110
|
+
if (isConPTYHosted()) {
|
|
1111
|
+
// ConPTY (native Windows and WSL) drops Shift+letter keypresses
|
|
1112
|
+
// entirely when flag 4 (report alternate keys) is set. Use flag 1
|
|
1113
|
+
// (disambiguate only), preserving flag 2 if already active.
|
|
1114
|
+
this.#kittyEnableSeq = (reportedFlags & 2) !== 0 ? "\x1b[>3u" : "\x1b[>1u";
|
|
1115
|
+
this.#safeWrite(this.#kittyEnableSeq);
|
|
1116
|
+
} else if ((reportedFlags & 2) !== 0) {
|
|
1104
1117
|
// Preserve event-type reporting already enabled by a parent app.
|
|
1105
1118
|
// Push level-2 to keep its shortcuts reporting consistently.
|
|
1106
1119
|
this.#kittyEnableSeq = "\x1b[>7u";
|
package/src/tui.ts
CHANGED
|
@@ -1670,7 +1670,10 @@ export class TUI extends Container {
|
|
|
1670
1670
|
|
|
1671
1671
|
#querySixelSupport(): void {
|
|
1672
1672
|
if (TERMINAL.imageProtocol) return;
|
|
1673
|
-
|
|
1673
|
+
// win32 native or WSL under Windows Terminal — both are ConPTY-hosted and
|
|
1674
|
+
// reach the same WT graphics negotiation. WSL reports process.platform
|
|
1675
|
+
// "linux", so a bare win32 check silently skips the probe there (#6009).
|
|
1676
|
+
if (!isConPTYHosted()) return;
|
|
1674
1677
|
if (!Bun.env.WT_SESSION) return;
|
|
1675
1678
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
1676
1679
|
|