@oh-my-pi/pi-tui 16.0.0 → 16.0.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/CHANGELOG.md +11 -1
- package/package.json +3 -3
- package/src/autocomplete.ts +30 -29
- package/src/ttyid.ts +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [16.0.1] - 2026-06-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added Zellij and WezTerm pane environment fallbacks for terminal-specific session continuation when no TTY path is available.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed slash command autocomplete acceptance replacing only a stale rendered prefix, which could leave fast-typed characters before `/skills:` completions and corrupt the submitted command ([#1745](https://github.com/can1357/oh-my-pi/issues/1745)).
|
|
14
|
+
|
|
5
15
|
## [15.13.1] - 2026-06-15
|
|
6
16
|
|
|
7
17
|
### Added
|
|
@@ -382,7 +392,7 @@
|
|
|
382
392
|
|
|
383
393
|
### Changed
|
|
384
394
|
|
|
385
|
-
- Changed native-scrollback safety defaults to treat unknown POSIX, SSH, and multiplexer-shaped terminals as ED3-risk for passive rendering; checkpoint replay now requires a positive at-tail viewport proof instead of assuming prompt submit makes host scrollback safe.
|
|
395
|
+
- Changed native-scrollback safety defaults to treat unknown POSIX, SSH, and multiplexer-shaped terminals as ED3-risk for passive rendering; checkpoint replay now requires a positive at-tail viewport proof instead of assuming prompt submit makes host scrollback safe ([#1799](https://github.com/can1357/oh-my-pi/issues/1799)).
|
|
386
396
|
- Changed synchronized-output defaults to a conservative opt-in profile: DEC 2026 paint wrappers stay disabled for remote/multiplexer/VTE/unknown terminals unless explicitly forced, while the autowrap guards remain active.
|
|
387
397
|
|
|
388
398
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "16.0.
|
|
4
|
+
"version": "16.0.1",
|
|
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,8 +37,8 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-natives": "16.0.
|
|
41
|
-
"@oh-my-pi/pi-utils": "16.0.
|
|
40
|
+
"@oh-my-pi/pi-natives": "16.0.1",
|
|
41
|
+
"@oh-my-pi/pi-utils": "16.0.1",
|
|
42
42
|
"lru-cache": "11.5.1",
|
|
43
43
|
"marked": "^18.0.5"
|
|
44
44
|
},
|
package/src/autocomplete.ts
CHANGED
|
@@ -413,27 +413,39 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
413
413
|
prefix: string,
|
|
414
414
|
): { lines: string[]; cursorLine: number; cursorCol: number } {
|
|
415
415
|
const currentLine = lines[cursorLine] || "";
|
|
416
|
-
const
|
|
416
|
+
const textBeforeCursor = currentLine.slice(0, cursorCol);
|
|
417
417
|
const afterCursor = currentLine.slice(cursorCol);
|
|
418
418
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const isSlashCommand = prefix.startsWith("/") && beforePrefix.trim() === "" && !prefix.slice(1).includes("/");
|
|
422
|
-
if (isSlashCommand) {
|
|
423
|
-
// This is a command name completion
|
|
424
|
-
const newLine = `${beforePrefix}/${item.value} ${afterCursor}`;
|
|
425
|
-
const newLines = [...lines];
|
|
426
|
-
newLines[cursorLine] = newLine;
|
|
419
|
+
const slashStart = textBeforeCursor.indexOf("/");
|
|
420
|
+
const hasOnlyWhitespaceBeforeSlash = slashStart >= 0 && textBeforeCursor.slice(0, slashStart).trim() === "";
|
|
427
421
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
422
|
+
// Slash command suggestions can be accepted before the debounced refresh
|
|
423
|
+
// catches up to newly typed characters. Replace the live command token,
|
|
424
|
+
// not only the prefix captured when the suggestion list was rendered.
|
|
425
|
+
if (prefix.startsWith("/") && hasOnlyWhitespaceBeforeSlash) {
|
|
426
|
+
const slashPrefix = textBeforeCursor.slice(slashStart);
|
|
427
|
+
if (!slashPrefix.includes(" ") && !slashPrefix.slice(1).includes("/")) {
|
|
428
|
+
const beforeSlash = currentLine.slice(0, slashStart);
|
|
429
|
+
const newLine = `${beforeSlash}/${item.value} ${afterCursor}`;
|
|
430
|
+
const newLines = [...lines];
|
|
431
|
+
newLines[cursorLine] = newLine;
|
|
432
|
+
|
|
433
|
+
return {
|
|
434
|
+
lines: newLines,
|
|
435
|
+
cursorLine,
|
|
436
|
+
cursorCol: beforeSlash.length + item.value.length + 2, // +2 for "/" and space
|
|
437
|
+
};
|
|
438
|
+
}
|
|
433
439
|
}
|
|
434
440
|
|
|
441
|
+
let beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
|
|
442
|
+
|
|
435
443
|
// Check if we're completing a file attachment (prefix starts with "@")
|
|
436
444
|
if (prefix.startsWith("@")) {
|
|
445
|
+
const liveAtPrefix = this.#extractAtPrefix(textBeforeCursor);
|
|
446
|
+
if (liveAtPrefix) {
|
|
447
|
+
beforePrefix = currentLine.slice(0, cursorCol - liveAtPrefix.length);
|
|
448
|
+
}
|
|
437
449
|
// This is a file attachment completion
|
|
438
450
|
const newLine = `${beforePrefix + item.value} ${afterCursor}`;
|
|
439
451
|
const newLines = [...lines];
|
|
@@ -446,21 +458,10 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
446
458
|
};
|
|
447
459
|
}
|
|
448
460
|
|
|
449
|
-
//
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const newLine = beforePrefix + item.value + afterCursor;
|
|
454
|
-
const newLines = [...lines];
|
|
455
|
-
newLines[cursorLine] = newLine;
|
|
456
|
-
|
|
457
|
-
return {
|
|
458
|
-
lines: newLines,
|
|
459
|
-
cursorLine,
|
|
460
|
-
cursorCol: beforePrefix.length + item.value.length,
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
|
|
461
|
+
// Slash command argument and plain file path completion both fall through
|
|
462
|
+
// to the path-completion tail below — `beforePrefix` already covers the
|
|
463
|
+
// rendered prefix, which preserves earlier arguments (e.g. accepting
|
|
464
|
+
// `package.json` for `/swarm run pac<Tab>` keeps the `run` token intact).
|
|
464
465
|
// For file paths, complete the path
|
|
465
466
|
const newLine = beforePrefix + item.value + afterCursor;
|
|
466
467
|
const newLines = [...lines];
|
package/src/ttyid.ts
CHANGED
|
@@ -51,15 +51,29 @@ export function getTerminalId(): string | null {
|
|
|
51
51
|
|
|
52
52
|
// Fallback to terminal-specific env vars
|
|
53
53
|
// Prefer inner multiplexers over host terminal emulators when stdin has no TTY path.
|
|
54
|
+
const zellijPane = process.env.ZELLIJ_PANE_ID;
|
|
55
|
+
if (zellijPane) {
|
|
56
|
+
// Session names are user-chosen (`zellij -s …`) and the id is used as a
|
|
57
|
+
// breadcrumb filename — normalize path separators like the TTY branch does.
|
|
58
|
+
const zellijSession = process.env.ZELLIJ_SESSION_NAME?.replace(/[\\/]/g, "-");
|
|
59
|
+
return zellijSession ? `zellij-${zellijSession}-${zellijPane}` : `zellij-${zellijPane}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
54
62
|
const tmuxPane = process.env.TMUX_PANE;
|
|
55
63
|
if (tmuxPane) return `tmux-${tmuxPane}`;
|
|
56
64
|
|
|
57
65
|
const cmuxSurface = process.env.CMUX_SURFACE_ID;
|
|
58
66
|
if (cmuxSurface) return `cmux-${cmuxSurface}`;
|
|
59
67
|
|
|
68
|
+
// Kitty before WezTerm/others, matching terminal-capabilities.ts detection
|
|
69
|
+
// order. Inherited env makes either order wrong for some nesting; staying
|
|
70
|
+
// consistent with the capability detector keeps the two answers aligned.
|
|
60
71
|
const kittyId = process.env.KITTY_WINDOW_ID;
|
|
61
72
|
if (kittyId) return `kitty-${kittyId}`;
|
|
62
73
|
|
|
74
|
+
const weztermPane = process.env.WEZTERM_PANE;
|
|
75
|
+
if (weztermPane) return `wezterm-${weztermPane}`;
|
|
76
|
+
|
|
63
77
|
const terminalSessionId = process.env.TERM_SESSION_ID; // macOS Terminal.app
|
|
64
78
|
if (terminalSessionId) return `apple-${terminalSessionId}`;
|
|
65
79
|
|