@oh-my-pi/pi-tui 18.8.8 → 18.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -221
- package/dist/types/charts/chart-plan.d.ts +595 -13
- package/dist/types/charts/chart-svg.d.ts +38 -9
- package/dist/types/charts/table-data.d.ts +70 -2
- package/dist/types/chat/table-chart.d.ts +3 -2
- package/dist/types/chat/user-message.d.ts +12 -1
- package/dist/types/chrome/shared.d.ts +9 -0
- package/dist/types/chrome/transcript-container.d.ts +1 -0
- package/dist/types/components/editor.d.ts +6 -0
- package/dist/types/components/form.d.ts +1 -0
- package/dist/types/components/markdown.d.ts +7 -0
- package/dist/types/components/tree-view.d.ts +7 -0
- package/dist/types/kitty-graphics.d.ts +2 -2
- package/dist/types/loop-watchdog.d.ts +8 -7
- package/dist/types/multiplexers/cmux.d.ts +16 -0
- package/dist/types/multiplexers/herdr.d.ts +26 -0
- package/dist/types/multiplexers/notify.d.ts +13 -0
- package/dist/types/multiplexers/orca.d.ts +12 -0
- package/dist/types/multiplexers/screen.d.ts +9 -0
- package/dist/types/multiplexers/tmux.d.ts +29 -0
- package/dist/types/multiplexers/types.d.ts +100 -0
- package/dist/types/multiplexers/wmux.d.ts +12 -0
- package/dist/types/multiplexers/zellij.d.ts +12 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +4 -3
- package/dist/types/overlays/agent-hub-types.d.ts +9 -0
- package/dist/types/overlays/annotation-overlay.d.ts +2 -0
- package/dist/types/overlays/model-browser.d.ts +9 -1
- package/dist/types/overlays/settings-defs.d.ts +1 -0
- package/dist/types/overlays/usage-display.d.ts +3 -1
- package/dist/types/setup/scenes/types.d.ts +1 -0
- package/dist/types/status-line/component.d.ts +2 -0
- package/dist/types/status-line/host.d.ts +4 -1
- package/dist/types/status-line/types.d.ts +11 -2
- package/dist/types/terminal-capabilities.d.ts +24 -32
- package/dist/types/terminal-multiplexer.d.ts +127 -14
- package/dist/types/terminal.d.ts +12 -4
- package/dist/types/theme/schema.d.ts +11 -2
- package/dist/types/theme/theme-class.d.ts +7 -0
- package/dist/types/tmux.d.ts +1 -4
- package/dist/types/tools/eval.d.ts +21 -2
- package/dist/types/tools/output-meta.d.ts +11 -1
- package/dist/types/tools/streaming-output.d.ts +9 -0
- package/package.json +9 -9
- package/src/charts/chart-plan.ts +4802 -88
- package/src/charts/chart-svg.ts +4315 -351
- package/src/charts/table-data.ts +1076 -34
- package/src/chat/assistant-message.ts +27 -9
- package/src/chat/chat-transcript-builder.ts +1 -3
- package/src/chat/svg-figure.ts +45 -8
- package/src/chat/table-chart.ts +7 -11
- package/src/chat/user-message.ts +40 -2
- package/src/chrome/shared.ts +53 -0
- package/src/chrome/transcript-container.ts +32 -9
- package/src/components/editor.ts +38 -5
- package/src/components/form.ts +8 -0
- package/src/components/markdown.ts +45 -2
- package/src/components/settings-list.ts +2 -0
- package/src/components/tree-view.ts +38 -8
- package/src/kitty-graphics.ts +4 -4
- package/src/loop-watchdog.ts +18 -13
- package/src/multiplexers/cmux.ts +29 -0
- package/src/multiplexers/herdr.ts +64 -0
- package/src/multiplexers/notify.ts +24 -0
- package/src/multiplexers/orca.ts +16 -0
- package/src/multiplexers/screen.ts +15 -0
- package/src/multiplexers/tmux.ts +40 -0
- package/src/multiplexers/types.ts +110 -0
- package/src/multiplexers/wmux.ts +16 -0
- package/src/multiplexers/zellij.ts +24 -0
- package/src/overlays/agent-hub-projection.ts +51 -14
- package/src/overlays/agent-hub-types.ts +6 -0
- package/src/overlays/annotation-overlay.ts +2 -1
- package/src/overlays/model-browser.ts +43 -7
- package/src/overlays/model-hub.ts +12 -19
- package/src/overlays/settings-defs.ts +4 -3
- package/src/overlays/settings-selector.ts +10 -1
- package/src/overlays/tree-selector.ts +21 -16
- package/src/overlays/usage-display.ts +10 -4
- package/src/setup/scenes/model.ts +2 -1
- package/src/setup/scenes/types.ts +1 -0
- package/src/status-line/component.ts +65 -11
- package/src/status-line/host.ts +4 -1
- package/src/status-line/segments.ts +21 -16
- package/src/status-line/types.ts +12 -2
- package/src/terminal-capabilities.ts +65 -181
- package/src/terminal-multiplexer.ts +112 -33
- package/src/terminal.ts +73 -32
- package/src/theme/schema-validation.ts +1 -0
- package/src/theme/schema.ts +14 -1
- package/src/theme/session-color.ts +1 -7
- package/src/theme/theme-class.ts +26 -1
- package/src/theme/theme-schema.json +5 -1
- package/src/theme/theme.ts +7 -4
- package/src/tmux.ts +4 -11
- package/src/tools/eval.ts +56 -16
- package/src/tools/output-meta.ts +23 -3
- package/src/tools/streaming-output.ts +29 -2
- package/src/tools/todo.ts +4 -1
- package/src/tui.ts +33 -18
- package/src/windows-input-mode.ts +8 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Model } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import type
|
|
2
|
+
import { type ModelKind } from "@oh-my-pi/pi-catalog/types";
|
|
3
3
|
import type { Component } from "../tui.js";
|
|
4
4
|
import type { SgrMouseEvent } from "../mouse.js";
|
|
5
5
|
import { type ConfiguredThinkingLevel } from "../thinking.js";
|
|
@@ -103,6 +103,14 @@ export type RoleAssignments = Record<string, RoleAssignment | undefined>;
|
|
|
103
103
|
* the alt+p session picker.
|
|
104
104
|
*/
|
|
105
105
|
export declare function resolveRoleAssignments(settings: ModelBrowserSource, allModels: ReadonlyArray<Model>, autoCandidates: ReadonlyArray<Model>): RoleAssignments;
|
|
106
|
+
/**
|
|
107
|
+
* Role-resolution pool for a `--models`/`enabledModels` scope: the scoped
|
|
108
|
+
* models plus every available non-chat runner (judge, search, image, …). The
|
|
109
|
+
* scope only filters chat models (it feeds Ctrl+P cycling) and runtime role
|
|
110
|
+
* resolution ignores it for other kinds, so displayed role assignments must too.
|
|
111
|
+
* Shared by the /models hub and the session picker.
|
|
112
|
+
*/
|
|
113
|
+
export declare function scopedRolePool(scoped: ReadonlyArray<Model>, registry: ModelBrowserRegistry): Model[];
|
|
106
114
|
/** Wrap raw models into browser items. */
|
|
107
115
|
export declare function buildBrowserItems(models: ReadonlyArray<Model>): ModelBrowserItem[];
|
|
108
116
|
/** Options for {@link sortModelItems}. */
|
|
@@ -44,6 +44,7 @@ export type AnyUiMetadata = UiBase & {
|
|
|
44
44
|
options?: ReadonlyArray<SubmenuOption> | "runtime";
|
|
45
45
|
secret?: boolean;
|
|
46
46
|
ordered?: boolean;
|
|
47
|
+
editor?: "json";
|
|
47
48
|
};
|
|
48
49
|
/** Structural schema entries supplied by the application host. */
|
|
49
50
|
export interface SettingsDisplayEntry {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UsageLimit, UsageReport, UsageResetCredits } from "@oh-my-pi/pi-ai";
|
|
1
|
+
import type { UsageLimit, UsageReport, UsageResetCreditDetail, UsageResetCredits } from "@oh-my-pi/pi-ai";
|
|
2
2
|
/** Include the usage tier in a limit title unless its label already names it. */
|
|
3
3
|
export declare function formatLimitTitle(limit: UsageLimit): string;
|
|
4
4
|
/** Human-readable quota scope for a normalized saved-reset window ID. */
|
|
@@ -10,6 +10,8 @@ export interface UsageResetSummary {
|
|
|
10
10
|
soonestExpiry?: string;
|
|
11
11
|
unavailableReason?: string;
|
|
12
12
|
}
|
|
13
|
+
/** Expiry (epoch ms) of a credit that still banks a reset, whether or not it can be spent now. */
|
|
14
|
+
export declare function bankedResetCreditExpiryMs(credit: UsageResetCreditDetail): number | undefined;
|
|
13
15
|
/**
|
|
14
16
|
* Normalize old count-only and current provider reset metadata for display.
|
|
15
17
|
* `availableCount` is banked inventory; `redeemableCount` is the subset that
|
|
@@ -28,6 +28,7 @@ export interface SetupHost extends SetupUiHost {
|
|
|
28
28
|
readonly disabledProviders: readonly string[];
|
|
29
29
|
readonly authStorage: AuthStorage;
|
|
30
30
|
readonly modelSource: ModelBrowserSource;
|
|
31
|
+
/** Available and catalog models of every kind; role chips resolve over all of them, rows list chat models. */
|
|
31
32
|
getModels(): {
|
|
32
33
|
available: Model[];
|
|
33
34
|
all: Model[];
|
|
@@ -111,6 +111,8 @@ export declare class StatusLineComponent<TSession extends StatusLineSession = St
|
|
|
111
111
|
setRecording(recording: boolean): void;
|
|
112
112
|
/** Set the callback that presents detected Codex reset celebrations, or clear it with `undefined`. */
|
|
113
113
|
setCodexResetFireworksHandler(handler: ((event: CodexResetFireworksEvent) => void) | undefined): void;
|
|
114
|
+
/** Set the callback that presents the first pool-wide saved-reset expiry warning, or clear it with `undefined`. */
|
|
115
|
+
setResetExpiryNoticeHandler(handler: ((notice: string) => void) | undefined): void;
|
|
114
116
|
setHookStatus(key: string, text: string | undefined): void;
|
|
115
117
|
watchBranch(onBranchChange: () => void): void;
|
|
116
118
|
dispose(): void;
|
|
@@ -2,7 +2,7 @@ import type { AgentMessage, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
|
2
2
|
import type { Tool, UsageLimit, UsageReport } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import type { Model } from "@oh-my-pi/pi-catalog/types";
|
|
4
4
|
import type { CompactionBoundaries } from "./context-usage.js";
|
|
5
|
-
import type { StatusLineSettings } from "./types.js";
|
|
5
|
+
import type { StatusLineSettings, StatusResetExpiry } from "./types.js";
|
|
6
6
|
export interface StatusAccountIdentity {
|
|
7
7
|
accountId?: string;
|
|
8
8
|
email?: string;
|
|
@@ -126,6 +126,9 @@ export interface StatusLineHost<TSession extends StatusLineSession = StatusLineS
|
|
|
126
126
|
}>;
|
|
127
127
|
calculateTokensPerSecond(messages: readonly AgentMessage[], isStreaming: boolean): number | null;
|
|
128
128
|
limitMatchesActiveAccount(report: UsageReport, limit: UsageLimit, identity: StatusAccountIdentity): boolean;
|
|
129
|
+
classifyResetExpiry?(report: UsageReport, nowMs: number): StatusResetExpiry | undefined;
|
|
130
|
+
/** One-line warning for saved resets anywhere in the pool that expire within 24 hours. */
|
|
131
|
+
resetExpiryNotice?(reports: readonly UsageReport[], nowMs: number): string | undefined;
|
|
129
132
|
computeCompactionBoundaries(session: TSession, contextWindow: number, model?: Model): CompactionBoundaries | null;
|
|
130
133
|
}
|
|
131
134
|
export interface FooterHost {
|
|
@@ -223,9 +223,18 @@ export interface SegmentContext {
|
|
|
223
223
|
expiryHours?: number;
|
|
224
224
|
expired?: boolean;
|
|
225
225
|
unavailableReason?: string;
|
|
226
|
+
expiring?: StatusResetExpiry;
|
|
226
227
|
};
|
|
227
228
|
} | null;
|
|
228
229
|
}
|
|
230
|
+
/** How close an account's saved resets are to expiring, when it is worth a warning. */
|
|
231
|
+
export interface StatusResetExpiry {
|
|
232
|
+
/** `soon`: within 7 days; `imminent`: within 24 hours. */
|
|
233
|
+
tier: "soon" | "imminent";
|
|
234
|
+
count: number;
|
|
235
|
+
/** Expiry of the reset the warning is about (epoch ms); it can be later than the soonest banked one. */
|
|
236
|
+
expiresAtMs: number;
|
|
237
|
+
}
|
|
229
238
|
export interface RenderedSegment {
|
|
230
239
|
content: string;
|
|
231
240
|
visible: boolean;
|
|
@@ -245,8 +254,8 @@ export interface SegmentView {
|
|
|
245
254
|
}
|
|
246
255
|
/**
|
|
247
256
|
* The status line's facts for the native composer. A TSP terminal shows no
|
|
248
|
-
* status strip: the tab title carries the session, the pane header the path
|
|
249
|
-
* and
|
|
257
|
+
* status strip: the tab title carries the session, the pane header the path,
|
|
258
|
+
* and the composer the rest (the git branch among its facts).
|
|
250
259
|
*/
|
|
251
260
|
export interface ComposerFacts {
|
|
252
261
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HangulCompatibilityJamoWidth } from "./utils.js";
|
|
2
2
|
export * from "./terminal-multiplexer.js";
|
|
3
|
-
export {
|
|
3
|
+
export { wrapTmuxPassthrough } from "./tmux.js";
|
|
4
4
|
export declare enum ImageProtocol {
|
|
5
5
|
Kitty = "\u001B_G",
|
|
6
6
|
Iterm2 = "\u001B]1337;File=",
|
|
@@ -55,12 +55,6 @@ export declare class TerminalInfo {
|
|
|
55
55
|
formatNotification(message: string | TerminalNotification): string;
|
|
56
56
|
sendNotification(message: string | TerminalNotification): void;
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Whether the agent process is running inside a Zellij session. Read fresh on
|
|
60
|
-
* each call (like {@link isInsideTmux}) so a session attached/detached mid-run
|
|
61
|
-
* is observed and tests can toggle `Bun.env.ZELLIJ` per case.
|
|
62
|
-
*/
|
|
63
|
-
export declare function isInsideZellij(env?: NodeJS.ProcessEnv): boolean;
|
|
64
58
|
/**
|
|
65
59
|
* Whether the agent process runs in an SSH session, so the terminal emulator
|
|
66
60
|
* is remote and host-local input/keyboard modes cannot be assumed.
|
|
@@ -96,12 +90,12 @@ export declare function synchronizedOutputUserOverride(env?: NodeJS.ProcessEnv):
|
|
|
96
90
|
* 2. Positive `TERM_FEATURES` advertisement (`Sy`) — survives SSH/mux wrapping.
|
|
97
91
|
* 3. Windows Terminal (1.24+) via `WT_SESSION`, on native win32 and the
|
|
98
92
|
* WSL/SSH-fronted host alike.
|
|
99
|
-
* 4.
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* composite as dirty-row patches — the live viewport tears, with
|
|
104
|
-
* frozen while only the bottom refreshes.
|
|
93
|
+
* 4. A multiplexer session whose pane VTE honors DEC 2026 regardless of its
|
|
94
|
+
* DECRQM reply (Herdr's libghostty pane). Such a multiplexer still owns
|
|
95
|
+
* the grid, so leaked kitty/ghostty identities cannot enable placeholder
|
|
96
|
+
* graphics, but leaving sync off lets CUP-diff paints and split write(2)
|
|
97
|
+
* chunks composite as dirty-row patches — the live viewport tears, with
|
|
98
|
+
* the top frozen while only the bottom refreshes.
|
|
105
99
|
* 5. Known direct terminals with confirmed support. SSH does *not* disable —
|
|
106
100
|
* DEC 2026 passes through SSH when the outer terminal honors it.
|
|
107
101
|
* 6. Everything else starts off, including risky multiplexers; the runtime
|
|
@@ -159,27 +153,25 @@ export declare function hyperlinksUserOverride(env?: NodeJS.ProcessEnv): boolean
|
|
|
159
153
|
* Policy (highest precedence first):
|
|
160
154
|
* 1. Explicit user override (`PI_NO_HYPERLINKS=1` off, `PI_FORCE_HYPERLINKS=1`
|
|
161
155
|
* on). Opt-out wins ties.
|
|
162
|
-
* 2.
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
156
|
+
* 2. Every multiplexer session with a hyperlink policy renders OSC 8 itself
|
|
157
|
+
* (`render`, e.g. Herdr): on. Herdr hides the outer terminal
|
|
158
|
+
* (`TERM=xterm-256color`, no `TERM_PROGRAM`), so the outer terminal's
|
|
159
|
+
* support does not matter.
|
|
166
160
|
* 3. Static terminal capability — terminals whose {@link TerminalInfo} marks
|
|
167
161
|
* `hyperlinks: false` (e.g. `base`) stay off unless the user forced on.
|
|
168
|
-
* 4.
|
|
169
|
-
*
|
|
170
|
-
* 5.
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* 7.
|
|
181
|
-
* no version available, so off.
|
|
182
|
-
* 8. Otherwise honor the static terminal capability.
|
|
162
|
+
* 4. A session that never forwards OSC 8 (`drop`, e.g. GNU screen's `STY`)
|
|
163
|
+
* always off, even when a forwarding multiplexer is also present.
|
|
164
|
+
* 5. Forwarding sessions (`forward`, e.g. `TMUX`): enabled when every one
|
|
165
|
+
* self-reports at least its forwarding version via `TERM_PROGRAM` /
|
|
166
|
+
* `TERM_PROGRAM_VERSION` (tmux 3.4). Older or unknown versions stay off;
|
|
167
|
+
* on outer terminals without the feature configured, tmux silently drops
|
|
168
|
+
* the sequence. Checked before the TERM heuristic because tmux's
|
|
169
|
+
* historical `default-terminal` is `screen-256color`, so `TERM=screen*`
|
|
170
|
+
* inside a tmux session must NOT short-circuit to off.
|
|
171
|
+
* 6. TERM naming a multiplexer whose session markers were stripped: off,
|
|
172
|
+
* since no session proves the multiplexer forwards OSC 8 (screen never
|
|
173
|
+
* does; tmux has no version to check).
|
|
174
|
+
* 7. Otherwise honor the static terminal capability.
|
|
183
175
|
*/
|
|
184
176
|
export declare function shouldEnableHyperlinksByDefault(env?: NodeJS.ProcessEnv, terminalId?: TerminalId): boolean;
|
|
185
177
|
/**
|
|
@@ -1,20 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function isInsideHerdr(env?: NodeJS.ProcessEnv): boolean;
|
|
3
|
-
/** Terminal multiplexers omp recognizes as owning the screen grid. */
|
|
4
|
-
export type TerminalMultiplexer = "herdr" | "tmux" | "screen" | "zellij" | "cmux" | "wmux";
|
|
1
|
+
import type { TerminalMultiplexerModule, TerminalMultiplexerNotificationRequest } from "./multiplexers/types.js";
|
|
5
2
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* Every multiplexer omp recognizes, in classification order within each
|
|
4
|
+
* precedence tier. Adding a multiplexer means adding its module here.
|
|
5
|
+
*/
|
|
6
|
+
declare const registry: readonly [{
|
|
7
|
+
readonly id: "herdr";
|
|
8
|
+
readonly precedence: "session";
|
|
9
|
+
readonly sessionEnvKeys: readonly ["HERDR_ENV", "HERDR_PANE_ID", "HERDR_TAB_ID", "HERDR_WORKSPACE_ID"];
|
|
10
|
+
readonly ownsScreenGrid: true;
|
|
11
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
12
|
+
readonly notifier: {
|
|
13
|
+
readonly tier: "pane";
|
|
14
|
+
readonly send: ({ message, env }: TerminalMultiplexerNotificationRequest) => boolean;
|
|
15
|
+
};
|
|
16
|
+
readonly hyperlinks: "render";
|
|
17
|
+
readonly honorsSynchronizedOutput: true;
|
|
18
|
+
readonly imagesRequireOverride: true;
|
|
19
|
+
}, {
|
|
20
|
+
readonly id: "tmux";
|
|
21
|
+
readonly precedence: "session";
|
|
22
|
+
readonly sessionEnvKeys: readonly ["TMUX"];
|
|
23
|
+
readonly termPrefix: "tmux";
|
|
24
|
+
readonly ownsScreenGrid: true;
|
|
25
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
26
|
+
readonly notifier: {
|
|
27
|
+
readonly tier: "inBand";
|
|
28
|
+
readonly send: ({ sequence, write }: TerminalMultiplexerNotificationRequest) => boolean;
|
|
29
|
+
};
|
|
30
|
+
readonly hyperlinks: {
|
|
31
|
+
readonly forward: {
|
|
32
|
+
readonly termProgram: "tmux";
|
|
33
|
+
readonly major: 3;
|
|
34
|
+
readonly minor: 4;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
readonly backgroundColorCache: {
|
|
38
|
+
readonly passthrough: typeof import("./tmux.js").wrapTmuxPassthrough;
|
|
39
|
+
readonly settleMs: 100;
|
|
40
|
+
};
|
|
41
|
+
readonly expandsRepPadding: true;
|
|
42
|
+
readonly expiresSynchronizedOutput: true;
|
|
43
|
+
readonly altRestoreEndsSynchronizedOutput: true;
|
|
44
|
+
readonly growsBeforeSigwinch: true;
|
|
45
|
+
}, {
|
|
46
|
+
readonly id: "screen";
|
|
47
|
+
readonly precedence: "session";
|
|
48
|
+
readonly sessionEnvKeys: readonly ["STY"];
|
|
49
|
+
readonly termPrefix: "screen";
|
|
50
|
+
readonly ownsScreenGrid: true;
|
|
51
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
52
|
+
readonly hyperlinks: "drop";
|
|
53
|
+
}, {
|
|
54
|
+
readonly id: "zellij";
|
|
55
|
+
readonly precedence: "session";
|
|
56
|
+
readonly sessionEnvKeys: readonly ["ZELLIJ"];
|
|
57
|
+
readonly ownsScreenGrid: true;
|
|
58
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
59
|
+
readonly notifier: {
|
|
60
|
+
readonly tier: "inBand";
|
|
61
|
+
readonly send: ({ sequence, write }: TerminalMultiplexerNotificationRequest) => boolean;
|
|
62
|
+
};
|
|
63
|
+
readonly backgroundQueryBrokenOn: readonly ["darwin"];
|
|
64
|
+
}, {
|
|
65
|
+
readonly id: "cmux";
|
|
66
|
+
readonly precedence: "session";
|
|
67
|
+
readonly sessionEnvKeys: readonly ["CMUX_WORKSPACE_ID", "CMUX_SURFACE_ID", "CMUX_REMOTE_TRANSPORT"];
|
|
68
|
+
readonly ownsScreenGrid: true;
|
|
69
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
70
|
+
readonly notifier: {
|
|
71
|
+
readonly tier: "surface";
|
|
72
|
+
readonly send: ({ message, env }: TerminalMultiplexerNotificationRequest) => boolean;
|
|
73
|
+
};
|
|
74
|
+
}, {
|
|
75
|
+
readonly id: "wmux";
|
|
76
|
+
readonly precedence: "session";
|
|
77
|
+
readonly sessionEnvKeys: readonly ["WMUX", "WMUX_SURFACE_ID"];
|
|
78
|
+
readonly ownsScreenGrid: true;
|
|
79
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
80
|
+
}, {
|
|
81
|
+
readonly id: "orca";
|
|
82
|
+
readonly precedence: "outerApp";
|
|
83
|
+
readonly sessionEnvKeys: readonly ["ORCA_PANE_KEY", "ORCA_WORKTREE_ID"];
|
|
84
|
+
readonly ownsScreenGrid: false;
|
|
85
|
+
readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
|
|
86
|
+
}];
|
|
87
|
+
/** Terminal multiplexers omp recognizes. */
|
|
88
|
+
export type TerminalMultiplexer = (typeof registry)[number]["id"];
|
|
89
|
+
/** Every environment variable multiplexer classification reads, including the TERM fallback. */
|
|
90
|
+
export declare const TERMINAL_MULTIPLEXER_ENV_KEYS: readonly string[];
|
|
91
|
+
/**
|
|
92
|
+
* Whether an explicit session marker identifies the current provider.
|
|
93
|
+
*
|
|
94
|
+
* TERM is intentionally excluded: it is a classification fallback, not proof
|
|
95
|
+
* that a particular multiplexer session owns the current grid.
|
|
96
|
+
*/
|
|
97
|
+
export declare function hasTerminalMultiplexerSession(multiplexer: TerminalMultiplexer, env?: NodeJS.ProcessEnv): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Every multiplexer whose explicit session markers are present, in registry
|
|
100
|
+
* order. Nested sessions all appear; TERM is not consulted.
|
|
101
|
+
*/
|
|
102
|
+
export declare function terminalMultiplexerSessions(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer>[];
|
|
103
|
+
/**
|
|
104
|
+
* The multiplexer TERM names, whether or not its session markers survived.
|
|
105
|
+
* This is classification's TERM fallback; session markers are not consulted.
|
|
106
|
+
*/
|
|
107
|
+
export declare function terminalMultiplexerForTerm(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer> | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Registry entry for the multiplexer hosting the current process, or
|
|
110
|
+
* `undefined` for a direct terminal. Same precedence as
|
|
111
|
+
* {@link classifyTerminalMultiplexer}.
|
|
112
|
+
*/
|
|
113
|
+
export declare function classifyTerminalMultiplexerModule(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer> | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* Classify which terminal multiplexer hosts the current process, or `null` for
|
|
116
|
+
* a direct terminal. Single source of truth for both the render-path gate
|
|
8
117
|
* (`isInsideTerminalMultiplexer`) and the debug snapshot label.
|
|
9
118
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* overrides and can be set outside a CMUX/WMUX terminal. wmux is a Windows
|
|
15
|
-
* multiplexer (Electron + xterm.js) modeled on cmux/herdr that repaints its
|
|
16
|
-
* pane in place and exports WMUX=1 plus a native WMUX_SURFACE_ID.
|
|
119
|
+
* Session markers are authoritative. TERM can also survive when those markers
|
|
120
|
+
* are stripped (`sudo` without -E, `su`, env-sanitizing launchers/ssh), so a
|
|
121
|
+
* `tmux`/`screen` TERM prefix comes next. Outer applications such as Orca rank
|
|
122
|
+
* last so a multiplexer running inside them wins.
|
|
17
123
|
*/
|
|
18
124
|
export declare function classifyTerminalMultiplexer(env?: NodeJS.ProcessEnv): TerminalMultiplexer | null;
|
|
19
|
-
/** True when
|
|
125
|
+
/** True when the classified multiplexer owns the current screen grid. */
|
|
20
126
|
export declare function isInsideTerminalMultiplexer(env?: NodeJS.ProcessEnv): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Offer a notification to every active session's notifier, innermost tier
|
|
129
|
+
* first. Returns whether one delivered it; otherwise the terminal fallback
|
|
130
|
+
* applies unchanged.
|
|
131
|
+
*/
|
|
132
|
+
export declare function routeTerminalMultiplexerNotification(request: TerminalMultiplexerNotificationRequest): boolean;
|
|
133
|
+
export {};
|
package/dist/types/terminal.d.ts
CHANGED
|
@@ -230,6 +230,12 @@ export interface Terminal {
|
|
|
230
230
|
* `status` is the DECRPM value when the terminal answered DECRQM.
|
|
231
231
|
*/
|
|
232
232
|
onPrivateModeReport?(callback: PrivateModeReportHandler): void;
|
|
233
|
+
/**
|
|
234
|
+
* Report whether DA1 advertises SIXEL (attribute 4), replaying the latest
|
|
235
|
+
* advertisement to late subscribers. A missing attribute does not rule out
|
|
236
|
+
* support discovered through another graphics query.
|
|
237
|
+
*/
|
|
238
|
+
onSixelSupport?(callback: (supported: boolean) => void): void;
|
|
233
239
|
/**
|
|
234
240
|
* Register a callback fired once the startup Glyph Protocol handshake
|
|
235
241
|
* resolves (see {@link GlyphProtocolReportHandler}). A subscriber that
|
|
@@ -298,10 +304,11 @@ export declare class ProcessTerminal implements Terminal {
|
|
|
298
304
|
onAppearanceReport(callback: (appearance: TerminalAppearance, requestToken?: TerminalAppearanceRequestToken) => void): () => void;
|
|
299
305
|
/**
|
|
300
306
|
* Re-query the terminal background through the startup DA1-sentinel FIFO,
|
|
301
|
-
* pending/queued gating, parsing, dedup, and appearance callbacks. Inside
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
307
|
+
* pending/queued gating, parsing, dedup, and appearance callbacks. Inside a
|
|
308
|
+
* multiplexer that answers OSC 11 from a cache (tmux), only this explicit
|
|
309
|
+
* path first passes an OSC 11 query to the outer terminal, waits briefly for
|
|
310
|
+
* the multiplexer to consume the response into its cache, then reads that
|
|
311
|
+
* cache with a direct query. The outer query deliberately has
|
|
305
312
|
* no DA1 sentinel: multiplexers can decode a fragmented DA1 response as a key
|
|
306
313
|
* sequence and leak the remaining bytes into the editor. Startup and Mode 2031
|
|
307
314
|
* probes remain direct. Suppressed while inactive, headless, or after teardown.
|
|
@@ -309,6 +316,7 @@ export declare class ProcessTerminal implements Terminal {
|
|
|
309
316
|
refreshAppearance(requestToken?: TerminalAppearanceRequestToken): TerminalAppearanceRequestToken | void;
|
|
310
317
|
onPrivateModeReport(callback: PrivateModeReportHandler): void;
|
|
311
318
|
onGlyphProtocolReport(callback: GlyphProtocolReportHandler): void;
|
|
319
|
+
onSixelSupport(callback: (supported: boolean) => void): void;
|
|
312
320
|
onTspHello(callback: TspHelloHandler): void;
|
|
313
321
|
get tspProbePending(): boolean;
|
|
314
322
|
get tspExpected(): boolean;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { SpinnerFramesOverride } from "./symbols.js";
|
|
2
2
|
export type ColorValue = string | number;
|
|
3
|
+
/**
|
|
4
|
+
* Tokens a theme is allowed to omit. They resolve to the terminal default
|
|
5
|
+
* foreground, so `Theme.fg()` stays total for callers that paint a token a theme
|
|
6
|
+
* never declared (e.g. a `modelTags.<role>.color` reference) while
|
|
7
|
+
* `Theme.hasColor()` still reports them as unset.
|
|
8
|
+
*/
|
|
9
|
+
export declare const OPTIONAL_THEME_COLOR_RECORD: {
|
|
10
|
+
assistantMessageText: true;
|
|
11
|
+
};
|
|
3
12
|
export interface ThemeJson {
|
|
4
13
|
$schema?: string;
|
|
5
14
|
name: string;
|
|
6
15
|
vars?: Record<string, ColorValue>;
|
|
7
|
-
colors: Omit<Record<ThemeColor | ThemeBg, ColorValue>, "thinkingMax"> & {
|
|
16
|
+
colors: Omit<Record<ThemeColor | ThemeBg, ColorValue>, "thinkingMax" | keyof typeof OPTIONAL_THEME_COLOR_RECORD> & Partial<Record<keyof typeof OPTIONAL_THEME_COLOR_RECORD, ColorValue>> & {
|
|
8
17
|
thinkingMax?: ColorValue;
|
|
9
18
|
};
|
|
10
19
|
export?: {
|
|
@@ -36,7 +45,7 @@ export interface ThemeJson {
|
|
|
36
45
|
spinnerFrames?: SpinnerFramesOverride;
|
|
37
46
|
};
|
|
38
47
|
}
|
|
39
|
-
export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "thinkingMax" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
|
|
48
|
+
export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "assistantMessageText" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "thinkingMax" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
|
|
40
49
|
/** Check if a string is a valid ThemeColor value */
|
|
41
50
|
export declare function isValidThemeColor(color: string): color is ThemeColor;
|
|
42
51
|
export type ThemeBg = "selectedBg" | "userMessageBg" | "customMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg" | "statusLineBg";
|
|
@@ -54,6 +54,13 @@ export declare class Theme {
|
|
|
54
54
|
* against. Built once per instance and frozen; callers share the object.
|
|
55
55
|
*/
|
|
56
56
|
get sessionAccentInputs(): SessionAccentTheme;
|
|
57
|
+
/**
|
|
58
|
+
* True when the theme paints `color` with a real foreground — i.e. the token
|
|
59
|
+
* exists and is not the empty string (terminal default, `\x1b[39m`). Optional
|
|
60
|
+
* tokens absent from the theme JSON are also false. Callers use this to keep
|
|
61
|
+
* terminal-default behavior byte-for-byte when an optional token is unset.
|
|
62
|
+
*/
|
|
63
|
+
hasColor(color: ThemeColor): boolean;
|
|
57
64
|
fg(color: ThemeColor, text: string): string;
|
|
58
65
|
/** Apply a foreground, replacing terminal-default tokens with the theme's contrast-safe fallback. */
|
|
59
66
|
fgResolved(color: ThemeColor, text: string): string;
|
package/dist/types/tmux.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function isInsideTmux(env?: NodeJS.ProcessEnv): boolean;
|
|
3
|
-
/** Wrap a control sequence in tmux's DCS passthrough envelope. */
|
|
4
|
-
export declare function wrapTmuxPassthrough(payload: string): string;
|
|
1
|
+
export { wrapTmuxPassthrough } from "./multiplexers/tmux.js";
|
|
5
2
|
/** Pass a control sequence through tmux, leaving direct-terminal output unchanged. */
|
|
6
3
|
export declare function wrapTmuxPassthroughIfNeeded(payload: string, env?: NodeJS.ProcessEnv): string;
|
|
7
4
|
/**
|
|
@@ -24,6 +24,8 @@ export interface EvalCellResult {
|
|
|
24
24
|
durationMs?: number;
|
|
25
25
|
exitCode?: number;
|
|
26
26
|
statusEvents?: EvalStatusEvent[];
|
|
27
|
+
/** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
|
|
28
|
+
statusEventsElided?: number;
|
|
27
29
|
hasMarkdown?: boolean;
|
|
28
30
|
}
|
|
29
31
|
/** Tool result detail object surfaced to the UI/transcript. */
|
|
@@ -32,6 +34,8 @@ export interface EvalToolDetails {
|
|
|
32
34
|
jsonOutputs?: unknown[];
|
|
33
35
|
images?: ImageContent[];
|
|
34
36
|
statusEvents?: EvalStatusEvent[];
|
|
37
|
+
/** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
|
|
38
|
+
statusEventsElided?: number;
|
|
35
39
|
isError?: boolean;
|
|
36
40
|
meta?: OutputMeta;
|
|
37
41
|
/** First backend that produced cells. Kept for transcript compatibility. */
|
|
@@ -74,13 +78,28 @@ export declare function statusEventKey(event: {
|
|
|
74
78
|
op: string;
|
|
75
79
|
[key: string]: unknown;
|
|
76
80
|
}): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Discrete status events a log keeps. A cell polling a helper in a loop emits
|
|
83
|
+
* one event per call (hundreds of thousands), and every live update and the
|
|
84
|
+
* persisted tool result would otherwise carry them all.
|
|
85
|
+
*/
|
|
86
|
+
export declare const MAX_STATUS_EVENTS = 200;
|
|
87
|
+
/** A status event list plus the count of discrete events dropped from its front. */
|
|
88
|
+
export type StatusEventLog = Pick<EvalCellResult, "statusEvents" | "statusEventsElided">;
|
|
77
89
|
/**
|
|
78
90
|
* Append or replace a status event. Progress snapshots (see
|
|
79
91
|
* {@link statusEventKey}) coalesce in place, preserving first-seen order; every
|
|
80
|
-
* other op is a discrete action and simply appends.
|
|
81
|
-
* list bounded even when a subagent or batch emits hundreds of progress ticks.
|
|
92
|
+
* other op is a discrete action and simply appends.
|
|
82
93
|
*/
|
|
83
94
|
export declare function upsertStatusEvent(events: EvalStatusEvent[], event: EvalStatusEvent): void;
|
|
95
|
+
/**
|
|
96
|
+
* {@link upsertStatusEvent} into a bounded log. Past {@link MAX_STATUS_EVENTS},
|
|
97
|
+
* the oldest discrete event is dropped and counted. Snapshots stay, since agent
|
|
98
|
+
* cards read them, and so does the newest committed `todo` result, which the
|
|
99
|
+
* session todo panel refreshes from. Renderers already show only the newest
|
|
100
|
+
* events behind an "… N earlier" row.
|
|
101
|
+
*/
|
|
102
|
+
export declare function recordStatusEvent(log: StatusEventLog, event: EvalStatusEvent): void;
|
|
84
103
|
/** Render eval code cells, structured display output, and progress events. */
|
|
85
104
|
export declare const evalToolRenderer: {
|
|
86
105
|
animatedPendingPreview: true;
|
|
@@ -84,12 +84,22 @@ export interface LimitsMeta {
|
|
|
84
84
|
reached: number;
|
|
85
85
|
suggestion: number;
|
|
86
86
|
};
|
|
87
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* `unit` may be absent in sessions persisted before it was recorded. `lines` is
|
|
89
|
+
* the first-to-last range of cut lines, and `selectorBase` the target a
|
|
90
|
+
* `:raw:<line>-<line>` selector reads one of them whole from (an artifact's
|
|
91
|
+
* `artifact://<id>` stands in when absent).
|
|
92
|
+
*/
|
|
88
93
|
columnTruncated?: {
|
|
89
94
|
maxColumn: number;
|
|
90
95
|
unit?: "bytes" | "chars";
|
|
91
96
|
artifactId?: string;
|
|
92
97
|
artifactElidedBytes?: number;
|
|
98
|
+
lines?: {
|
|
99
|
+
first: number;
|
|
100
|
+
last: number;
|
|
101
|
+
};
|
|
102
|
+
selectorBase?: string;
|
|
93
103
|
};
|
|
94
104
|
}
|
|
95
105
|
/**
|
|
@@ -31,6 +31,15 @@ export interface OutputSummary {
|
|
|
31
31
|
columnDroppedBytes?: number;
|
|
32
32
|
/** Number of distinct lines that hit the per-line column cap. */
|
|
33
33
|
columnTruncatedLines?: number;
|
|
34
|
+
/**
|
|
35
|
+
* 1-indexed first and last lines the column cap cut, numbered as in the
|
|
36
|
+
* artifact. Absent when the numbering cannot match the artifact (an inline
|
|
37
|
+
* substitute was capped, or `replace()` rewrote the buffer).
|
|
38
|
+
*/
|
|
39
|
+
columnTruncatedRange?: {
|
|
40
|
+
first: number;
|
|
41
|
+
last: number;
|
|
42
|
+
};
|
|
34
43
|
/** Configured per-line column cap in effect (UTF-8 bytes), when > 0. */
|
|
35
44
|
columnMax?: number;
|
|
36
45
|
/** Artifact ID for internal URL access (artifact://<id>) when truncated */
|
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.
|
|
4
|
+
"version": "18.9.0",
|
|
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.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "18.
|
|
46
|
-
"@oh-my-pi/pi-ai": "18.
|
|
47
|
-
"@oh-my-pi/pi-catalog": "18.
|
|
48
|
-
"@oh-my-pi/pi-natives": "18.
|
|
49
|
-
"@oh-my-pi/pi-utils": "18.
|
|
50
|
-
"@oh-my-pi/pi-wire": "18.
|
|
51
|
-
"@oh-my-pi/snapcompact": "18.
|
|
44
|
+
"@oh-my-pi/omptype": "18.9.0",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "18.9.0",
|
|
46
|
+
"@oh-my-pi/pi-ai": "18.9.0",
|
|
47
|
+
"@oh-my-pi/pi-catalog": "18.9.0",
|
|
48
|
+
"@oh-my-pi/pi-natives": "18.9.0",
|
|
49
|
+
"@oh-my-pi/pi-utils": "18.9.0",
|
|
50
|
+
"@oh-my-pi/pi-wire": "18.9.0",
|
|
51
|
+
"@oh-my-pi/snapcompact": "18.9.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"kitty-vt-wasm": "^0.2.0"
|