@oh-my-pi/pi-tui 18.4.8 → 18.4.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 +41 -0
- package/dist/types/apps/debug/log-viewer.d.ts +17 -0
- package/dist/types/apps/debug/raw-sse.d.ts +14 -0
- package/dist/types/chat/assistant-message.d.ts +4 -3
- package/dist/types/chat/messages.d.ts +4 -0
- package/dist/types/chrome/transcript-container.d.ts +7 -0
- package/dist/types/components/markdown.d.ts +0 -4
- package/dist/types/native/backend.d.ts +8 -0
- package/dist/types/native/encode.d.ts +5 -1
- package/dist/types/native/node.d.ts +14 -1
- package/dist/types/native/reconcile.d.ts +5 -0
- package/dist/types/overlays/advisor-config.d.ts +8 -0
- package/dist/types/overlays/ask-dialog.d.ts +1 -0
- package/dist/types/overlays/extensions/extension-dashboard.d.ts +31 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +37 -0
- package/dist/types/overlays/extensions/inspector-panel.d.ts +8 -0
- package/dist/types/overlays/jobs-panel.d.ts +35 -9
- package/dist/types/prompt/composer.d.ts +3 -1
- package/dist/types/prompt/word-completion.d.ts +12 -0
- package/dist/types/status-line/context-usage.d.ts +2 -0
- package/dist/types/terminal-capabilities.d.ts +5 -0
- package/dist/types/terminal.d.ts +7 -0
- package/dist/types/tools/bash-interactive.d.ts +15 -0
- package/dist/types/tools/output-meta.d.ts +8 -2
- package/dist/types/tools/streaming-output.d.ts +15 -10
- package/dist/types/tui.d.ts +8 -0
- package/dist/types/windows-input-mode.d.ts +26 -0
- package/package.json +9 -9
- package/src/apps/debug/log-viewer.ts +236 -2
- package/src/apps/debug/protocol-probe.ts +10 -1
- package/src/apps/debug/raw-sse.ts +210 -28
- package/src/chat/advisor-message.ts +4 -2
- package/src/chat/assistant-message.ts +7 -9
- package/src/chat/chat-transcript-builder.ts +1 -1
- package/src/chat/messages.ts +4 -0
- package/src/chrome/transcript-container.ts +13 -0
- package/src/components/markdown.ts +90 -130
- package/src/keys.ts +2 -4
- package/src/native/apply.ts +2 -1
- package/src/native/backend.ts +22 -0
- package/src/native/encode.ts +9 -2
- package/src/native/node.ts +15 -1
- package/src/native/reconcile.ts +28 -1
- package/src/overlays/advisor-config.ts +228 -2
- package/src/overlays/ask-dialog.ts +1 -0
- package/src/overlays/extensions/extension-dashboard.ts +275 -23
- package/src/overlays/extensions/extension-list.ts +274 -14
- package/src/overlays/extensions/inspector-panel.ts +368 -0
- package/src/overlays/hook-selector.ts +1 -1
- package/src/overlays/jobs-panel.ts +222 -49
- package/src/overlays/model-hub.ts +25 -4
- package/src/overlays/session-info-overlay.ts +55 -11
- package/src/prompt/composer-cache.ts +26 -3
- package/src/prompt/composer.ts +32 -7
- package/src/prompt/word-completion.ts +31 -13
- package/src/status-line/context-usage.ts +18 -2
- package/src/terminal-capabilities.ts +8 -0
- package/src/terminal.ts +43 -7
- package/src/tools/bash-interactive.ts +85 -16
- package/src/tools/output-meta.ts +13 -5
- package/src/tools/streaming-output.ts +48 -23
- package/src/tools/wait.ts +7 -19
- package/src/tui.ts +56 -14
- package/src/windows-input-mode.ts +206 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.4.10] - 2026-10-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added ContextUsageView.setBreakdown to refresh usage card without recreating it
|
|
10
|
+
- Added support for change events with flexible values in native TUI
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Keep settled responses reachable in scrollback while an ask panel is open, and keep the editor at the bottom after answering ([#12398](https://github.com/can1357/oh-my-pi/issues/12398), [#13993](https://github.com/can1357/oh-my-pi/pull/13993) by [@Dante-dan](https://github.com/Dante-dan)).
|
|
15
|
+
- Fixed a finished `wait` whose jobs were all still running going blank, and the next `wait` removing it while its turn's usage row stayed; the card now keeps its job snapshot ([#12248](https://github.com/can1357/oh-my-pi/issues/12248), [#13978](https://github.com/can1357/oh-my-pi/pull/13978) by [@Dante-dan](https://github.com/Dante-dan)).
|
|
16
|
+
- Hidden thinking blocks no longer leave a faint "Thought for Ns" row in Tern's native transcript; only the live "Thinking…" indicator shows while the model reasons.
|
|
17
|
+
- Fixed long Markdown paragraphs, such as a read preview of a file with no blank line, stalling rendering: a 44 KB paragraph now renders in about 8 ms instead of 95 ms ([#13961](https://github.com/can1357/oh-my-pi/pull/13961) by [@sjawhar](https://github.com/sjawhar)).
|
|
18
|
+
- Fixed Markdown paragraphs with many unclosed `[`, `*` or `_`, or with a long address-like word, stalling rendering for seconds ([#13961](https://github.com/can1357/oh-my-pi/pull/13961) by [@sjawhar](https://github.com/sjawhar)).
|
|
19
|
+
- Fixed Markdown paragraphs with many unclosed `~~`, `$`, `\(` or `\[`, nested brackets or emphasis, or unclosed HTML, stalling rendering for seconds: 40 KB of unclosed `~~` took 85 s. Emphasis or links nested a thousand levels deep still render slowly, for seconds per few KB: each level restyles the text inside it ([#13961](https://github.com/can1357/oh-my-pi/pull/13961) by [@sjawhar](https://github.com/sjawhar)).
|
|
20
|
+
- Fixed arrow keys acting as Escape and terminal query replies appearing as typed text when running omp on Windows over SSH ([#14034](https://github.com/can1357/oh-my-pi/issues/14034)).
|
|
21
|
+
- Fixed `/model` under an `enabledModels`/`--models` scope hiding every judge, search, image, and speech model and dropping their configured role assignments (JUDGE, WEB, IMAGE, …) ([#14016](https://github.com/can1357/oh-my-pi/issues/14016))
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
- Removed the internal `urlTokenPossible` export ([#13961](https://github.com/can1357/oh-my-pi/pull/13961) by [@sjawhar](https://github.com/sjawhar)).
|
|
26
|
+
- Removed the internal `autolinkSchemeScanIndex` export ([#13961](https://github.com/can1357/oh-my-pi/pull/13961) by [@sjawhar](https://github.com/sjawhar)).
|
|
27
|
+
|
|
28
|
+
## [18.4.9] - 2026-10-01
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Exported `wordCompletionQuery()` so hosts outside the editor can apply the same prose eligibility rules used by ghost-text word completion.
|
|
33
|
+
- Added a full-featured Background jobs view with selectable jobs, live status and elapsed time, working directory, process IDs, exit code, command, tailing output, and cancellation for running jobs.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- `OutputSink` now limits artifact files to 16 MiB by default while preserving the beginning and end of oversized output and marking the omitted bytes. Set `artifactMaxBytes: 0` to keep artifacts unbounded; `dump()` reports omitted bytes and full-output references identify sampled artifacts.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Reduced unnecessary composer startup-cache writes and ensured the cache database is released when it closes on Windows.
|
|
42
|
+
- Fixed Shift+Enter and Ctrl+Enter prompt behavior in Windows Terminal 1.24 and earlier; Shift+Enter now inserts a newline and Ctrl+Enter sends a follow-up, matching other platforms.
|
|
43
|
+
- Improved the Tern native terminal experience across background jobs, settings, debugging, logs, extension management, interactive shell, and provider streams: views remain usable and navigable, preserve output and selection behavior, support keyboard scrolling, and keep key actions accessible.
|
|
44
|
+
- Fixed multi-line labels in Background jobs and multi-line titles in native-terminal prompts so their formatting remains readable.
|
|
45
|
+
|
|
5
46
|
## [18.4.8] - 2026-10-01
|
|
6
47
|
|
|
7
48
|
### Fixed
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Component } from "../../tui.js";
|
|
2
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../../native/node.js";
|
|
2
3
|
/** Host capabilities for copying and fetching earlier log entries. */
|
|
3
4
|
export interface LogViewerDeps {
|
|
4
5
|
copyToClipboard(text: string): void;
|
|
@@ -76,6 +77,22 @@ export declare class DebugLogViewerComponent implements Component {
|
|
|
76
77
|
handleInput(keyData: string): void;
|
|
77
78
|
invalidate(): void;
|
|
78
79
|
dispose(): void;
|
|
80
|
+
/** A `picker` sheet floats over the transcript instead of taking the screen. */
|
|
81
|
+
nativeSheet(cx: DescribeContext): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* The logs as a picker sheet: the filter as its query, one row per entry
|
|
84
|
+
* (message, fields, time, pid, level dot) with the session boundary as a
|
|
85
|
+
* group head, the range selection checked, the entry under the cursor
|
|
86
|
+
* pretty-printed below, and the keys' actions in the bar. Without the
|
|
87
|
+
* `picker` kind it falls back to rows.
|
|
88
|
+
*/
|
|
89
|
+
describe(cx: DescribeContext): NativeNode | null;
|
|
90
|
+
/**
|
|
91
|
+
* Pointer actions run the keys' code: a row click moves the cursor there,
|
|
92
|
+
* a second click copies it (or loads older entries from that row), and the
|
|
93
|
+
* bar's buttons mirror their keys.
|
|
94
|
+
*/
|
|
95
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
79
96
|
render(width: number): readonly string[];
|
|
80
97
|
}
|
|
81
98
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Component } from "../../tui.js";
|
|
2
|
+
import type { NativeNode, NativeScreen, NativeUiEvent } from "../../native/node.js";
|
|
2
3
|
import { type RawSseDebugBuffer } from "./raw-sse-buffer.js";
|
|
3
4
|
/** @internal Exported for tests. */
|
|
4
5
|
export declare function expandPrettyDataLines(raw: readonly string[]): string[];
|
|
@@ -23,4 +24,17 @@ export declare class RawSseViewerComponent implements Component {
|
|
|
23
24
|
handleInput(keyData: string): void;
|
|
24
25
|
invalidate(): void;
|
|
25
26
|
render(width: number): readonly string[];
|
|
27
|
+
/** The action bar's buttons run the same code as their keys. */
|
|
28
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
29
|
+
/**
|
|
30
|
+
* The stream as a page of its own: the capture counters over the wire
|
|
31
|
+
* text, one `ansi` block that fills the page, scrolls itself and follows
|
|
32
|
+
* its tail until the user scrolls away (Tern-local, so no follow state
|
|
33
|
+
* here; the scroll keys reach it as `scroll` requests). The copy status
|
|
34
|
+
* and the buttons are this component's own node, docked under the page
|
|
35
|
+
* so they never scroll away.
|
|
36
|
+
*/
|
|
37
|
+
describeScreen(): NativeScreen;
|
|
38
|
+
/** The docked bar under the stream page: the copy status and the buttons. */
|
|
39
|
+
describe(): NativeNode;
|
|
26
40
|
}
|
|
@@ -86,9 +86,10 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
86
86
|
* A `col` (role `omp.assistant`) of `md` nodes keyed by content index, so
|
|
87
87
|
* streamed deltas reach the terminal as `text append` on the same node;
|
|
88
88
|
* the tail block carries `stream: true` until the message finalizes.
|
|
89
|
-
* Thinking blocks are quiet collapsible `section`s
|
|
90
|
-
*
|
|
91
|
-
*
|
|
89
|
+
* Thinking blocks are quiet collapsible `section`s: a muted "Thinking…"
|
|
90
|
+
* shimmer while live, then "Thought for 12s"; tokens and rate ride in the
|
|
91
|
+
* head's `title`. With `hideThinkingBlock` only the live head shows (collapsed)
|
|
92
|
+
* and a finished thought emits nothing.
|
|
92
93
|
*/
|
|
93
94
|
describe(): NativeNode;
|
|
94
95
|
/**
|
|
@@ -180,6 +180,10 @@ export interface AdvisorNote {
|
|
|
180
180
|
severity?: AdvisorSeverity;
|
|
181
181
|
/** Which configured advisor produced this note (omitted for the default advisor). */
|
|
182
182
|
advisor?: string;
|
|
183
|
+
/** Primary turns completed when note was emitted. */
|
|
184
|
+
turn?: number;
|
|
185
|
+
/** Primary turns elapsed before merged-batch delivery. */
|
|
186
|
+
turnsAgo?: number;
|
|
183
187
|
}
|
|
184
188
|
/** Details payload on the batched `advisor` custom message rendered in the transcript. */
|
|
185
189
|
export interface AdvisorMessageDetails {
|
|
@@ -81,6 +81,13 @@ export declare class TranscriptContainer extends Container {
|
|
|
81
81
|
resetStableEmission(): void;
|
|
82
82
|
/** Whether a transient block may be discarded without leaving tape history. */
|
|
83
83
|
canRemoveBlock(component: Component): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Whether a superseded snapshot block (a repeated `wait` poll) may be
|
|
86
|
+
* replaced by its successor. Beyond {@link canRemoveBlock}, a block directly
|
|
87
|
+
* above a usage row stays: that row describes the turn the block belongs to,
|
|
88
|
+
* and removing the block would leave a usage-only turn (#12248).
|
|
89
|
+
*/
|
|
90
|
+
canDisplaceBlock(component: Component): boolean;
|
|
84
91
|
/** Lifecycle state per block in transcript order (diagnostics and tests). */
|
|
85
92
|
blockStates(): readonly BlockState[];
|
|
86
93
|
/** Permanently captured presentation mode per block (diagnostics and tests). */
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { DescribeContext, NativeNode } from "../native/node.js";
|
|
2
2
|
import type { SymbolTheme } from "../symbols.js";
|
|
3
3
|
import type { Component } from "../tui.js";
|
|
4
|
-
/** @internal exported for tests — must stay index-identical to the old regex scan. */
|
|
5
|
-
export declare function autolinkSchemeScanIndex(src: string): number | undefined;
|
|
6
|
-
/** @internal exported for tests — must never return false for a src the built-in url regex matches. */
|
|
7
|
-
export declare function urlTokenPossible(src: string): boolean;
|
|
8
4
|
/** @internal exported for tests — the grown-line-start block-kind gate. */
|
|
9
5
|
export declare function fastLineStartHazard(grownLine: string): boolean;
|
|
10
6
|
/** A hyperlink as the renderer sees it: inline `[text](href)`, `<autolink>`, bare GFM URL, or reference link. */
|
|
@@ -19,6 +19,14 @@ export interface NativeHost {
|
|
|
19
19
|
overlays(): readonly NativeOverlay[];
|
|
20
20
|
/** Component receiving keyboard input. */
|
|
21
21
|
focused(): Component | null;
|
|
22
|
+
/**
|
|
23
|
+
* The user clicked into a node described by `owners[0]` (then the
|
|
24
|
+
* components containing it, innermost first): move keyboard focus there.
|
|
25
|
+
* `field` is the outermost owner that takes keys and whose focus target is
|
|
26
|
+
* the clicked `editor`/`input`, if any; `sheet` tells the overlays that
|
|
27
|
+
* don't hold the keys while the user works beside them.
|
|
28
|
+
*/
|
|
29
|
+
focusFromPointer(owners: readonly Component[], field: Component | null, sheet: (overlay: Component) => boolean): void;
|
|
22
30
|
requestRender(): void;
|
|
23
31
|
/** The terminal switched appearance. */
|
|
24
32
|
appearanceChanged(dark: boolean): void;
|
|
@@ -24,7 +24,11 @@ export declare function splitUtf8(body: string, limit: number): string[];
|
|
|
24
24
|
export declare function encodeTspMessage(verb: TspVerb, body: string, params?: TspParams, limit?: number): string;
|
|
25
25
|
/** Encode a JSON message body. */
|
|
26
26
|
export declare function encodeTspJson(verb: TspVerb, value: unknown, params?: TspParams, limit?: number): string;
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* The `hello` query; callers follow it with a DA1 sentinel. `features: ["edit"]`
|
|
29
|
+
* tells the terminal that omp applies its `edit` events (TSP §8.5), so it may keep a
|
|
30
|
+
* native selection in omp's editors; without it, every key stays omp's.
|
|
31
|
+
*/
|
|
28
32
|
export declare function encodeTspHelloQuery(version?: string): string;
|
|
29
33
|
/** One decoded APC message: verb, parameters and raw body. */
|
|
30
34
|
export interface TspRawMessage {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See `packages/wire/src/tsp.ts` for the wire vocabulary and
|
|
14
14
|
* `crates/tern/SURFACE_PROTOCOL.md` (Stencil repository) for the spec.
|
|
15
15
|
*/
|
|
16
|
-
import type { TspEvent, TspKind, TspProps, TspSpan } from "@oh-my-pi/pi-wire";
|
|
16
|
+
import type { TspEvent, TspKind, TspProps, TspScrollBy, TspSpan } from "@oh-my-pi/pi-wire";
|
|
17
17
|
import type { Component } from "../tui.js";
|
|
18
18
|
/** A described node: a wire node minus its id, with components allowed as children. */
|
|
19
19
|
export type NativeNode = {
|
|
@@ -32,8 +32,21 @@ export type NativeNode = {
|
|
|
32
32
|
* added. Key a node by what it points at to reveal it again on a move.
|
|
33
33
|
*/
|
|
34
34
|
readonly reveal?: "start" | "end" | "nearest";
|
|
35
|
+
/**
|
|
36
|
+
* Keyboard scrolling forwarded to the terminal (PgUp/PgDn/End reach the
|
|
37
|
+
* program): moves the scroller at or above the node by `by` whenever
|
|
38
|
+
* `n` differs from the previous description of the same node. Bump `n`
|
|
39
|
+
* per key press; presses between two frames repeat the latest `by` once
|
|
40
|
+
* each (`start`/`end` once). A freshly added node never scrolls.
|
|
41
|
+
*/
|
|
42
|
+
readonly scroll?: NativeScroll;
|
|
35
43
|
};
|
|
36
44
|
}[TspKind];
|
|
45
|
+
/** A {@link NativeNode.scroll} request. */
|
|
46
|
+
export interface NativeScroll {
|
|
47
|
+
readonly by: TspScrollBy;
|
|
48
|
+
readonly n: number;
|
|
49
|
+
}
|
|
37
50
|
/** A child slot: a described node, or a component that describes itself. */
|
|
38
51
|
export type NativeChild = NativeNode | Component;
|
|
39
52
|
/** What a component may consult while describing itself. Never a clock: motion is terminal-clocked. */
|
|
@@ -32,6 +32,11 @@ export declare class Reconciler {
|
|
|
32
32
|
detachLive(): void;
|
|
33
33
|
/** The component and keypath that described wire node `id`. */
|
|
34
34
|
target(id: string): NativeTarget | null;
|
|
35
|
+
/**
|
|
36
|
+
* The component that described wire node `id`, then each component whose
|
|
37
|
+
* node contains it, innermost first (empty for an unknown id).
|
|
38
|
+
*/
|
|
39
|
+
owners(id: string): Component[];
|
|
35
40
|
/** The key a list item node was described with (its key, else its child index). */
|
|
36
41
|
itemKey(id: string): string;
|
|
37
42
|
/** Wire id of the first `editor`/`input` `component` describes (for `focus`), or null. */
|
|
@@ -20,6 +20,10 @@ import { type Model, type UsageLimit, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
|
20
20
|
import { type Component, type TUI } from "../index.js";
|
|
21
21
|
import { type ModelBrowserSource } from "./model-browser.js";
|
|
22
22
|
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
23
|
+
export declare const ADVISOR_REVIEW_MODES: readonly ["turn", "agent-end"];
|
|
24
|
+
export declare const ADVISOR_SYNC_BACKLOG_MODES: readonly ["off", "1", "3", "5", "strict"];
|
|
25
|
+
export type AdvisorReviewMode = (typeof ADVISOR_REVIEW_MODES)[number];
|
|
26
|
+
export type AdvisorSyncBacklog = (typeof ADVISOR_SYNC_BACKLOG_MODES)[number];
|
|
23
27
|
/** One advisor declared in `WATCHDOG.yml`; its instructions specialize the shared baseline. */
|
|
24
28
|
export interface AdvisorConfig {
|
|
25
29
|
name: string;
|
|
@@ -32,6 +36,9 @@ export interface AdvisorConfig {
|
|
|
32
36
|
enabled?: boolean;
|
|
33
37
|
/** Maximum non-blocker notes per advisor prompt update (default 4); blockers are exempt. */
|
|
34
38
|
maxNotesPerUpdate?: number;
|
|
39
|
+
reviewMode?: AdvisorReviewMode;
|
|
40
|
+
reviewInterval?: number;
|
|
41
|
+
syncBacklog?: AdvisorSyncBacklog;
|
|
35
42
|
}
|
|
36
43
|
/** Which level a `WATCHDOG.yml` lives at: the project root or the user agent dir. */
|
|
37
44
|
export type AdvisorConfigScope = "project" | "user";
|
|
@@ -92,6 +99,7 @@ export interface AdvisorConfigDeps {
|
|
|
92
99
|
thinkingLevel?: ThinkingLevel;
|
|
93
100
|
}>;
|
|
94
101
|
availableToolNames: string[];
|
|
102
|
+
syncBacklog?: AdvisorSyncBacklog;
|
|
95
103
|
/** Formatted advisor-role model shown on the seeded default row (e.g. "anthropic/claude-..."). */
|
|
96
104
|
defaultModelLabel?: string;
|
|
97
105
|
}
|
|
@@ -88,6 +88,7 @@ export declare class AskDialogComponent implements Component {
|
|
|
88
88
|
#private;
|
|
89
89
|
private readonly callbacks;
|
|
90
90
|
private readonly options;
|
|
91
|
+
readonly retireDisplacedTranscript = true;
|
|
91
92
|
constructor(questions: ExtensionAskDialogQuestion[], callbacks: AskDialogCallbacks, options?: AskDialogOptions);
|
|
92
93
|
invalidate(): void;
|
|
93
94
|
dispose(): void;
|
|
@@ -12,8 +12,15 @@
|
|
|
12
12
|
* - Space/Enter or click: toggle selected item (or provider master switch)
|
|
13
13
|
* - Wheel over the inspector, or PageUp/PageDown when the inspector overflows: scroll the detail pane
|
|
14
14
|
* - Esc: clear search (if active) then close
|
|
15
|
+
*
|
|
16
|
+
* Natively (Tern) it is a `picker` sheet: provider scopes, the inventory as
|
|
17
|
+
* rows grouped by kind, the inspector as the side preview, and Toggle /
|
|
18
|
+
* Expand / Close actions; without `picker` it describes a page with the same
|
|
19
|
+
* parts. Pointer events run the key paths above.
|
|
15
20
|
*/
|
|
21
|
+
import type { TspPickerScope } from "@oh-my-pi/pi-wire";
|
|
16
22
|
import type { Component } from "../../tui.js";
|
|
23
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../../native/node.js";
|
|
17
24
|
import { type Tab } from "../../components/tab-bar.js";
|
|
18
25
|
import { type ToolRuntimeSource } from "./inspector-panel.js";
|
|
19
26
|
import type { ExtensionInspectorSource } from "./inspector-model.js";
|
|
@@ -45,6 +52,13 @@ export interface ExtensionDashboardOptions {
|
|
|
45
52
|
* re-enabled from the list. The "all" tab is never muted or marked.
|
|
46
53
|
*/
|
|
47
54
|
export declare function buildTabBarTabs(tabs: ProviderTab[]): Tab[];
|
|
55
|
+
/**
|
|
56
|
+
* Picker scopes from the provider tabs: "all" first, then each provider with
|
|
57
|
+
* its mark and count. Empty enabled providers are disabled (muted in the
|
|
58
|
+
* {@link TabBar}); switched-off providers keep a muted dot and stay
|
|
59
|
+
* selectable so their master switch can be turned back on.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildPickerScopes(tabs: ProviderTab[]): TspPickerScope[];
|
|
48
62
|
export declare class ExtensionDashboard implements Component {
|
|
49
63
|
#private;
|
|
50
64
|
onClose?: () => void;
|
|
@@ -59,5 +73,22 @@ export declare class ExtensionDashboard implements Component {
|
|
|
59
73
|
render(width: number): readonly string[];
|
|
60
74
|
invalidate(): void;
|
|
61
75
|
handleInput(data: string): void;
|
|
76
|
+
/** The dashboard is a `picker` sheet (scopes = providers, preview = inspector) wherever Tern draws pickers. */
|
|
77
|
+
nativeSheet(cx: DescribeContext): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* The picker sheet, or without `picker` a page: head, provider tabs,
|
|
80
|
+
* search, the inventory list beside the inspector, and an action bar.
|
|
81
|
+
* Rebuilt when state moves or the live tool set changes (MCP health
|
|
82
|
+
* changes arrive as render requests, which bump the version).
|
|
83
|
+
*/
|
|
84
|
+
describe(cx: DescribeContext): NativeNode;
|
|
85
|
+
/**
|
|
86
|
+
* Pointer input, each on the path of the key it stands for: a row click
|
|
87
|
+
* selects (click on the selected row or double click toggles, like
|
|
88
|
+
* Space/Enter), a scope switches provider (←/→), `toggle`/`expand` run
|
|
89
|
+
* Space and the expand key, `clear` empties the search (first Esc) and
|
|
90
|
+
* `close` closes. Provider tabs in the page route to the {@link TabBar}.
|
|
91
|
+
*/
|
|
92
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
62
93
|
dispose(): void;
|
|
63
94
|
}
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* that toggles the entire provider. All items below are dimmed when the
|
|
6
6
|
* master switch is off.
|
|
7
7
|
*/
|
|
8
|
+
import type { TspPickerGroup, TspPickerItem, TspProps } from "@oh-my-pi/pi-wire";
|
|
8
9
|
import type { Component } from "../../tui.js";
|
|
10
|
+
import type { NativeNode } from "../../native/node.js";
|
|
9
11
|
import { type ToolRuntimeSource } from "./inspector-model.js";
|
|
10
12
|
import { type MCPRuntimeSource } from "./mcp-runtime.js";
|
|
11
13
|
import { type Extension, type ExtensionKind, type ExtensionProvider } from "./types.js";
|
|
@@ -19,6 +21,22 @@ export interface ExtensionListCallbacks {
|
|
|
19
21
|
mcpSource?: MCPRuntimeSource;
|
|
20
22
|
toolSource?: ToolRuntimeSource;
|
|
21
23
|
}
|
|
24
|
+
/** The inventory as `picker` data: rows, display order with kind groups, the selection and search hits. */
|
|
25
|
+
export interface ExtensionListPickerView {
|
|
26
|
+
readonly items: TspPickerItem[];
|
|
27
|
+
/** Item ids in display order; kind headers become group entries. */
|
|
28
|
+
readonly order: (string | TspPickerGroup)[];
|
|
29
|
+
/** Selected item id; null when nothing or a kind header is selected. */
|
|
30
|
+
readonly selected: string | null;
|
|
31
|
+
readonly hits: Record<string, [number, number][]>;
|
|
32
|
+
/** Whether kind headers group the rows (the unfiltered ALL view). */
|
|
33
|
+
readonly grouped: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** The selected row's switch: its state, and why it cannot flip when it can't. */
|
|
36
|
+
export interface ExtensionListSwitch {
|
|
37
|
+
readonly on: boolean;
|
|
38
|
+
readonly blocked?: string;
|
|
39
|
+
}
|
|
22
40
|
export declare class ExtensionList implements Component {
|
|
23
41
|
#private;
|
|
24
42
|
constructor(extensions: Extension[], callbacks?: ExtensionListCallbacks, maxVisible?: number);
|
|
@@ -29,6 +47,8 @@ export declare class ExtensionList implements Component {
|
|
|
29
47
|
setMcpSource(source: MCPRuntimeSource | undefined): void;
|
|
30
48
|
setToolSource(source: ToolRuntimeSource | undefined): void;
|
|
31
49
|
getSearchQuery(): string;
|
|
50
|
+
/** The search field's text and caret for a native `picker` head. */
|
|
51
|
+
nativeQuery(): Pick<TspProps<"picker">, "query" | "cursor">;
|
|
32
52
|
resetSelection(): void;
|
|
33
53
|
getSelectedExtension(): Extension | null;
|
|
34
54
|
/** Get the currently selected kind header (for preview purposes) */
|
|
@@ -38,6 +58,23 @@ export declare class ExtensionList implements Component {
|
|
|
38
58
|
clearSearch(): void;
|
|
39
59
|
invalidate(): void;
|
|
40
60
|
render(width: number): readonly string[];
|
|
61
|
+
/** The visible rows as `picker` data, joined with live MCP health and tool runtime like {@link render}. */
|
|
62
|
+
pickerView(): ExtensionListPickerView;
|
|
63
|
+
/**
|
|
64
|
+
* The visible rows as a native `list` (kind headers included, so the
|
|
65
|
+
* selection matches the keyboard's), for terminals without `picker`.
|
|
66
|
+
*/
|
|
67
|
+
describeList(key: string): NativeNode;
|
|
68
|
+
/**
|
|
69
|
+
* A pointer pick of the row with native id `id`: select it, then toggle it
|
|
70
|
+
* when `activate` (the click-on-selected / double-click path). Returns
|
|
71
|
+
* whether the id named a visible row.
|
|
72
|
+
*/
|
|
73
|
+
pickNative(id: string, activate: boolean): boolean;
|
|
74
|
+
/** The selected row's switch, or undefined on a kind header or an empty list. */
|
|
75
|
+
selectedSwitch(): ExtensionListSwitch | undefined;
|
|
76
|
+
/** Toggle the selected item, or flip the provider master switch when on it (Space/Enter). */
|
|
77
|
+
activateSelected(): void;
|
|
41
78
|
/** Highlight the row under the pointer (null clears). */
|
|
42
79
|
setHoverIndex(index: number | null): void;
|
|
43
80
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Component } from "../../tui.js";
|
|
2
|
+
import type { NativeNode } from "../../native/node.js";
|
|
2
3
|
import { type ExtensionInspectorSource, type ToolRuntimeSource } from "./inspector-model.js";
|
|
3
4
|
import { type MCPRuntimeSource } from "./mcp-runtime.js";
|
|
4
5
|
import { type Extension } from "./types.js";
|
|
@@ -14,4 +15,11 @@ export declare class InspectorPanel implements Component {
|
|
|
14
15
|
toggleExpanded(): boolean;
|
|
15
16
|
invalidate(): void;
|
|
16
17
|
render(width: number): readonly string[];
|
|
18
|
+
/**
|
|
19
|
+
* The selected extension as native preview nodes, in the same order as
|
|
20
|
+
* {@link render}: identity, runtime/enablement and origin facts,
|
|
21
|
+
* description, guidance, kind sections, content preview, config. The
|
|
22
|
+
* collapsed budgets follow {@link toggleExpanded} like the ANSI view.
|
|
23
|
+
*/
|
|
24
|
+
describePreview(): NativeNode[];
|
|
17
25
|
}
|
|
@@ -16,6 +16,30 @@ export interface JobsPanelSnapshot {
|
|
|
16
16
|
readonly running: readonly JobsPanelJob[];
|
|
17
17
|
readonly recent: readonly JobsPanelJob[];
|
|
18
18
|
}
|
|
19
|
+
/** What the sheet shows about the selected job beyond its row. */
|
|
20
|
+
export interface JobsPanelDetail {
|
|
21
|
+
/** Full command line of a job that runs a process (rows show the cut label). */
|
|
22
|
+
readonly command?: string;
|
|
23
|
+
readonly cwd?: string;
|
|
24
|
+
/** Live pids the job's command spawned. */
|
|
25
|
+
readonly pids: readonly number[];
|
|
26
|
+
readonly exitCode?: number;
|
|
27
|
+
/** Output tail while running; the final text once settled. */
|
|
28
|
+
readonly output?: string;
|
|
29
|
+
/** Artifact holding the full output when `output` is cut. */
|
|
30
|
+
readonly artifactId?: string;
|
|
31
|
+
}
|
|
32
|
+
/** The session behind a {@link JobsSheet}. */
|
|
33
|
+
export interface JobsSheetSource {
|
|
34
|
+
/** Current jobs; runs once per frame. */
|
|
35
|
+
load(): JobsPanelSnapshot;
|
|
36
|
+
/** The selected job's detail; runs once per frame, undefined once the job is gone. */
|
|
37
|
+
inspect(id: string): JobsPanelDetail | undefined;
|
|
38
|
+
/** Cancel a running job. */
|
|
39
|
+
cancel(id: string): void;
|
|
40
|
+
/** Dismiss the sheet. */
|
|
41
|
+
close(): void;
|
|
42
|
+
}
|
|
19
43
|
/** The `/jobs` block: `ansi` renders in the terminal, the snapshot describes the native frame. */
|
|
20
44
|
export declare class JobsPanel extends Container {
|
|
21
45
|
#private;
|
|
@@ -23,26 +47,28 @@ export declare class JobsPanel extends Container {
|
|
|
23
47
|
describe(cx: DescribeContext): NativeNode;
|
|
24
48
|
}
|
|
25
49
|
/**
|
|
26
|
-
* The jobs pill's sheet: a centred `
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* the
|
|
50
|
+
* The jobs pill's sheet: a centred `lg` glass sheet titled Background jobs.
|
|
51
|
+
* A selectable list of every job (running first) sits over the selected
|
|
52
|
+
* job's detail: status and live elapsed (a task job's `agent` node), cwd,
|
|
53
|
+
* live pids, exit code, the full command and a tail-following output pane.
|
|
54
|
+
* It re-reads the session every frame, so the caller re-renders it on a
|
|
55
|
+
* timer while it is open. ↑/↓ select, X cancels the selected running job,
|
|
56
|
+
* Esc or Close dismisses; nothing enters the transcript.
|
|
30
57
|
*/
|
|
31
58
|
export declare class JobsSheet implements Component {
|
|
32
59
|
#private;
|
|
33
60
|
readonly nativeOverlay: {
|
|
34
61
|
readonly role: "omp.overlay.jobs";
|
|
35
|
-
readonly size: "
|
|
62
|
+
readonly size: "lg";
|
|
36
63
|
readonly anchor: "center";
|
|
37
64
|
readonly head: "Background jobs";
|
|
38
65
|
};
|
|
39
|
-
|
|
40
|
-
constructor(load: () => JobsPanelSnapshot, onClose: () => void);
|
|
66
|
+
constructor(source: JobsSheetSource);
|
|
41
67
|
describe(cx: DescribeContext): NativeNode;
|
|
42
|
-
/** Rows for a terminal without the native surface:
|
|
68
|
+
/** Rows for a terminal without the native surface: one per job, then the selected job's facts and output tail. */
|
|
43
69
|
render(width: number): readonly string[];
|
|
44
70
|
invalidate(): void;
|
|
45
71
|
handleInput(data: string): void;
|
|
46
|
-
/** Close
|
|
72
|
+
/** Clicks select a row; Close and Cancel job run what Esc and X run. */
|
|
47
73
|
handleNativeEvent(event: NativeUiEvent): void;
|
|
48
74
|
}
|
|
@@ -62,7 +62,9 @@ export interface RuntimeChildrenOptions {
|
|
|
62
62
|
* multi-line editor). They are billed at their smallest height so expansion
|
|
63
63
|
* clips the live tail instead of retiring rows a later shrink could not
|
|
64
64
|
* reclaim (#11007). Every other root is billed at its current height, so
|
|
65
|
-
* settled rows it displaces retire to native scrollback.
|
|
65
|
+
* settled rows it displaces retire to native scrollback. Decision panels
|
|
66
|
+
* declaring `retireDisplacedTranscript` opt out of this floor even when
|
|
67
|
+
* mounted as a child of a transient editor container.
|
|
66
68
|
*/
|
|
67
69
|
readonly transient?: readonly Component[];
|
|
68
70
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EditorTextAssistProvider } from "../components/editor.js";
|
|
2
|
+
import { ProseSource } from "./prose-gate.js";
|
|
2
3
|
/** Values of the `spelling.autocomplete` setting. */
|
|
3
4
|
export declare const WORD_COMPLETION_METHODS: readonly ["off", "auto", "ngram", "smollm", "apple"];
|
|
4
5
|
/** Configured word-completion engine; `off` disables ghost text. */
|
|
@@ -21,6 +22,17 @@ export type WordPredictionBackendResolver = (method: WordCompletionEngine) => Wo
|
|
|
21
22
|
* before the host finished starting. Pass `undefined` to detach.
|
|
22
23
|
*/
|
|
23
24
|
export declare function setWordPredictionHost(resolver: WordPredictionBackendResolver | undefined): void;
|
|
25
|
+
/** The prose word ending at the cursor and the editor text before it: what an engine is asked to complete. */
|
|
26
|
+
export interface WordCompletionQuery {
|
|
27
|
+
before: string;
|
|
28
|
+
prefix: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The query for the prose word ending at the cursor, or `undefined` where no
|
|
32
|
+
* ghost text applies (mid-word, no word, code, paths, commands). `prose`
|
|
33
|
+
* memoizes the whole-buffer mask; pass one instance across keystrokes.
|
|
34
|
+
*/
|
|
35
|
+
export declare function wordCompletionQuery(lines: readonly string[], cursorLine: number, cursorCol: number, prose?: ProseSource): WordCompletionQuery | undefined;
|
|
24
36
|
/**
|
|
25
37
|
* Ghost-text word completion for the prose word ending at the cursor, served
|
|
26
38
|
* by an injected asynchronous {@link WordPredictionBackend}.
|
|
@@ -168,6 +168,8 @@ export declare function describeContextUsage(breakdown: ContextBreakdown): Nativ
|
|
|
168
168
|
export declare class ContextUsageView extends Container {
|
|
169
169
|
#private;
|
|
170
170
|
constructor(breakdown: ContextBreakdown, theme: Theme);
|
|
171
|
+
/** Replace the shown breakdown in place, refreshing both the ANSI and native views. */
|
|
172
|
+
setBreakdown(breakdown: ContextBreakdown): void;
|
|
171
173
|
describe(cx: DescribeContext): NativeNode;
|
|
172
174
|
}
|
|
173
175
|
/**
|
|
@@ -61,6 +61,11 @@ export declare class TerminalInfo {
|
|
|
61
61
|
* is observed and tests can toggle `Bun.env.ZELLIJ` per case.
|
|
62
62
|
*/
|
|
63
63
|
export declare function isInsideZellij(env?: NodeJS.ProcessEnv): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the agent process runs in an SSH session, so the terminal emulator
|
|
66
|
+
* is remote and host-local input/keyboard modes cannot be assumed.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isSshSession(env?: NodeJS.ProcessEnv): boolean;
|
|
64
69
|
export declare function isNotificationSuppressed(): boolean;
|
|
65
70
|
/**
|
|
66
71
|
* Whether `PI_FORCE_IMAGE_PROTOCOL` pins the image protocol, including its
|
package/dist/types/terminal.d.ts
CHANGED
|
@@ -276,6 +276,13 @@ export interface ProcessTerminalOptions {
|
|
|
276
276
|
* `WSL_INTEROP`) — the suite must behave identically on WSL and on CI.
|
|
277
277
|
*/
|
|
278
278
|
conpty?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Whether stdin is a native Windows console handle (win32, not WSL), whose
|
|
281
|
+
* console host answers `CSI ? 9001 h` with win32-input-mode key records.
|
|
282
|
+
* Defaults to `process.platform === "win32"`; only consulted when `conpty`
|
|
283
|
+
* is also true.
|
|
284
|
+
*/
|
|
285
|
+
nativeWindowsConsole?: boolean;
|
|
279
286
|
}
|
|
280
287
|
/**
|
|
281
288
|
* Real terminal using process.stdin/stdout
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type * as XtermModule from "@oh-my-pi/pi-utils/vterm";
|
|
2
2
|
import type { Component } from "../tui.js";
|
|
3
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
3
4
|
import type { Theme } from "../theme/theme.js";
|
|
4
5
|
/** Resize-only backend exposed by an interactive PTY controller. */
|
|
5
6
|
export interface BashInteractiveTerminalBackend {
|
|
@@ -8,6 +9,12 @@ export interface BashInteractiveTerminalBackend {
|
|
|
8
9
|
/** Interactive terminal overlay driven by an external PTY controller. */
|
|
9
10
|
export declare class BashInteractiveOverlayComponent implements Component {
|
|
10
11
|
#private;
|
|
12
|
+
/** Native sheet: a full-pane glass overlay titled Console. */
|
|
13
|
+
readonly nativeOverlay: {
|
|
14
|
+
readonly role: "omp.overlay.console";
|
|
15
|
+
readonly size: "full";
|
|
16
|
+
readonly head: "Console";
|
|
17
|
+
};
|
|
11
18
|
constructor(command: string, uiTheme: Theme, getTerminalRows: () => number, terminalCtor: typeof XtermModule.Terminal, backend: BashInteractiveTerminalBackend);
|
|
12
19
|
/** Connects normalized keyboard input and overlay lifecycle events to the controller. */
|
|
13
20
|
setHandlers(onInput: (data: string) => void, onDismiss: () => void, onDispose: () => void): void;
|
|
@@ -22,6 +29,14 @@ export declare class BashInteractiveOverlayComponent implements Component {
|
|
|
22
29
|
timedOut: boolean;
|
|
23
30
|
}): void;
|
|
24
31
|
handleInput(data: string): void;
|
|
32
|
+
/** The Force kill button runs the Esc path. */
|
|
33
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
34
|
+
/**
|
|
35
|
+
* Native view: the command with its state badge, the PTY screen as an
|
|
36
|
+
* `ansi` node (SGR kept, fixed to the PTY grid), and a footer with the
|
|
37
|
+
* Force kill action while running.
|
|
38
|
+
*/
|
|
39
|
+
describe(cx: DescribeContext): NativeNode;
|
|
25
40
|
render(width: number): readonly string[];
|
|
26
41
|
invalidate(): void;
|
|
27
42
|
dispose(): void;
|
|
@@ -31,6 +31,8 @@ export interface TruncationMeta {
|
|
|
31
31
|
elidedLines?: number;
|
|
32
32
|
/** Artifact ID if full output was saved */
|
|
33
33
|
artifactId?: string;
|
|
34
|
+
/** Bytes the artifact cap dropped from the saved file's middle; the artifact is then a head/tail sample. */
|
|
35
|
+
artifactElidedBytes?: number;
|
|
34
36
|
/** Next offset for pagination (head truncation only) */
|
|
35
37
|
nextOffset?: number;
|
|
36
38
|
/**
|
|
@@ -87,6 +89,7 @@ export interface LimitsMeta {
|
|
|
87
89
|
maxColumn: number;
|
|
88
90
|
unit?: "bytes" | "chars";
|
|
89
91
|
artifactId?: string;
|
|
92
|
+
artifactElidedBytes?: number;
|
|
90
93
|
};
|
|
91
94
|
}
|
|
92
95
|
/**
|
|
@@ -111,8 +114,11 @@ export interface OutputMeta {
|
|
|
111
114
|
* Messages that don't match the expected format are appended ungrouped at the end.
|
|
112
115
|
*/
|
|
113
116
|
export declare function formatGroupedDiagnosticMessages(messages: string[]): string;
|
|
114
|
-
/**
|
|
115
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Format a recoverable output artifact link. An artifact the size cap cut
|
|
119
|
+
* (`artifactElidedBytes > 0`) is labeled as the head/tail sample it holds.
|
|
120
|
+
*/
|
|
121
|
+
export declare function formatFullOutputReference(artifactId: string, artifactElidedBytes?: number): string;
|
|
116
122
|
/** Strip the last literal notice or a matching final line; optionally preserve surrounding whitespace. */
|
|
117
123
|
export declare function stripTrailingNotice(text: string, notice: string | ((line: string) => boolean), trimResult?: boolean): string;
|
|
118
124
|
/** Remove the trailing bash raw-output artifact footer while preserving its artifact id. */
|