@oh-my-pi/pi-tui 18.4.1 → 18.4.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 +34 -0
- package/dist/types/chat/thinking-display.d.ts +2 -0
- package/dist/types/chrome/transcript-container.d.ts +15 -1
- package/dist/types/components/editor.d.ts +5 -0
- package/dist/types/loop-watchdog.d.ts +9 -0
- package/dist/types/overlays/model-browser.d.ts +15 -0
- package/dist/types/overlays/model-picker.d.ts +2 -1
- package/dist/types/overlays/rewind-selector.d.ts +2 -1
- package/dist/types/prompt/composer-attachments.d.ts +7 -0
- package/dist/types/prompt/model-mention-autocomplete.d.ts +4 -1
- package/dist/types/render/width-aware-text.d.ts +6 -0
- package/dist/types/setup/scenes/sign-in.d.ts +9 -9
- package/dist/types/setup/scenes/types.d.ts +0 -26
- package/dist/types/stdin-buffer.d.ts +10 -7
- package/dist/types/terminal.d.ts +16 -0
- package/dist/types/theme/color.d.ts +1 -0
- package/dist/types/theme/session-color.d.ts +3 -3
- package/dist/types/theme/shimmer.d.ts +1 -1
- package/dist/types/theme/theme-class.d.ts +1 -1
- package/dist/types/tools/web-search-types.d.ts +90 -0
- package/dist/types/tools/web-search.d.ts +1 -168
- package/dist/types/tui.d.ts +3 -2
- package/package.json +9 -9
- package/src/chat/assistant-message.ts +192 -40
- package/src/chat/thinking-display.ts +73 -11
- package/src/chat/tool-execution.ts +24 -4
- package/src/chrome/transcript-container.ts +178 -31
- package/src/components/editor.ts +51 -15
- package/src/components/image.ts +15 -7
- package/src/components/loader.ts +37 -17
- package/src/components/markdown.ts +110 -56
- package/src/loop-watchdog.ts +38 -10
- package/src/overlays/agent-hub.ts +16 -6
- package/src/overlays/copy-selector.ts +5 -0
- package/src/overlays/model-browser.ts +106 -25
- package/src/overlays/model-picker.ts +9 -6
- package/src/overlays/rewind-selector.ts +10 -2
- package/src/overlays/settings-selector.ts +2 -10
- package/src/prompt/composer-attachments.ts +54 -7
- package/src/prompt/composer.ts +5 -2
- package/src/prompt/custom-editor.ts +24 -6
- package/src/prompt/model-mention-autocomplete.ts +22 -10
- package/src/render/width-aware-text.ts +9 -0
- package/src/setup/scenes/sign-in.ts +17 -12
- package/src/setup/scenes/types.ts +0 -27
- package/src/setup/wizard.ts +1 -1
- package/src/status-line/component.ts +229 -134
- package/src/status-line/segments.ts +34 -29
- package/src/stdin-buffer.ts +27 -21
- package/src/terminal.ts +60 -20
- package/src/theme/color.ts +15 -0
- package/src/theme/mermaid-cache.ts +10 -1
- package/src/theme/session-color.ts +26 -4
- package/src/theme/shimmer.ts +55 -76
- package/src/theme/theme-class.ts +29 -12
- package/src/theme/tui-adapters.ts +14 -1
- package/src/tools/bash.ts +53 -13
- package/src/tools/edit.ts +110 -29
- package/src/tools/streaming-output.ts +79 -16
- package/src/tools/web-search-types.ts +99 -0
- package/src/tools/web-search.ts +1 -172
- package/src/tui.ts +143 -113
- package/src/utils.ts +15 -0
- package/dist/types/setup/scenes/providers.d.ts +0 -3
- package/dist/types/setup/scenes/web-search.d.ts +0 -22
- package/src/setup/scenes/providers.ts +0 -110
- package/src/setup/scenes/web-search.ts +0 -165
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.4.3] - 2026-09-28
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Reduced frame spikes and memory while long assistant replies retire into scrollback mid-stream: retiring rows no longer re-renders the whole published reply once per row, and the transcript no longer rescans the entire session history every frame ([#13650](https://github.com/can1357/oh-my-pi/pull/13650) by [@H4vC](https://github.com/H4vC)).
|
|
10
|
+
- Reduced memory held by finished messages: streamed Markdown blocks release their streaming row caches, frozen lex tokens, and syntax-highlight streams when they finalize, and the Mermaid render cache is now size-bounded ([#13650](https://github.com/can1357/oh-my-pi/pull/13650) by [@H4vC](https://github.com/H4vC)).
|
|
11
|
+
- Reduced per-frame CPU while streaming Markdown, edit previews (header facts are reused across frames; replace previews process only the visible lines), bash previews (highlighting is deferred to paint and the highlight cache is size-bounded), interleaved thinking blocks, and the live bash/ssh output tail ([#13650](https://github.com/can1357/oh-my-pi/pull/13650) by [@H4vC](https://github.com/H4vC)).
|
|
12
|
+
- Changed git status refresh interval to 10 seconds and added generation tracking to avoid stale counts after HEAD moves
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fixed streaming bash previews showing fields that follow the `env` object (e.g. `command`) as environment assignments ([#13650](https://github.com/can1357/oh-my-pi/pull/13650) by [@H4vC](https://github.com/H4vC)).
|
|
17
|
+
- Fixed model picker latency by avoiding unnecessary catalog rebuilds
|
|
18
|
+
- Fixed the `@` completion popup showing a `Searching…` placeholder while a refreshed file search is pending; the popup now stays hidden until results arrive, and Escape is no longer swallowed by it
|
|
19
|
+
- Fixed multi-line IME and dictation input (for example, voice input in Ghostty or cmux) being sent as one message per line; it now lands in the prompt as a single multi-line draft, while Enter typed during a UI freeze still submits ([#13378](https://github.com/can1357/oh-my-pi/pull/13378) by [@goransh-walia](https://github.com/goransh-walia))
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
|
|
23
|
+
- Removed the setup wizard's "Web search" tab; the providers scene is now sign-in only, and web search is chosen through the `web` model role like other kind roles.
|
|
24
|
+
|
|
25
|
+
## [18.4.2] - 2026-09-28
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Optimized activity clock rendering by caching timestamp formatting strings
|
|
30
|
+
- Reduced CPU overhead during animated terminal redraws, transcript updates, inline-image bookkeeping, and status-line layout.
|
|
31
|
+
- Reduced per-keystroke CPU in `^` model-mention autocomplete and per-frame CPU while streaming (status line, live transcript blocks, tool cards, frame writes).
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Fixed the `@` completion popup swallowing Tab and cursor-movement keys while a narrowed filter matched nothing: with no candidate to accept they now fall through to their normal completion and cursor roles instead of being trapped ([#13046](https://github.com/can1357/oh-my-pi/pull/13046) by [@jchanghong023](https://github.com/jchanghong023)).
|
|
36
|
+
- Fixed the Esc-Esc rewind and fullscreen `/copy` selectors getting stuck at the oldest turn of a long session's recent tail; stepping past it now loads the earlier history
|
|
37
|
+
- Fixed the composer attachment band showing chip `#1` (and other prefix IDs) as still present when only `#10` remained in the prompt ([#13605](https://github.com/can1357/oh-my-pi/issues/13605))
|
|
38
|
+
|
|
5
39
|
## [18.4.1] - 2026-09-28
|
|
6
40
|
|
|
7
41
|
### Breaking Changes
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
/** Drop every memo slot so the next call recomputes from scratch. Tests only. */
|
|
3
|
+
export declare function resetThinkingDisplayCacheForTests(): void;
|
|
2
4
|
export declare function canonicalizeMessage(text: string | null | undefined): string;
|
|
3
5
|
/**
|
|
4
6
|
* Thinking text prepared for display. Both modes drop empty `<!-- -->`
|
|
@@ -96,6 +96,16 @@ export declare class TranscriptContainer extends Container {
|
|
|
96
96
|
* quit is pure write volume. An already offered replay batch stays valid.
|
|
97
97
|
*/
|
|
98
98
|
cancelReplay(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Open one composed frame: every live-block measurement until this frame's
|
|
101
|
+
* {@link renderViewport} returns renders against `frame` and is taken once,
|
|
102
|
+
* so the retirement peek and the viewport share each block's render.
|
|
103
|
+
*
|
|
104
|
+
* Callers MUST call {@link renderViewport} with the same `frame` in the same
|
|
105
|
+
* synchronous composition, without mutating any transcript block in
|
|
106
|
+
* between: the shared rows are only as fresh as that first measurement.
|
|
107
|
+
*/
|
|
108
|
+
beginFrame(frame: AnimationFrame): void;
|
|
99
109
|
/**
|
|
100
110
|
* Total rows the live, un-emitted tail occupies at `width`.
|
|
101
111
|
*
|
|
@@ -107,7 +117,11 @@ export declare class TranscriptContainer extends Container {
|
|
|
107
117
|
liveRowCount(width: number, limit?: number): number;
|
|
108
118
|
/** Block spans of the last `renderViewport` output, in output coordinates. Empty when the tail is empty. */
|
|
109
119
|
getLastViewportSpans(): readonly TranscriptViewportSpan[];
|
|
110
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Render the live tail, constrained to the supplied transcript height.
|
|
122
|
+
* Closes the frame {@link beginFrame} opened; a different `frame` discards
|
|
123
|
+
* its measurements first.
|
|
124
|
+
*/
|
|
111
125
|
renderViewport(width: number, rows: number, frame: AnimationFrame): readonly string[];
|
|
112
126
|
/** Offers stable-head emission or the shortest finalized prefix needed under pressure. */
|
|
113
127
|
peekFinalizedBatch(width: number, capacity: number): HistoryBatch | undefined;
|
|
@@ -278,5 +278,10 @@ export declare class Editor implements Component, Focusable {
|
|
|
278
278
|
* {@link getExpandedText}). Hosts that intercept large pastes through {@link onLargePaste} use
|
|
279
279
|
* this to re-insert a (possibly transformed) paste without re-triggering the interception hook. */
|
|
280
280
|
insertPaste(content: string): void;
|
|
281
|
+
/**
|
|
282
|
+
* Whether an autocomplete popup is on screen. An `@` list narrowed to no match
|
|
283
|
+
* while its refresh is pending stays open internally but is hidden, so it does
|
|
284
|
+
* not claim keys (Escape, Vim mode switches) meant for the editor or app.
|
|
285
|
+
*/
|
|
281
286
|
isShowingAutocomplete(): boolean;
|
|
282
287
|
}
|
|
@@ -45,5 +45,14 @@ export declare class LoopWatchdog {
|
|
|
45
45
|
constructor(options?: LoopWatchdogOptions);
|
|
46
46
|
start(): void;
|
|
47
47
|
stop(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the loop is blocked right now — the armed tick is already more
|
|
50
|
+
* than `thresholdMs` overdue — or a detected block ended within the last
|
|
51
|
+
* `thresholdMs`. Input read at such a moment may be keystrokes the block
|
|
52
|
+
* batched into one read. Resolves both orders in which a resumed loop can
|
|
53
|
+
* run the late tick and the queued stdin read. A suspended-process gap is
|
|
54
|
+
* not a stall, and a stopped watchdog never reports one.
|
|
55
|
+
*/
|
|
56
|
+
isStalled(): boolean;
|
|
48
57
|
}
|
|
49
58
|
export {};
|
|
@@ -37,6 +37,11 @@ export interface ResolvedModelRoleValue {
|
|
|
37
37
|
}
|
|
38
38
|
/** Host-provided preferences and model-role resolution for the browser. */
|
|
39
39
|
export interface ModelBrowserSource extends ModelRoleLookup {
|
|
40
|
+
/**
|
|
41
|
+
* Changes whenever any preference this source reads or resolves against changes,
|
|
42
|
+
* except the storage-backed `mruOrder` and `modelPerf`. Keys derived-scope caches.
|
|
43
|
+
*/
|
|
44
|
+
readonly revision: number;
|
|
40
45
|
readonly defaultThinkingLevel: string;
|
|
41
46
|
readonly modelProviderOrder: readonly string[];
|
|
42
47
|
readonly knownRoleIds: readonly string[];
|
|
@@ -104,6 +109,16 @@ export interface SessionModelScope {
|
|
|
104
109
|
}
|
|
105
110
|
/** Build the session picker's current scope without creating an interactive browser. */
|
|
106
111
|
export declare function buildSessionModelScope(settings: ModelBrowserSource, registry: ModelBrowserRegistry, scopedModels: ReadonlyArray<Model>): SessionModelScope;
|
|
112
|
+
/**
|
|
113
|
+
* {@link buildSessionModelScope} for per-keystroke callers: returns the same
|
|
114
|
+
* scope until the source revision, MRU order, scoped models, or the registry's
|
|
115
|
+
* available models, catalog, or load error change.
|
|
116
|
+
*/
|
|
117
|
+
export declare class SessionModelScopeCache {
|
|
118
|
+
#private;
|
|
119
|
+
constructor(settings: ModelBrowserSource, registry: ModelBrowserRegistry);
|
|
120
|
+
get(scopedModels: ReadonlyArray<Model>): SessionModelScope;
|
|
121
|
+
}
|
|
107
122
|
/** User affinity used to order search matches within one relevance tier. */
|
|
108
123
|
export interface SearchAffinity {
|
|
109
124
|
/** `provider/id` (lowercased) → rank; configured-role models first, then MRU. */
|
|
@@ -19,7 +19,8 @@ export interface ResolvedRoleModel {
|
|
|
19
19
|
}
|
|
20
20
|
/** Catalog refresh capability used by the session picker. */
|
|
21
21
|
export interface ModelPickerRegistry extends ModelBrowserRegistry {
|
|
22
|
-
|
|
22
|
+
/** Bring the catalog up to date without rebuilding a current one; `true` when the picker must re-read it. */
|
|
23
|
+
refreshIfStale(): Promise<boolean>;
|
|
23
24
|
}
|
|
24
25
|
export interface ModelPickerCallbacks {
|
|
25
26
|
/**
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
* variants at a fork and jump between user turns elsewhere, `f` opens a
|
|
23
23
|
* filter (typing narrows the current path to matching items; Esc leaves the
|
|
24
24
|
* filter with the selection kept), Enter rewinds to the outlined item, A loads
|
|
25
|
-
* earlier turns without changing selection
|
|
25
|
+
* earlier turns without changing selection (stepping above the oldest replayed
|
|
26
|
+
* turn loads them too), Esc cancels.
|
|
26
27
|
*/
|
|
27
28
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
28
29
|
import { type Component, type TUI } from "../index.js";
|
|
@@ -37,6 +37,13 @@ export declare function attachmentSgr(kind: ChipKind, n: number): string;
|
|
|
37
37
|
export declare const PLACEHOLDER_REGEX: RegExp;
|
|
38
38
|
/** Matches an expanded attachment marker, a compact attachment chip, or a skill chip. */
|
|
39
39
|
export declare const COMPOSER_TOKEN_REGEX: RegExp;
|
|
40
|
+
/**
|
|
41
|
+
* Attachment indices referenced by a composer buffer, per kind. Image/video count compact chips
|
|
42
|
+
* and expanded markers; paste counts compact chips only, since `[Paste #N]` markers number the
|
|
43
|
+
* base editor's separate paste buffer. Registered labels take precedence over theme glyphs so
|
|
44
|
+
* tokens created before a theme switch keep their kind; full numbers prevent `#1` matching `#10`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function referencedAttachments(text: string, recorded: ReadonlyMap<string, ChipKind>): Record<ChipKind, Set<number>>;
|
|
40
47
|
/** Add the registered model-chip labels to the composer placeholder matcher. */
|
|
41
48
|
export declare function composerTokenRegex(mentionLabels: Iterable<string>): RegExp;
|
|
42
49
|
/** Offsets image marker indices, including matching `attachment://` references. */
|
|
@@ -17,7 +17,10 @@ export declare function applyModelMentionCompletion(lines: string[], cursorLine:
|
|
|
17
17
|
cursorLine: number;
|
|
18
18
|
cursorCol: number;
|
|
19
19
|
};
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Create a session-scoped model candidate lookup using picker ordering. The
|
|
22
|
+
* scope and search affinity are reused across queries until their inputs change.
|
|
23
|
+
*/
|
|
21
24
|
export declare function createModelMentionSource(host: {
|
|
22
25
|
source: ModelBrowserSource;
|
|
23
26
|
registry: ModelBrowserRegistry;
|
|
@@ -19,5 +19,11 @@ export declare class WidthAwareText implements Component {
|
|
|
19
19
|
setCustomBgFn(customBgFn?: (text: string) => string): void;
|
|
20
20
|
setIgnoreTight(ignore: boolean): this;
|
|
21
21
|
invalidate(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Re-run the formatter on the next render because its inputs changed.
|
|
24
|
+
* Unlike {@link invalidate}, the inner `Text` keeps its wrap cache, so a
|
|
25
|
+
* reformat that yields the same string skips re-wrapping and re-tinting.
|
|
26
|
+
*/
|
|
27
|
+
reformat(): void;
|
|
22
28
|
render(width: number): readonly string[];
|
|
23
29
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { type SgrMouseEvent } from "../../mouse.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { SetupScene, SetupSceneController, SetupSceneHost } from "./types.js";
|
|
3
3
|
/**
|
|
4
|
-
* "Sign in"
|
|
5
|
-
* OAuth.
|
|
6
|
-
*
|
|
4
|
+
* "Sign in" scene: lets the user authenticate one or more model providers via
|
|
5
|
+
* OAuth. It never auto-advances the wizard — the user may sign in to several
|
|
6
|
+
* providers and then continue with Esc.
|
|
7
7
|
*/
|
|
8
|
-
export declare class
|
|
8
|
+
export declare class SignInScene implements SetupSceneController {
|
|
9
9
|
#private;
|
|
10
|
-
readonly
|
|
11
|
-
|
|
10
|
+
readonly title = "Sign in to your providers";
|
|
11
|
+
get subtitle(): string;
|
|
12
12
|
constructor(host: SetupSceneHost);
|
|
13
|
-
/** Modal while an OAuth flow is running so the scene won't switch tabs or finish. */
|
|
14
|
-
get modal(): boolean;
|
|
15
13
|
dispose(): void;
|
|
16
14
|
invalidate(): void;
|
|
17
15
|
handleInput(data: string): void;
|
|
@@ -19,3 +17,5 @@ export declare class SignInTab implements SetupTab {
|
|
|
19
17
|
routeMouse(event: SgrMouseEvent, line: number, col: number): void;
|
|
20
18
|
render(width: number, maxLines?: number): readonly string[];
|
|
21
19
|
}
|
|
20
|
+
/** Onboarding scene for provider sign-in. */
|
|
21
|
+
export declare const providersSetupScene: SetupScene;
|
|
@@ -5,7 +5,6 @@ import type { ComposerPreviewStatusSource } from "../../overlays/composer-shape-
|
|
|
5
5
|
import type { ComposerShape } from "../../overlays/composer-shape-registry.js";
|
|
6
6
|
import type { ModelBrowserSource } from "../../overlays/model-browser.js";
|
|
7
7
|
import type { SymbolPreset } from "../../theme/theme.js";
|
|
8
|
-
import type { SearchProviderId } from "../../tools/web-search.js";
|
|
9
8
|
import type { Component, TUI } from "../../tui.js";
|
|
10
9
|
/** Terminal capabilities used by setup overlays and the startup splash. */
|
|
11
10
|
export interface SetupUiHost {
|
|
@@ -21,7 +20,6 @@ export interface SetupHost extends SetupUiHost {
|
|
|
21
20
|
readonly composerShape: ComposerShape;
|
|
22
21
|
readonly symbolPreset: SymbolPreset;
|
|
23
22
|
readonly colorBlindMode: boolean;
|
|
24
|
-
readonly webSearchOrder: readonly string[];
|
|
25
23
|
readonly disabledProviders: readonly string[];
|
|
26
24
|
readonly authStorage: AuthStorage;
|
|
27
25
|
readonly modelSource: ModelBrowserSource;
|
|
@@ -37,8 +35,6 @@ export interface SetupHost extends SetupUiHost {
|
|
|
37
35
|
saveSymbolPreset(preset: SymbolPreset): void;
|
|
38
36
|
saveColorBlindMode(enabled: boolean): void;
|
|
39
37
|
saveTheme(mode: "dark" | "light", name: string): void;
|
|
40
|
-
isSearchProviderAvailable(id: SearchProviderId): Promise<boolean>;
|
|
41
|
-
saveSearchProvider(id: SearchProviderId | "auto"): void;
|
|
42
38
|
captureBrowserSession(request: OAuthBrowserSessionRequest, signal?: AbortSignal): Promise<string>;
|
|
43
39
|
copyToClipboard(text: string): Promise<void>;
|
|
44
40
|
openInBrowser(url: string): void;
|
|
@@ -78,28 +74,6 @@ export interface SetupSceneController extends Component {
|
|
|
78
74
|
*/
|
|
79
75
|
routeMouse?(event: SgrMouseEvent, line: number, col: number): void;
|
|
80
76
|
}
|
|
81
|
-
/**
|
|
82
|
-
* A single panel inside a tabbed setup scene. The host scene owns the tab bar
|
|
83
|
-
* and forwards rendering/input to the active tab.
|
|
84
|
-
*/
|
|
85
|
-
export interface SetupTab {
|
|
86
|
-
readonly id: string;
|
|
87
|
-
readonly label: string;
|
|
88
|
-
/**
|
|
89
|
-
* While `true` the tab owns all keyboard input (e.g. an in-progress OAuth
|
|
90
|
-
* login). The parent scene MUST NOT switch tabs or finish while modal.
|
|
91
|
-
*/
|
|
92
|
-
readonly modal: boolean;
|
|
93
|
-
/** See {@link SetupSceneController.render}: `maxLines` is the tab-local row budget. */
|
|
94
|
-
render(width: number, maxLines?: number): readonly string[];
|
|
95
|
-
handleInput(data: string): void;
|
|
96
|
-
invalidate(): void;
|
|
97
|
-
/** Called when the tab becomes active (including initial mount). */
|
|
98
|
-
onActivate?(): void;
|
|
99
|
-
/** Mouse routing at tab-local coordinates; see {@link SetupSceneController.routeMouse}. */
|
|
100
|
-
routeMouse?(event: SgrMouseEvent, line: number, col: number): void;
|
|
101
|
-
dispose(): void;
|
|
102
|
-
}
|
|
103
77
|
/** Versioned onboarding scene definition. */
|
|
104
78
|
export interface SetupScene {
|
|
105
79
|
id: string;
|
|
@@ -63,14 +63,17 @@ export declare class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
|
|
|
63
63
|
constructor(options?: StdinBufferOptions);
|
|
64
64
|
process(data: string | Buffer): void;
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* paste then always arrives wrapped, so
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
66
|
+
* Gate unbracketed raw-paste classification on event-loop responsiveness.
|
|
67
|
+
* Terminal installs a probe once DECRQM confirms bracketed-paste (mode
|
|
68
|
+
* 2004) support: a genuine paste then always arrives wrapped, so an
|
|
69
|
+
* unmarked multiline burst is either an input-method commit — IME,
|
|
70
|
+
* dictation, and emoji commits are typed input, never bracketed (#13344) —
|
|
71
|
+
* or keystrokes an event-loop stall batched into one read (#12540). A burst
|
|
72
|
+
* classified while `stalled()` reports a stall is replayed as the original
|
|
73
|
+
* keys so every Enter submits; otherwise it is delivered as one paste.
|
|
74
|
+
* `undefined` restores unconditional classification.
|
|
72
75
|
*/
|
|
73
|
-
|
|
76
|
+
setRawPasteStallProbe(stalled: (() => boolean) | undefined): void;
|
|
74
77
|
flush(): string[];
|
|
75
78
|
clear(): void;
|
|
76
79
|
getBuffer(): string;
|
package/dist/types/terminal.d.ts
CHANGED
|
@@ -96,6 +96,15 @@ export interface TerminalStartOptions {
|
|
|
96
96
|
* echoes even while module loading blocks the event loop.
|
|
97
97
|
*/
|
|
98
98
|
deferInput?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Reports whether the event loop is stalled or just recovered from a
|
|
101
|
+
* stall. Once the terminal confirms bracketed paste, an unmarked multiline
|
|
102
|
+
* burst is an input-method commit (IME, dictation) delivered as one paste
|
|
103
|
+
* on a responsive loop, but keystrokes a stall batched into one read —
|
|
104
|
+
* replayed as keys so Enter submits — while this returns true. Without a
|
|
105
|
+
* probe every such burst is treated as an input-method commit.
|
|
106
|
+
*/
|
|
107
|
+
isLoopStalled?: () => boolean;
|
|
99
108
|
}
|
|
100
109
|
/** Identity of an accepted explicit terminal appearance refresh request. */
|
|
101
110
|
export type TerminalAppearanceRequestToken = number;
|
|
@@ -276,6 +285,13 @@ export declare class ProcessTerminal implements Terminal {
|
|
|
276
285
|
stop(): void;
|
|
277
286
|
write(data: string): void;
|
|
278
287
|
get columns(): number;
|
|
288
|
+
/**
|
|
289
|
+
* With the output pump, a backlog bound at or below
|
|
290
|
+
* {@link STDOUT_BACKLOG_CLEAR_BYTES} is reported as-is instead of re-read:
|
|
291
|
+
* both consumers (the render gate and the stall watchdog) act only on a
|
|
292
|
+
* backlog above that level, so the bound already decides them and spares a
|
|
293
|
+
* native read on every frame.
|
|
294
|
+
*/
|
|
279
295
|
get pendingOutputBytes(): number;
|
|
280
296
|
get hostOwnsGridOnResize(): boolean;
|
|
281
297
|
get rows(): number;
|
|
@@ -5,6 +5,7 @@ export declare const FG_RESET = "\u001B[39m";
|
|
|
5
5
|
export declare const BG_RESET = "\u001B[49m";
|
|
6
6
|
/** Resolve theme color depth from the shared terminal capability model. */
|
|
7
7
|
export declare function detectColorMode(env?: NodeJS.ProcessEnv): ColorMode;
|
|
8
|
+
/** Convert a theme color to foreground SGR at the requested depth; throws for invalid colors. */
|
|
8
9
|
export declare function colorToAnsi(color: string, mode: ColorMode): string;
|
|
9
10
|
export declare function fgAnsi(color: string | number, mode: ColorMode): string;
|
|
10
11
|
export declare function bgAnsi(color: string | number, mode: ColorMode): string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/** Theme-derived inputs for {@link getSessionAccentHex}; see `Theme.sessionAccentInputs`. */
|
|
2
2
|
export interface SessionAccentTheme {
|
|
3
3
|
/** Theme accent hex; the session accent adopts its OKLCH lightness and chroma. */
|
|
4
|
-
accentHex: string;
|
|
4
|
+
readonly accentHex: string;
|
|
5
5
|
/** Major theme color hexes checked for hue collision. */
|
|
6
|
-
colorHexes: string[];
|
|
6
|
+
readonly colorHexes: readonly string[];
|
|
7
7
|
/** WCAG luminance of the status-line surface on light themes; undefined on dark themes. */
|
|
8
|
-
surfaceLuminance?: number;
|
|
8
|
+
readonly surfaceLuminance?: number;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Derive a stable CSS hex accent color from a session name and the active theme.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Theme, ThemeColor } from "./theme.js";
|
|
2
2
|
type ShimmerTheme = Pick<Theme, "bold" | "fg" | "getFgAnsi">;
|
|
3
|
-
/** Sweep style for animated shimmer text; `disabled` renders every tier as the
|
|
3
|
+
/** Sweep style for animated shimmer text; `disabled` renders every tier as the mid color. */
|
|
4
4
|
export type ShimmerMode = "classic" | "kitt" | "disabled";
|
|
5
5
|
/** Select the shimmer sweep style. The host pushes its `display.shimmer` preference here. */
|
|
6
6
|
export declare function setShimmerMode(mode: ShimmerMode): void;
|
|
@@ -49,7 +49,7 @@ export declare class Theme {
|
|
|
49
49
|
* Theme-derived inputs for `getSessionAccentHex`: the accent hex whose
|
|
50
50
|
* OKLCH weight session accents adopt, the major colors they must not
|
|
51
51
|
* hue-collide with, and the light-theme surface luminance to contrast
|
|
52
|
-
* against.
|
|
52
|
+
* against. Built once per instance and frozen; callers share the object.
|
|
53
53
|
*/
|
|
54
54
|
get sessionAccentInputs(): SessionAccentTheme;
|
|
55
55
|
fg(color: ThemeColor, text: string): string;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web search response types shared by the coding agent's search providers and
|
|
3
|
+
* the transcript renderer in {@link ./web-search}. Render-free, so provider code
|
|
4
|
+
* can import it without loading UI components.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Display label for every search implementation: `web/*` engines and the
|
|
8
|
+
* chat-model groundings. Keys are the ids providers report in
|
|
9
|
+
* {@link SearchResponse.provider} and search errors.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SEARCH_PROVIDER_LABELS: {
|
|
12
|
+
readonly parallel: "Parallel";
|
|
13
|
+
readonly perplexity: "Perplexity";
|
|
14
|
+
readonly gemini: "Gemini";
|
|
15
|
+
readonly anthropic: "Anthropic";
|
|
16
|
+
readonly codex: "OpenAI Codex";
|
|
17
|
+
readonly openai: "OpenAI API";
|
|
18
|
+
readonly xai: "xAI";
|
|
19
|
+
readonly openrouter: "OpenRouter";
|
|
20
|
+
readonly zai: "Z.AI";
|
|
21
|
+
readonly exa: "Exa";
|
|
22
|
+
readonly tinyfish: "TinyFish";
|
|
23
|
+
readonly jina: "Jina";
|
|
24
|
+
readonly kagi: "Kagi";
|
|
25
|
+
readonly tavily: "Tavily";
|
|
26
|
+
readonly firecrawl: "Firecrawl";
|
|
27
|
+
readonly brave: "Brave";
|
|
28
|
+
readonly kimi: "Kimi";
|
|
29
|
+
readonly synthetic: "Synthetic";
|
|
30
|
+
readonly ollama: "Ollama";
|
|
31
|
+
readonly searxng: "SearXNG";
|
|
32
|
+
readonly startpage: "Startpage";
|
|
33
|
+
readonly duckduckgo: "DuckDuckGo";
|
|
34
|
+
readonly ecosia: "Ecosia";
|
|
35
|
+
readonly google: "Google";
|
|
36
|
+
readonly mojeek: "Mojeek";
|
|
37
|
+
readonly public: "Public Web";
|
|
38
|
+
};
|
|
39
|
+
/** Id of a search implementation; see {@link SEARCH_PROVIDER_LABELS}. */
|
|
40
|
+
export type SearchProviderId = keyof typeof SEARCH_PROVIDER_LABELS;
|
|
41
|
+
/** Label for a provider id; ids from older transcripts fall back to the raw id. */
|
|
42
|
+
export declare function getSearchProviderLabel(id: SearchProviderId): string;
|
|
43
|
+
/** Source returned by search (all providers) */
|
|
44
|
+
export interface SearchSource {
|
|
45
|
+
title: string;
|
|
46
|
+
url: string;
|
|
47
|
+
snippet?: string;
|
|
48
|
+
/** ISO date string or relative ("2d ago") */
|
|
49
|
+
publishedDate?: string;
|
|
50
|
+
/** Age in seconds for consistent formatting */
|
|
51
|
+
ageSeconds?: number;
|
|
52
|
+
author?: string;
|
|
53
|
+
}
|
|
54
|
+
/** Citation with text reference (LLM-mediated providers) */
|
|
55
|
+
export interface SearchCitation {
|
|
56
|
+
url: string;
|
|
57
|
+
title: string;
|
|
58
|
+
citedText?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Usage metrics */
|
|
61
|
+
export interface SearchUsage {
|
|
62
|
+
inputTokens?: number;
|
|
63
|
+
outputTokens?: number;
|
|
64
|
+
/** Anthropic: number of web search requests made */
|
|
65
|
+
searchRequests?: number;
|
|
66
|
+
/** Perplexity: combined token count */
|
|
67
|
+
totalTokens?: number;
|
|
68
|
+
}
|
|
69
|
+
/** Unified response across providers */
|
|
70
|
+
export interface SearchResponse {
|
|
71
|
+
provider: SearchProviderId | "none";
|
|
72
|
+
/** Synthesized answer text (LLM-mediated providers) */
|
|
73
|
+
answer?: string;
|
|
74
|
+
/** Search result sources */
|
|
75
|
+
sources: SearchSource[];
|
|
76
|
+
/** Text citations with context */
|
|
77
|
+
citations?: SearchCitation[];
|
|
78
|
+
/** Intermediate search queries (anthropic) */
|
|
79
|
+
searchQueries?: string[];
|
|
80
|
+
/** Follow-up question suggestions (provider-dependent) */
|
|
81
|
+
relatedQuestions?: string[];
|
|
82
|
+
/** Token usage metrics */
|
|
83
|
+
usage?: SearchUsage;
|
|
84
|
+
/** Model used */
|
|
85
|
+
model?: string;
|
|
86
|
+
/** Request ID for debugging */
|
|
87
|
+
requestId?: string;
|
|
88
|
+
/** Authentication mode used by the provider (e.g. oauth, api-key) */
|
|
89
|
+
authMode?: string;
|
|
90
|
+
}
|