@oh-my-pi/pi-tui 18.10.1 → 18.10.3
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 +29 -50
- package/THIRD-PARTY-NOTICES.txt +3 -3
- package/dist/types/app-keybindings.d.ts +8 -8
- package/dist/types/apps/git/diff-pane.d.ts +5 -0
- package/dist/types/apps/git/state.d.ts +11 -0
- package/dist/types/chat/assistant-message.d.ts +8 -3
- package/dist/types/chat/tool-execution.d.ts +32 -20
- package/dist/types/native/backend.d.ts +5 -4
- package/dist/types/native/blobs.d.ts +13 -1
- package/dist/types/overlays/model-browser.d.ts +6 -1
- package/dist/types/thinking.d.ts +5 -0
- package/dist/types/tools/bash.d.ts +6 -1
- package/dist/types/tools/eval.d.ts +2 -2
- package/dist/types/tools/native-view.d.ts +1 -1
- package/dist/types/tools/read.d.ts +7 -1
- package/dist/types/tools/renderer.d.ts +2 -0
- package/package.json +9 -9
- package/src/app-keybindings.ts +8 -8
- package/src/apps/git/diff-pane.ts +39 -35
- package/src/apps/git/git-tui.ts +53 -4
- package/src/apps/git/state.ts +12 -0
- package/src/chat/assistant-message.ts +27 -6
- package/src/chat/tool-execution.ts +73 -30
- package/src/native/backend.ts +13 -5
- package/src/native/blobs.ts +34 -1
- package/src/overlays/model-browser.ts +23 -1
- package/src/overlays/model-hub.ts +3 -9
- package/src/overlays/snapcompact-shape-preview.ts +13 -6
- package/src/overlays/tree-selector.ts +117 -2
- package/src/thinking.ts +9 -1
- package/src/tools/bash.ts +15 -9
- package/src/tools/eval.ts +2 -2
- package/src/tools/native-view.ts +2 -2
- package/src/tools/read.ts +12 -4
- package/src/tools/renderer.ts +2 -0
- package/src/tools/wait.ts +16 -30
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.10.3] - 2026-10-12
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Updated model picker to offer manual effort selection for unverified models instead of automatic mode
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed the `snapcompact.shape` settings preview labelling variants `5x8-sent` and repeating the first variant's sample when the frame edge differs from the variant table (Claude and GPT on Cursor; `auto` on high-resolution Claude) ([#15448](https://github.com/can1357/oh-my-pi/pull/15448) by [@will-bogusz](https://github.com/will-bogusz))
|
|
14
|
+
|
|
15
|
+
## [18.10.2] - 2026-10-12
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Added opt-in `/tree` branch navigation across visible branches and nested fork depths; bind `app.tree.previousBranch` / `app.tree.nextBranch` (e.g. to `Shift+Left` / `Shift+Right`) in `keybindings.yml` ([#12623](https://github.com/can1357/oh-my-pi/pull/12623) by [@azain47](https://github.com/azain47)).
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- The `wait` tool's native job rows (`omp.wait.job`) are a single `row`: badge, id and label, progress and clock, without the output preview or capture notice beneath
|
|
24
|
+
- The native bash run foot reads In background with a live clock (`omp.run.time` without `stopped`) while a parked job's frames stream (`details.async.state === "running"`, partial), instead of Running
|
|
25
|
+
- Native model pickers (/model, the quick switch and the advisor's) mark providers with their logo (`mark.icon: "provider:<id>"`, initials where the terminal has none), and every model row leads with its provider's mark
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
- Removed the unused `app.tree.foldOrUp` / `app.tree.unfoldOrDown` keybinding ids, which no longer did anything.
|
|
30
|
+
- Added `parksAsBackground(toolName, details)`, `asyncJobState(details)`, `isSettledJobFrame(details)` and `settleWithJobFrame(component, frame, toolCallId)` (`chat/tool-execution`): whether a returned call's card stays live for its background job's frames (`task` always; `bash` and `eval` under native rendering), the job state a frame reports, and settling the card with the job's last frame (a cancelled job keeps its output and seals as cancelled)
|
|
31
|
+
- `BashToolDetails.async.state` and `EvalToolDetails.async.state` gain `cancelled` for a job killed before it finished
|
|
32
|
+
|
|
5
33
|
## [18.10.1] - 2026-10-12
|
|
6
34
|
|
|
7
35
|
### Added
|
|
@@ -2754,53 +2782,4 @@
|
|
|
2754
2782
|
|
|
2755
2783
|
- Optimized padding operations across all components to use pre-allocated space buffer for better performance
|
|
2756
2784
|
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
### Added
|
|
2760
|
-
|
|
2761
|
-
- Added setAutocompleteMaxVisible() configuration (3-20 items)
|
|
2762
|
-
- Added image detection to terminal capabilities (containsImage method)
|
|
2763
|
-
- Added stdin monitoring to detect stalled input events and log warnings
|
|
2764
|
-
|
|
2765
|
-
### Changed
|
|
2766
|
-
|
|
2767
|
-
- Improved blockquote rendering with text wrapping in Markdown component
|
|
2768
|
-
- Restructured terminal capabilities from interface-based to class-based model
|
|
2769
|
-
- Improved table column width calculation with word-aware wrapping
|
|
2770
|
-
- Refactored text utilities to use native WASM implementations for strings >256 chars with JS fast path
|
|
2771
|
-
|
|
2772
|
-
### Fixed
|
|
2773
|
-
|
|
2774
|
-
- Simplified terminal write error handling to mark terminal as dead on any write failure
|
|
2775
|
-
- Fixed multi-line strings in renderOutputBlock causing width overflow
|
|
2776
|
-
- Fixed slash command autocomplete applying stale completion when typing quickly
|
|
2777
|
-
|
|
2778
|
-
### Removed
|
|
2779
|
-
|
|
2780
|
-
- Removed TUI layout engine exports from public API (BoxNode, ColumnNode, LayoutNode, etc.)
|
|
2781
|
-
|
|
2782
|
-
## [8.12.7] - 2026-01-29
|
|
2783
|
-
|
|
2784
|
-
### Fixed
|
|
2785
|
-
|
|
2786
|
-
- Fixed slash command autocomplete applying stale completion when typing quickly
|
|
2787
|
-
|
|
2788
|
-
## [8.4.1] - 2026-01-25
|
|
2789
|
-
|
|
2790
|
-
### Added
|
|
2791
|
-
|
|
2792
|
-
- Added fuzzy match function for autocomplete suggestions
|
|
2793
|
-
|
|
2794
|
-
## [8.4.0] - 2026-01-25
|
|
2795
|
-
|
|
2796
|
-
### Changed
|
|
2797
|
-
|
|
2798
|
-
- Added Ctrl+Backspace as a delete-word-backward keybinding and improved modified backspace matching
|
|
2799
|
-
|
|
2800
|
-
### Fixed
|
|
2801
|
-
|
|
2802
|
-
- Terminal gracefully handles write failures by marking dead instead of exiting the process
|
|
2803
|
-
- Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
|
|
2804
|
-
- Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
|
|
2805
|
-
|
|
2806
|
-
Older entries are archived in [packages/tui/CHANGELOG.md@89ad0a77d575](https://github.com/can1357/oh-my-pi/blob/89ad0a77d575f01398d3c0a57bc3a22111bef36a/packages/tui/CHANGELOG.md).
|
|
2785
|
+
Older entries are archived in [packages/tui/CHANGELOG.md@e19bb3cb2344](https://github.com/can1357/oh-my-pi/blob/e19bb3cb2344a8953dc04aa398b810230f0e24c3/packages/tui/CHANGELOG.md).
|
package/THIRD-PARTY-NOTICES.txt
CHANGED
|
@@ -79,9 +79,9 @@ uutils coreutils (https://github.com/uutils/coreutils), MIT
|
|
|
79
79
|
--------------------------------------------------------------------------------
|
|
80
80
|
Covers: base32, base64, basename, cat, cksum (shared checksum machinery),
|
|
81
81
|
b2sum, md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, comm, cp,
|
|
82
|
-
cut, date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv,
|
|
83
|
-
printenv, readlink, realpath, rm, seq, sort, stat, tac, tail, tee,
|
|
84
|
-
truncate, uname, uniq, wc, whoami, yes.
|
|
82
|
+
cut, date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv, nl, nproc,
|
|
83
|
+
paste, printenv, readlink, realpath, rm, seq, sort, stat, tac, tail, tee,
|
|
84
|
+
touch, tr, truncate, uname, uniq, wc, whoami, yes.
|
|
85
85
|
|
|
86
86
|
Copyright (c) uutils developers
|
|
87
87
|
|
|
@@ -37,8 +37,8 @@ interface AppKeybindings {
|
|
|
37
37
|
"app.session.rename": true;
|
|
38
38
|
"app.session.delete": true;
|
|
39
39
|
"app.session.deleteNoninvasive": true;
|
|
40
|
-
"app.tree.
|
|
41
|
-
"app.tree.
|
|
40
|
+
"app.tree.previousBranch": true;
|
|
41
|
+
"app.tree.nextBranch": true;
|
|
42
42
|
"app.plan.toggle": true;
|
|
43
43
|
"app.history.search": true;
|
|
44
44
|
"app.stt.pushToTalk": true;
|
|
@@ -319,13 +319,13 @@ export declare const KEYBINDINGS: {
|
|
|
319
319
|
readonly defaultKeys: "ctrl+backspace";
|
|
320
320
|
readonly description: "Delete session (non-invasive)";
|
|
321
321
|
};
|
|
322
|
-
readonly "app.tree.
|
|
323
|
-
readonly defaultKeys: [
|
|
324
|
-
readonly description: "
|
|
322
|
+
readonly "app.tree.previousBranch": {
|
|
323
|
+
readonly defaultKeys: [];
|
|
324
|
+
readonly description: "Jump to the previous branch in /tree";
|
|
325
325
|
};
|
|
326
|
-
readonly "app.tree.
|
|
327
|
-
readonly defaultKeys: [
|
|
328
|
-
readonly description: "
|
|
326
|
+
readonly "app.tree.nextBranch": {
|
|
327
|
+
readonly defaultKeys: [];
|
|
328
|
+
readonly description: "Jump to the next branch in /tree";
|
|
329
329
|
};
|
|
330
330
|
readonly "app.plan.toggle": {
|
|
331
331
|
readonly defaultKeys: "alt+shift+p";
|
|
@@ -118,6 +118,11 @@ export type PaneClick = {
|
|
|
118
118
|
} | {
|
|
119
119
|
type: "handled";
|
|
120
120
|
} | null;
|
|
121
|
+
/**
|
|
122
|
+
* The heading of one side of a media/binary change (`Before · PNG · Git LFS`):
|
|
123
|
+
* `label` plus the side's kind, shared by the ANSI pane and the native compare.
|
|
124
|
+
*/
|
|
125
|
+
export declare function assetTitle(label: string, side: FileAssetSide): string;
|
|
121
126
|
/**
|
|
122
127
|
* Scrollable diff viewport. The root component feeds it key/mouse input and
|
|
123
128
|
* composes its rendered lines into the frame.
|
|
@@ -73,11 +73,22 @@ export interface TextFileContents {
|
|
|
73
73
|
readonly newText: string;
|
|
74
74
|
readonly streamResult: DiffStreamResult;
|
|
75
75
|
}
|
|
76
|
+
/** Where one side of a change lives, so a host viewer (Tern's TSP `media` node) can load it by path. */
|
|
77
|
+
export interface MediaRef {
|
|
78
|
+
/** Absolute path of the file (repository root joined with its repository path). */
|
|
79
|
+
readonly path: string;
|
|
80
|
+
/** Git revision holding this side (`HEAD`, a sha, `:0` for the index); absent for the worktree file. */
|
|
81
|
+
readonly rev?: string;
|
|
82
|
+
}
|
|
76
83
|
/** Non-text sides rendered as previews or explicit placeholders. */
|
|
77
84
|
export interface AssetFileContents {
|
|
78
85
|
readonly kind: "asset";
|
|
79
86
|
readonly old: FileAssetSide;
|
|
80
87
|
readonly new: FileAssetSide;
|
|
88
|
+
/** Source of {@link old}; absent when that side is empty. */
|
|
89
|
+
readonly oldRef?: MediaRef;
|
|
90
|
+
/** Source of {@link new}; absent when that side is empty. */
|
|
91
|
+
readonly newRef?: MediaRef;
|
|
81
92
|
}
|
|
82
93
|
/** Loaded file content selected for text diffing or asset preview. */
|
|
83
94
|
export type FileContents = TextFileContents | AssetFileContents;
|
|
@@ -2,7 +2,7 @@ import type { AssistantMessage, ImageContent } from "@oh-my-pi/pi-ai";
|
|
|
2
2
|
import { type Component, Container } from "../tui.js";
|
|
3
3
|
import { type ImageBudget } from "../components/image.js";
|
|
4
4
|
import type { AssistantThinkingRenderer } from "./extension-types.js";
|
|
5
|
-
import type { NativeNode, NativeUiEvent } from "../native/node.js";
|
|
5
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
6
6
|
import { type CacheInvalidation } from "./cache-invalidation-marker.js";
|
|
7
7
|
import { type ServedModelMismatch } from "./served-model-marker.js";
|
|
8
8
|
import { type TranscriptStableRow } from "../chrome/transcript-container.js";
|
|
@@ -99,7 +99,7 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
99
99
|
* head's `title`. With `hideThinkingBlock` only the live head shows (collapsed)
|
|
100
100
|
* and a finished thought emits nothing.
|
|
101
101
|
*/
|
|
102
|
-
describe(): NativeNode;
|
|
102
|
+
describe(cx?: DescribeContext): NativeNode;
|
|
103
103
|
/**
|
|
104
104
|
* A TTSR rule rewound this partial answer: a native terminal dims it and
|
|
105
105
|
* tags it `↺ rewound` (the ANSI render leaves it as it stopped).
|
|
@@ -130,7 +130,12 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
130
130
|
setTableChartsVisible(visible: boolean): void;
|
|
131
131
|
/** Toggle only images produced by tool results; assistant-native images remain governed by setImagesVisible. */
|
|
132
132
|
setToolResultImagesVisible(visible: boolean): void;
|
|
133
|
-
|
|
133
|
+
/**
|
|
134
|
+
* A grouped read's result images, and `mediaPath`: the file it read that Tern's media viewer
|
|
135
|
+
* shows (read details), which a native host supporting `media` shows by path instead of the
|
|
136
|
+
* images. A media-only result (a model, a PDF) passes no images.
|
|
137
|
+
*/
|
|
138
|
+
setToolResultImages(toolCallId: string, images: ImageContent[], mediaPath?: string): void;
|
|
134
139
|
updateContent(message: AssistantMessage, opts?: {
|
|
135
140
|
transient?: boolean;
|
|
136
141
|
}): void;
|
|
@@ -17,19 +17,21 @@ export interface ToolExecutionOptions {
|
|
|
17
17
|
/** Allow the name-keyed renderer registry only when the active tool is the built-in implementation. */
|
|
18
18
|
useBuiltInRenderer?: boolean;
|
|
19
19
|
}
|
|
20
|
+
/** A tool result or progress frame as a card shows it. */
|
|
21
|
+
export interface ToolResultFrame {
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: string;
|
|
24
|
+
text?: string;
|
|
25
|
+
data?: string;
|
|
26
|
+
mimeType?: string;
|
|
27
|
+
}>;
|
|
28
|
+
details?: unknown;
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
}
|
|
20
31
|
export interface ToolExecutionHandle extends Component {
|
|
21
32
|
updateArgs(args: unknown, toolCallId?: string): void;
|
|
22
33
|
updateStreamPreview?(update: unknown): void;
|
|
23
|
-
updateResult(result:
|
|
24
|
-
content: Array<{
|
|
25
|
-
type: string;
|
|
26
|
-
text?: string;
|
|
27
|
-
data?: string;
|
|
28
|
-
mimeType?: string;
|
|
29
|
-
}>;
|
|
30
|
-
details?: unknown;
|
|
31
|
-
isError?: boolean;
|
|
32
|
-
}, isPartial?: boolean, toolCallId?: string): void;
|
|
34
|
+
updateResult(result: ToolResultFrame, isPartial?: boolean, toolCallId?: string): void;
|
|
33
35
|
setArgsComplete(toolCallId?: string): void;
|
|
34
36
|
setExecutionStarted(toolCallId?: string): void;
|
|
35
37
|
setExpanded(expanded: boolean): void;
|
|
@@ -39,6 +41,25 @@ export interface ToolExecutionHandle extends Component {
|
|
|
39
41
|
/** Seal the block as final history and stop its animations. */
|
|
40
42
|
seal(): void;
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Whether a call that returned with `details.async.state === "running"` stays
|
|
46
|
+
* parked ({@link ToolExecutionHandle.parkAsBackground}) so its job's later
|
|
47
|
+
* frames keep filling the card until a `completed`/`failed` frame settles it.
|
|
48
|
+
* Detached `task` spawns always do; backgrounded `bash`/`eval` jobs only under
|
|
49
|
+
* native rendering, where the terminal transcript keeps them frozen instead.
|
|
50
|
+
* Shared by the live event controller and the transcript rebuild.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parksAsBackground(toolName: string, details: unknown): boolean;
|
|
53
|
+
/** The background job state a tool result reports (`details.async.state`: running, completed, failed, cancelled). */
|
|
54
|
+
export declare function asyncJobState(details: unknown): string | undefined;
|
|
55
|
+
/** Whether a frame is a background job's last one: it completed, failed or was cancelled. */
|
|
56
|
+
export declare function isSettledJobFrame(details: unknown): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Settle a parked card ({@link parksAsBackground}) with its job's last frame
|
|
59
|
+
* ({@link isSettledJobFrame}): a completed or failed job is the call's result;
|
|
60
|
+
* a cancelled one keeps the output it got to and seals the card as cancelled.
|
|
61
|
+
*/
|
|
62
|
+
export declare function settleWithJobFrame(component: ToolExecutionHandle, frame: ToolResultFrame, toolCallId: string): void;
|
|
42
63
|
/** Phase-locked spinner glyph index shared by every live tool block so parallel
|
|
43
64
|
* spinners advance in lockstep instead of each tracking its own start time. */
|
|
44
65
|
export declare function sharedSpinnerFrame(frameCount: number, now?: number): number;
|
|
@@ -74,16 +95,7 @@ export declare class ToolExecutionComponent extends Container {
|
|
|
74
95
|
*/
|
|
75
96
|
whenPreviewSettled(timeoutMs?: number): Promise<void>;
|
|
76
97
|
updateStreamPreview(update: unknown): void;
|
|
77
|
-
updateResult(result:
|
|
78
|
-
content: Array<{
|
|
79
|
-
type: string;
|
|
80
|
-
text?: string;
|
|
81
|
-
data?: string;
|
|
82
|
-
mimeType?: string;
|
|
83
|
-
}>;
|
|
84
|
-
details?: unknown;
|
|
85
|
-
isError?: boolean;
|
|
86
|
-
}, isPartial?: boolean, _toolCallId?: string): void;
|
|
98
|
+
updateResult(result: ToolResultFrame, isPartial?: boolean, _toolCallId?: string): void;
|
|
87
99
|
/**
|
|
88
100
|
* Advance to the shared spinner glyph and repaint just this block. Driven by
|
|
89
101
|
* the single shared spinner ticker (see `registerSpinnerBlock`); the tick is
|
|
@@ -47,10 +47,11 @@ export interface NativeBackendOptions {
|
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* The reply a v1 terminal is assumed to give before its real `hello` arrives
|
|
50
|
-
* (the `TERM_PROGRAM=tern` optimistic start): the whole vocabulary
|
|
51
|
-
* default APC limit and credits, the terminal's
|
|
52
|
-
* already detected, full motion, and `blobs`, so a
|
|
53
|
-
* are asked about rather than resent before the
|
|
50
|
+
* (the `TERM_PROGRAM=tern` optimistic start): the whole vocabulary except
|
|
51
|
+
* {@link UNASSUMED_KINDS}, the default APC limit and credits, the terminal's
|
|
52
|
+
* width, the appearance omp already detected, full motion, and `blobs`, so a
|
|
53
|
+
* resumed session's images are asked about rather than resent before the
|
|
54
|
+
* reply comes.
|
|
54
55
|
*/
|
|
55
56
|
export declare function assumedTspHello(terminal: Terminal): TspHello;
|
|
56
57
|
export declare class NativeBackend {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* references it.
|
|
9
9
|
*/
|
|
10
10
|
import type { TspProps } from "@oh-my-pi/pi-wire";
|
|
11
|
-
import type { NativeNode } from "./node.js";
|
|
11
|
+
import type { NativeChild, NativeNode } from "./node.js";
|
|
12
12
|
export interface NativeBlob {
|
|
13
13
|
readonly id: string;
|
|
14
14
|
readonly mime: string;
|
|
@@ -31,3 +31,15 @@ export declare class NativeImageCache {
|
|
|
31
31
|
#private;
|
|
32
32
|
get(key: string, data: string, mimeType: string): NativeNode;
|
|
33
33
|
}
|
|
34
|
+
/** The disk file a tool result's image was read from (`read` details `mediaPath`), when it has one. */
|
|
35
|
+
export declare function readMediaPath(details: unknown): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* A `media` node the host loads by path, capped at the inline image preview
|
|
38
|
+
* height. Callers check `cx.supports("media")` first.
|
|
39
|
+
*/
|
|
40
|
+
export declare function nativeMediaNode(path: string, key: string): NativeNode;
|
|
41
|
+
/** Blob ids of the `image` nodes and paths of the `media` nodes under `children` (described nodes only). */
|
|
42
|
+
export declare function shownMedia(children: readonly NativeChild[] | undefined): {
|
|
43
|
+
blobs: Set<string>;
|
|
44
|
+
paths: Set<string>;
|
|
45
|
+
};
|
|
@@ -4,7 +4,7 @@ import type { Component } from "../tui.js";
|
|
|
4
4
|
import type { SgrMouseEvent } from "../mouse.js";
|
|
5
5
|
import { type ConfiguredThinkingLevel } from "../thinking.js";
|
|
6
6
|
import { type ThemeColor } from "../theme/theme.js";
|
|
7
|
-
import type { TspPickerColumn, TspPickerGroup, TspPickerItem } from "@oh-my-pi/pi-wire";
|
|
7
|
+
import type { TspPickerColumn, TspPickerGroup, TspPickerItem, TspPickerMark } from "@oh-my-pi/pi-wire";
|
|
8
8
|
import type { NativeChild, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
9
9
|
/** Canonical display ordering of built-in model roles. */
|
|
10
10
|
export type ModelRole = "default" | "smol" | "slow" | "vision" | "plan" | "commit" | "tiny" | "memory" | "task" | "advisor" | "image" | "web" | "speech" | "dictation" | "judge";
|
|
@@ -198,6 +198,11 @@ export declare function rankModelItems(query: string, items: ReadonlyArray<Model
|
|
|
198
198
|
export declare function formatRoleChip(role: string, assignment: RoleAssignment, settings: ModelBrowserSource): string;
|
|
199
199
|
/** Fact columns of a model picker (Stencil `NATIVE_REDESIGN.md` §4.7); the lowest priority hides first. */
|
|
200
200
|
export declare const MODEL_PICKER_COLUMNS: readonly TspPickerColumn[];
|
|
201
|
+
/**
|
|
202
|
+
* A provider's picker mark: the terminal's logo for it, else its initials
|
|
203
|
+
* (`amazon-bedrock` → `AB`, `anthropic` → `An`) on its own gradient.
|
|
204
|
+
*/
|
|
205
|
+
export declare function providerMark(providerId: string): TspPickerMark;
|
|
201
206
|
/** The omp theme token of a thinking level's dot (`thinkingHigh`); none for inherit and auto. */
|
|
202
207
|
export declare function thinkingDotToken(level: ConfiguredThinkingLevel): string | undefined;
|
|
203
208
|
/**
|
package/dist/types/thinking.d.ts
CHANGED
|
@@ -37,6 +37,11 @@ export declare function shouldDisableReasoning(level: ThinkingLevel | undefined)
|
|
|
37
37
|
* Resolves a selector against the current model while preserving explicit "off".
|
|
38
38
|
*/
|
|
39
39
|
export declare function resolveThinkingLevelForModel(model: Model | undefined, level: ThinkingLevel | undefined): ResolvedThinkingLevel | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Level applied to `model` when the user has not picked one for it (carried,
|
|
42
|
+
* global default, auto). Unverified thinking stays unset until the user picks.
|
|
43
|
+
*/
|
|
44
|
+
export declare function automaticThinkingLevel<T>(model: Model | undefined, fallback: T): T | undefined;
|
|
40
45
|
/**
|
|
41
46
|
* Sentinel selector for the coding-agent "auto" thinking mode. Kept entirely
|
|
42
47
|
* inside the coding-agent layer: it is never an {@link Effort} or
|
|
@@ -18,6 +18,8 @@ export interface BashToolDetails {
|
|
|
18
18
|
requestedTimeoutSeconds?: number;
|
|
19
19
|
timeoutDisabled?: boolean;
|
|
20
20
|
wallTimeMs?: number;
|
|
21
|
+
/** False when no wall-time footer was emitted; absent on older results. */
|
|
22
|
+
wallTimeNoticeEmitted?: boolean;
|
|
21
23
|
/** Exit code of a command that ran to completion but failed (non-zero). */
|
|
22
24
|
exitCode?: number;
|
|
23
25
|
/** True when the command was killed by its timeout deadline (not a failure). */
|
|
@@ -31,12 +33,15 @@ export interface BashToolDetails {
|
|
|
31
33
|
timedOut: boolean;
|
|
32
34
|
pid?: number;
|
|
33
35
|
};
|
|
36
|
+
/** Background job behind the call; `cancelled`: killed (`proc://<id>/kill`) before it finished. */
|
|
34
37
|
async?: {
|
|
35
|
-
state: "running" | "completed" | "failed";
|
|
38
|
+
state: "running" | "completed" | "failed" | "cancelled";
|
|
36
39
|
jobId: string;
|
|
37
40
|
type: "bash";
|
|
38
41
|
};
|
|
39
42
|
}
|
|
43
|
+
/** Minimum duration for a model-facing wall-time notice; shorter runs keep timing only in details. */
|
|
44
|
+
export declare const WALL_TIME_NOTICE_MIN_MS = 1000;
|
|
40
45
|
/** Formats the model-facing command duration notice. */
|
|
41
46
|
export declare function formatWallTimeNotice(wallTimeMs: number): string;
|
|
42
47
|
/** Formats the model-facing command exit status notice. */
|
|
@@ -44,9 +44,9 @@ export interface EvalToolDetails {
|
|
|
44
44
|
languages?: EvalLanguage[];
|
|
45
45
|
/** Optional human-readable notice (e.g. fallback explanation). */
|
|
46
46
|
notice?: string;
|
|
47
|
-
/** Present when the cell was auto-backgrounded as an async job. */
|
|
47
|
+
/** Present when the cell was auto-backgrounded as an async job; `cancelled`: killed before it finished. */
|
|
48
48
|
async?: {
|
|
49
|
-
state: "running" | "completed" | "failed";
|
|
49
|
+
state: "running" | "completed" | "failed" | "cancelled";
|
|
50
50
|
jobId: string;
|
|
51
51
|
type: "eval";
|
|
52
52
|
};
|
|
@@ -85,7 +85,7 @@ export interface RunFootInput {
|
|
|
85
85
|
readonly state: RunState;
|
|
86
86
|
/** Exit code of a `failed` run; a non-zero code names the state `exit N`. */
|
|
87
87
|
readonly exitCode?: number;
|
|
88
|
-
/** Milliseconds run so far (`running`) or in total;
|
|
88
|
+
/** Milliseconds run so far (`running`, a live `background` job) or in total; omitted when undefined. */
|
|
89
89
|
readonly elapsedMs?: number;
|
|
90
90
|
/** Quiet facts (job id, service state, artifact), muted and ` · `-joined. */
|
|
91
91
|
readonly facts?: readonly string[];
|
|
@@ -20,6 +20,12 @@ export interface ReadToolDetails {
|
|
|
20
20
|
truncation?: ReadTruncationStats;
|
|
21
21
|
isDirectory?: boolean;
|
|
22
22
|
resolvedPath?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Absolute path of the disk file whose image this read returned. A native TSP host that
|
|
25
|
+
* supports `media` shows the file by path instead of the uploaded image bytes. Unset for
|
|
26
|
+
* screenshots, URL reads and other images not backed by a file. Display-only.
|
|
27
|
+
*/
|
|
28
|
+
mediaPath?: string;
|
|
23
29
|
suffixResolution?: {
|
|
24
30
|
from: string;
|
|
25
31
|
to: string;
|
|
@@ -140,7 +146,7 @@ export declare const readToolRenderer: {
|
|
|
140
146
|
}>;
|
|
141
147
|
details?: ReadToolDetails;
|
|
142
148
|
isError?: boolean;
|
|
143
|
-
},
|
|
149
|
+
}, options: RenderResultOptions, args?: ReadRenderArgs): NativeToolView;
|
|
144
150
|
mergeCallAndResult: true;
|
|
145
151
|
};
|
|
146
152
|
/** Inclusive line range describing one elided span in a structural summary. */
|
|
@@ -33,6 +33,8 @@ export interface RenderResultOptions {
|
|
|
33
33
|
elapsedMs?: number;
|
|
34
34
|
/** The call was abandoned without a final result (turn aborted, sealed). Native describe hooks only. */
|
|
35
35
|
cancelled?: boolean;
|
|
36
|
+
/** The native host shows files by path (`cx.supports("media")`). Native describe hooks only. */
|
|
37
|
+
media?: boolean;
|
|
36
38
|
}
|
|
37
39
|
/** Render options for a result, plus the tool-specific context the transcript threads through. */
|
|
38
40
|
export type RenderResultContextOptions = RenderResultOptions & {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "18.10.
|
|
4
|
+
"version": "18.10.3",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"gen:glyphs": "bun scripts/gen-glyphs.ts"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@oh-my-pi/omptype": "18.10.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "18.10.
|
|
46
|
-
"@oh-my-pi/pi-ai": "18.10.
|
|
47
|
-
"@oh-my-pi/pi-catalog": "18.10.
|
|
48
|
-
"@oh-my-pi/pi-natives": "18.10.
|
|
49
|
-
"@oh-my-pi/pi-utils": "18.10.
|
|
50
|
-
"@oh-my-pi/pi-wire": "18.10.
|
|
51
|
-
"@oh-my-pi/snapcompact": "18.10.
|
|
44
|
+
"@oh-my-pi/omptype": "18.10.3",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "18.10.3",
|
|
46
|
+
"@oh-my-pi/pi-ai": "18.10.3",
|
|
47
|
+
"@oh-my-pi/pi-catalog": "18.10.3",
|
|
48
|
+
"@oh-my-pi/pi-natives": "18.10.3",
|
|
49
|
+
"@oh-my-pi/pi-utils": "18.10.3",
|
|
50
|
+
"@oh-my-pi/pi-wire": "18.10.3",
|
|
51
|
+
"@oh-my-pi/snapcompact": "18.10.3"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"kitty-vt-wasm": "^0.2.0"
|
package/src/app-keybindings.ts
CHANGED
|
@@ -57,8 +57,8 @@ interface AppKeybindings {
|
|
|
57
57
|
"app.session.rename": true;
|
|
58
58
|
"app.session.delete": true;
|
|
59
59
|
"app.session.deleteNoninvasive": true;
|
|
60
|
-
"app.tree.
|
|
61
|
-
"app.tree.
|
|
60
|
+
"app.tree.previousBranch": true;
|
|
61
|
+
"app.tree.nextBranch": true;
|
|
62
62
|
"app.plan.toggle": true;
|
|
63
63
|
"app.history.search": true;
|
|
64
64
|
"app.stt.pushToTalk": true;
|
|
@@ -227,13 +227,13 @@ export const KEYBINDINGS = {
|
|
|
227
227
|
defaultKeys: "ctrl+backspace",
|
|
228
228
|
description: "Delete session (non-invasive)",
|
|
229
229
|
},
|
|
230
|
-
"app.tree.
|
|
231
|
-
defaultKeys: [
|
|
232
|
-
description: "
|
|
230
|
+
"app.tree.previousBranch": {
|
|
231
|
+
defaultKeys: [],
|
|
232
|
+
description: "Jump to the previous branch in /tree",
|
|
233
233
|
},
|
|
234
|
-
"app.tree.
|
|
235
|
-
defaultKeys: [
|
|
236
|
-
description: "
|
|
234
|
+
"app.tree.nextBranch": {
|
|
235
|
+
defaultKeys: [],
|
|
236
|
+
description: "Jump to the next branch in /tree",
|
|
237
237
|
},
|
|
238
238
|
"app.plan.toggle": {
|
|
239
239
|
defaultKeys: "alt+shift+p",
|
|
@@ -570,6 +570,43 @@ interface AssetDocument {
|
|
|
570
570
|
/** Result of a left click inside the pane. */
|
|
571
571
|
export type PaneClick = { type: "hunk-action"; hunk: HunkBlock; action: HunkAction } | { type: "handled" } | null;
|
|
572
572
|
|
|
573
|
+
/**
|
|
574
|
+
* The heading of one side of a media/binary change (`Before · PNG · Git LFS`):
|
|
575
|
+
* `label` plus the side's kind, shared by the ANSI pane and the native compare.
|
|
576
|
+
*/
|
|
577
|
+
export function assetTitle(label: string, side: FileAssetSide): string {
|
|
578
|
+
let kind: string;
|
|
579
|
+
let lfs = false;
|
|
580
|
+
switch (side.kind) {
|
|
581
|
+
case "empty":
|
|
582
|
+
return label;
|
|
583
|
+
case "image":
|
|
584
|
+
kind =
|
|
585
|
+
side.image.sourceMimeType === "image/svg+xml"
|
|
586
|
+
? "SVG"
|
|
587
|
+
: side.image.sourceMimeType.replace(/^image\//, "").toUpperCase();
|
|
588
|
+
lfs = side.image.lfsOid !== undefined;
|
|
589
|
+
break;
|
|
590
|
+
case "text":
|
|
591
|
+
kind = "Text";
|
|
592
|
+
lfs = side.lfsOid !== undefined;
|
|
593
|
+
break;
|
|
594
|
+
case "binary":
|
|
595
|
+
kind = "Binary";
|
|
596
|
+
lfs = side.lfsOid !== undefined;
|
|
597
|
+
break;
|
|
598
|
+
case "tooLarge":
|
|
599
|
+
kind = "Too large";
|
|
600
|
+
lfs = side.lfsOid !== undefined;
|
|
601
|
+
break;
|
|
602
|
+
case "lfsMissing":
|
|
603
|
+
kind = "LFS missing";
|
|
604
|
+
lfs = true;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
return `${label} · ${kind}${lfs ? " · Git LFS" : ""}`;
|
|
608
|
+
}
|
|
609
|
+
|
|
573
610
|
/**
|
|
574
611
|
* Scrollable diff viewport. The root component feeds it key/mouse input and
|
|
575
612
|
* composes its rendered lines into the frame.
|
|
@@ -1129,11 +1166,11 @@ export class DiffPane {
|
|
|
1129
1166
|
for (let index = 0; index < height; index++) {
|
|
1130
1167
|
const leftSource =
|
|
1131
1168
|
index === 0
|
|
1132
|
-
? centerLine(theme.bold(
|
|
1169
|
+
? centerLine(theme.bold(assetTitle("Before", asset.old)), leftWidth).trimEnd()
|
|
1133
1170
|
: (oldLines[index - 1] ?? "");
|
|
1134
1171
|
const rightSource =
|
|
1135
1172
|
index === 0
|
|
1136
|
-
? centerLine(theme.bold(
|
|
1173
|
+
? centerLine(theme.bold(assetTitle("After", asset.new)), rightWidth).trimEnd()
|
|
1137
1174
|
: (newLines[index - 1] ?? "");
|
|
1138
1175
|
const left = truncateToWidth(leftSource, leftWidth);
|
|
1139
1176
|
const right = truncateToWidth(rightSource, rightWidth);
|
|
@@ -1208,39 +1245,6 @@ export class DiffPane {
|
|
|
1208
1245
|
return Array.from({ length: height }, (_, index) => content[index - top] ?? "");
|
|
1209
1246
|
}
|
|
1210
1247
|
|
|
1211
|
-
#assetTitle(label: string, side: FileAssetSide): string {
|
|
1212
|
-
let kind: string;
|
|
1213
|
-
let lfs = false;
|
|
1214
|
-
switch (side.kind) {
|
|
1215
|
-
case "empty":
|
|
1216
|
-
return label;
|
|
1217
|
-
case "image":
|
|
1218
|
-
kind =
|
|
1219
|
-
side.image.sourceMimeType === "image/svg+xml"
|
|
1220
|
-
? "SVG"
|
|
1221
|
-
: side.image.sourceMimeType.replace(/^image\//, "").toUpperCase();
|
|
1222
|
-
lfs = side.image.lfsOid !== undefined;
|
|
1223
|
-
break;
|
|
1224
|
-
case "text":
|
|
1225
|
-
kind = "Text";
|
|
1226
|
-
lfs = side.lfsOid !== undefined;
|
|
1227
|
-
break;
|
|
1228
|
-
case "binary":
|
|
1229
|
-
kind = "Binary";
|
|
1230
|
-
lfs = side.lfsOid !== undefined;
|
|
1231
|
-
break;
|
|
1232
|
-
case "tooLarge":
|
|
1233
|
-
kind = "Too large";
|
|
1234
|
-
lfs = side.lfsOid !== undefined;
|
|
1235
|
-
break;
|
|
1236
|
-
case "lfsMissing":
|
|
1237
|
-
kind = "LFS missing";
|
|
1238
|
-
lfs = true;
|
|
1239
|
-
break;
|
|
1240
|
-
}
|
|
1241
|
-
return `${label} · ${kind}${lfs ? " · Git LFS" : ""}`;
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
1248
|
#renderStreaming(width: number, height: number): string[] {
|
|
1245
1249
|
const streaming = this.#streaming;
|
|
1246
1250
|
if (!streaming) return [];
|