@oh-my-pi/pi-coding-agent 16.1.9 → 16.1.11
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 +46 -0
- package/dist/cli.js +3455 -3430
- package/dist/types/config/settings-schema.d.ts +10 -0
- package/dist/types/edit/streaming.d.ts +5 -5
- package/dist/types/export/html/index.d.ts +31 -2
- package/dist/types/export/html/web-palette.d.ts +117 -0
- package/dist/types/hindsight/content.d.ts +7 -0
- package/dist/types/hindsight/transcript.d.ts +1 -1
- package/dist/types/modes/components/hook-editor.d.ts +2 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +0 -1
- package/dist/types/modes/interactive-mode.d.ts +5 -0
- package/dist/types/modes/types.d.ts +17 -0
- package/dist/types/modes/utils/keybinding-matchers.d.ts +13 -0
- package/dist/types/sdk.d.ts +1 -0
- package/dist/types/session/agent-session.d.ts +4 -0
- package/dist/types/session/session-context.d.ts +2 -0
- package/dist/types/session/session-entries.d.ts +6 -0
- package/dist/types/session/session-manager.d.ts +2 -1
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/tools/acp-bridge.d.ts +29 -0
- package/dist/types/tools/browser/aria/aria-snapshot.d.ts +39 -0
- package/dist/types/tools/browser/cmux/cmux-tab.d.ts +10 -0
- package/dist/types/tools/browser/tab-worker.d.ts +20 -0
- package/dist/types/tools/browser.d.ts +1 -0
- package/dist/types/tools/find.d.ts +1 -2
- package/dist/types/tools/write.d.ts +1 -2
- package/dist/types/utils/image-loading.d.ts +4 -3
- package/dist/types/utils/jj.d.ts +25 -0
- package/dist/types/utils/title-generator.d.ts +0 -2
- package/package.json +12 -12
- package/scripts/generate-aria-snapshot.ts +134 -0
- package/scripts/generate-share-viewer.ts +4 -2
- package/src/autoresearch/git.ts +12 -0
- package/src/config/settings-schema.ts +12 -0
- package/src/discovery/opencode.ts +47 -4
- package/src/edit/hashline/filesystem.ts +8 -0
- package/src/edit/modes/patch.ts +18 -2
- package/src/edit/modes/replace.ts +13 -10
- package/src/edit/streaming.ts +5 -5
- package/src/export/html/index.ts +50 -8
- package/src/export/html/web-palette.ts +142 -0
- package/src/hindsight/backend.ts +4 -4
- package/src/hindsight/content.ts +17 -1
- package/src/hindsight/transcript.ts +2 -2
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/modes/components/agent-dashboard.ts +8 -8
- package/src/modes/components/hook-editor.ts +13 -10
- package/src/modes/components/session-selector.ts +3 -0
- package/src/modes/controllers/event-controller.ts +29 -5
- package/src/modes/controllers/extension-ui-controller.ts +6 -2
- package/src/modes/controllers/selector-controller.ts +3 -5
- package/src/modes/interactive-mode.ts +69 -29
- package/src/modes/theme/dark.json +1 -1
- package/src/modes/types.ts +18 -0
- package/src/modes/utils/keybinding-matchers.ts +36 -1
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/system/project-prompt.md +2 -0
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/prompts/tools/browser.md +5 -2
- package/src/sdk.ts +20 -2
- package/src/session/agent-session.ts +38 -14
- package/src/session/session-context.ts +5 -0
- package/src/session/session-entries.ts +6 -0
- package/src/session/session-manager.ts +3 -1
- package/src/system-prompt.ts +15 -3
- package/src/task/worktree.ts +12 -4
- package/src/thinking.ts +1 -1
- package/src/tools/acp-bridge.ts +66 -0
- package/src/tools/bash.ts +3 -3
- package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
- package/src/tools/browser/aria/aria-snapshot.ts +103 -0
- package/src/tools/browser/cmux/cmux-tab.ts +73 -1
- package/src/tools/browser/tab-worker.ts +242 -47
- package/src/tools/browser.ts +5 -0
- package/src/tools/find.ts +1 -2
- package/src/tools/index.ts +1 -1
- package/src/tools/write.ts +3 -27
- package/src/utils/git.ts +3 -2
- package/src/utils/image-loading.ts +6 -3
- package/src/utils/jj.ts +47 -0
- package/src/utils/title-generator.ts +31 -99
|
@@ -912,6 +912,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
912
912
|
readonly description: "Surface the active model identifier in the system prompt so the agent knows which model it is";
|
|
913
913
|
};
|
|
914
914
|
};
|
|
915
|
+
readonly includeWorkspaceTree: {
|
|
916
|
+
readonly type: "boolean";
|
|
917
|
+
readonly default: false;
|
|
918
|
+
readonly ui: {
|
|
919
|
+
readonly tab: "model";
|
|
920
|
+
readonly group: "Prompt";
|
|
921
|
+
readonly label: "Include Workspace Tree";
|
|
922
|
+
readonly description: "Render the workspace directory tree in the system prompt. WARNING: This can bust prompt caching across sessions when files are modified.";
|
|
923
|
+
};
|
|
924
|
+
};
|
|
915
925
|
readonly personality: {
|
|
916
926
|
readonly type: "enum";
|
|
917
927
|
readonly values: readonly ["default", "friendly", "pragmatic", "none"];
|
|
@@ -63,12 +63,12 @@ export interface EditStreamingStrategy<Args = unknown> {
|
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Given an edits array parsed from partial JSON, drop the last entry when the
|
|
66
|
-
* corresponding object in `partialJson`
|
|
66
|
+
* corresponding object in `partialJson` has not yet closed with `}`.
|
|
67
67
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
* The streaming parser materializes a trailing edit object from the fields seen
|
|
69
|
+
* so far before its closing `}` arrives, so an unfinished last entry can render
|
|
70
|
+
* as a (partial) edit mid-stream. Dropping it until the object closes keeps the
|
|
71
|
+
* preview from showing an incomplete edit.
|
|
72
72
|
*/
|
|
73
73
|
export declare function dropIncompleteLastEdit<T>(edits: readonly T[], partialJson: string | undefined, listKey: string): T[];
|
|
74
74
|
export declare const EDIT_MODE_STRATEGIES: Record<EditMode, EditStreamingStrategy<unknown>>;
|
|
@@ -5,12 +5,41 @@ import { SessionManager } from "../../session/session-manager";
|
|
|
5
5
|
export declare function getTemplate(): string;
|
|
6
6
|
export interface ExportOptions {
|
|
7
7
|
outputPath?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Which color palette the export ships with.
|
|
10
|
+
* - `"web"` (default) — the omp brand identity (collab-web pink/purple),
|
|
11
|
+
* so public HTML exports and the `/s/<id>` share viewer match the live
|
|
12
|
+
* `my.omp.sh` client. See `web-palette.ts`.
|
|
13
|
+
* - `"theme"` — derive from `themeName` (or the active TUI theme), preserving
|
|
14
|
+
* the pre-15.12 behavior where an export mirrored the user's terminal.
|
|
15
|
+
*/
|
|
16
|
+
palette?: "web" | "theme";
|
|
17
|
+
/**
|
|
18
|
+
* TUI theme to derive colors from when `palette: "theme"`. Ignored for the
|
|
19
|
+
* default `"web"` palette. Resolves to the active TUI theme when omitted.
|
|
20
|
+
*/
|
|
8
21
|
themeName?: string;
|
|
9
22
|
/** Embed subagent session transcripts found next to the session file (default true). */
|
|
10
23
|
includeSubSessions?: boolean;
|
|
11
24
|
}
|
|
12
|
-
/**
|
|
13
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Generate CSS custom properties for the export `:root`.
|
|
27
|
+
*
|
|
28
|
+
* Two call shapes:
|
|
29
|
+
* • `generateThemeVars("web" | "theme", themeName?)` — explicit palette.
|
|
30
|
+
* `"web"` (the default for public artifacts) returns the fixed omp brand
|
|
31
|
+
* palette from `web-palette.ts` — collab-web pink/purple identity, shared
|
|
32
|
+
* with the live `my.omp.sh` client, so exports and the share viewer render
|
|
33
|
+
* identically to it. `"theme"` derives from the TUI theme via
|
|
34
|
+
* `getResolvedThemeColors(themeName)` plus the three
|
|
35
|
+
* `export.{pageBg,cardBg,infoBg}` surface overrides.
|
|
36
|
+
* • `generateThemeVars(themeName)` — legacy single-arg form: derive from the
|
|
37
|
+
* named TUI theme. Kept so existing callers (and the theme-islight test)
|
|
38
|
+
* keep working; equivalent to `generateThemeVars("theme", themeName)`.
|
|
39
|
+
*
|
|
40
|
+
* Exported for the share-viewer build script.
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateThemeVars(palette?: "web" | "theme" | (string & {}), themeName?: string): Promise<string>;
|
|
14
43
|
/** Embedded subagent session transcript, keyed by slash-joined agent path in `SessionData.subSessions`. */
|
|
15
44
|
export interface SubSession {
|
|
16
45
|
/** Bare agent id (session file stem), e.g. "ToolAsk". */
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web/export palette — the omp brand identity shared by the collab-web live
|
|
3
|
+
* client (`my.omp.sh/`) and every public HTML export / share viewer (`/s/<id>`).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists separately from `modes/theme/dark.json`: the `dark` theme is
|
|
6
|
+
* the **default TUI theme** — its amber accent (`#febc38`) drives the terminal
|
|
7
|
+
* status line, syntax highlighting, thinking levels, and bash/python mode
|
|
8
|
+
* colors for every omp user. The public web artifacts want the collab-web
|
|
9
|
+
* pink/purple identity instead, so they pin this palette rather than inheriting
|
|
10
|
+
* the TUI's. Editing `dark.json` to repurpose it for the web would repaint
|
|
11
|
+
* every terminal; this file keeps the two surfaces decoupled.
|
|
12
|
+
*
|
|
13
|
+
* Token layout — emitted as CSS custom properties on `:root`:
|
|
14
|
+
* • Legacy export names consumed by `template.css` / `template.js`
|
|
15
|
+
* (`--text`, `--body-bg`, `--container-bg`, `--info-bg`, `--accent`,
|
|
16
|
+
* `--border`, `--success`, `--error`, `--warning`, `--muted`, `--dim`,
|
|
17
|
+
* `--borderAccent`, `--selectedBg`, `--userMessageBg`, `--customMessageBg`,
|
|
18
|
+
* `--customMessageLabel`, `--mdHeading`, `--mdLink`, `--mdCode`,
|
|
19
|
+
* `--mdListBullet`, `--toolOutput`, `--thinkingText`, syntax*, …).
|
|
20
|
+
* • collab-web-native aliases consumed by the `tv-` tool-render bridge
|
|
21
|
+
* (`tool-render.css`: `var(--bg-inset, …)`, `var(--fg, …)`, …) so embedded
|
|
22
|
+
* tool cards resolve to the *real* collab-web tokens and render
|
|
23
|
+
* pixel-identical to the live client.
|
|
24
|
+
*
|
|
25
|
+
* Alpha-bearing tokens (`--border`, `--ring`, `--accent-muted`, …) keep their
|
|
26
|
+
* `oklch(… / N%)` form — flattening them to opaque hex would produce harsh
|
|
27
|
+
* white borders and non-matching translucent focus rings. Opaque surfaces are
|
|
28
|
+
* sRGB hex (the collab-web `tokens.css` OKLCH dark-theme tokens converted via
|
|
29
|
+
* the standard OKLab→linear-sRGB→gamma path); if the live client palette
|
|
30
|
+
* changes, regenerate those from there.
|
|
31
|
+
*/
|
|
32
|
+
export declare const WEB_EXPORT_PALETTE: {
|
|
33
|
+
readonly "--bg": "#0f0b14";
|
|
34
|
+
readonly "--bg-raised": "#16111c";
|
|
35
|
+
readonly "--bg-inset": "#09060c";
|
|
36
|
+
readonly "--bg-overlay": "#211b28";
|
|
37
|
+
readonly "--fg": "#e6e3ea";
|
|
38
|
+
readonly "--fg-muted": "#a49faa";
|
|
39
|
+
readonly "--fg-faint": "#6e6974";
|
|
40
|
+
readonly "--accent": "#ed4abf";
|
|
41
|
+
readonly "--accent-muted": "oklch(0.674 0.23 341 / 18%)";
|
|
42
|
+
readonly "--ok": "#68ca80";
|
|
43
|
+
readonly "--err": "#f05653";
|
|
44
|
+
readonly "--warn": "#e4b33f";
|
|
45
|
+
readonly "--ring": "oklch(0.817 0.112 205 / 70%)";
|
|
46
|
+
readonly "--font-mono": 'ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Mono", Menlo, Consolas, monospace';
|
|
47
|
+
readonly "--body-bg": "#0f0b14";
|
|
48
|
+
readonly "--container-bg": "#16111c";
|
|
49
|
+
readonly "--info-bg": "#09060c";
|
|
50
|
+
readonly "--text": "#e6e3ea";
|
|
51
|
+
readonly "--muted": "#a49faa";
|
|
52
|
+
readonly "--dim": "#6e6974";
|
|
53
|
+
readonly "--thinkingText": "#a49faa";
|
|
54
|
+
readonly "--border": "oklch(1 0 0 / 9%)";
|
|
55
|
+
readonly "--borderMuted": "oklch(1 0 0 / 6%)";
|
|
56
|
+
readonly "--borderAccent": "#945ff9";
|
|
57
|
+
readonly "--selectedBg": "#2d2535";
|
|
58
|
+
readonly "--success": "#68ca80";
|
|
59
|
+
readonly "--error": "#f05653";
|
|
60
|
+
readonly "--warning": "#e4b33f";
|
|
61
|
+
readonly "--userMessageBg": "oklch(0.674 0.23 341 / 6%)";
|
|
62
|
+
readonly "--userMessageText": "#e6e3ea";
|
|
63
|
+
readonly "--customMessageBg": "#211b28";
|
|
64
|
+
readonly "--customMessageText": "#a49faa";
|
|
65
|
+
readonly "--customMessageLabel": "#b281d6";
|
|
66
|
+
readonly "--toolPendingBg": "#16111c";
|
|
67
|
+
readonly "--toolSuccessBg": "#09060c";
|
|
68
|
+
readonly "--toolErrorBg": "oklch(0.66 0.19 25 / 14%)";
|
|
69
|
+
readonly "--toolTitle": "#e6e3ea";
|
|
70
|
+
readonly "--toolOutput": "#a49faa";
|
|
71
|
+
readonly "--mdHeading": "#ed4abf";
|
|
72
|
+
readonly "--mdLink": "#5ad8e5";
|
|
73
|
+
readonly "--mdLinkUrl": "#6e6974";
|
|
74
|
+
readonly "--mdCode": "#e6e3ea";
|
|
75
|
+
readonly "--mdCodeBlock": "#e6e3ea";
|
|
76
|
+
readonly "--mdCodeBlockBorder": "oklch(1 0 0 / 9%)";
|
|
77
|
+
readonly "--mdQuote": "#a49faa";
|
|
78
|
+
readonly "--mdQuoteBorder": "oklch(1 0 0 / 13%)";
|
|
79
|
+
readonly "--mdHr": "oklch(1 0 0 / 9%)";
|
|
80
|
+
readonly "--mdListBullet": "#ed4abf";
|
|
81
|
+
readonly "--toolDiffAdded": "#68ca80";
|
|
82
|
+
readonly "--toolDiffRemoved": "#f05653";
|
|
83
|
+
readonly "--toolDiffContext": "#6e6974";
|
|
84
|
+
readonly "--syntaxComment": "#6e6974";
|
|
85
|
+
readonly "--syntaxKeyword": "#945ff9";
|
|
86
|
+
readonly "--syntaxFunction": "#e4b33f";
|
|
87
|
+
readonly "--syntaxVariable": "#5ad8e5";
|
|
88
|
+
readonly "--syntaxString": "#68ca80";
|
|
89
|
+
readonly "--syntaxNumber": "#ed4abf";
|
|
90
|
+
readonly "--syntaxType": "#b281d6";
|
|
91
|
+
readonly "--syntaxOperator": "#e6e3ea";
|
|
92
|
+
readonly "--syntaxPunctuation": "#a49faa";
|
|
93
|
+
readonly "--thinkingOff": "#6e6974";
|
|
94
|
+
readonly "--thinkingMinimal": "#6e6974";
|
|
95
|
+
readonly "--thinkingLow": "#945ff9";
|
|
96
|
+
readonly "--thinkingMedium": "#b281d6";
|
|
97
|
+
readonly "--thinkingHigh": "#ed4abf";
|
|
98
|
+
readonly "--thinkingXhigh": "#e4b33f";
|
|
99
|
+
readonly "--bashMode": "#5ad8e5";
|
|
100
|
+
readonly "--pythonMode": "#e4b33f";
|
|
101
|
+
readonly "--statusLineBg": "#0f0b14";
|
|
102
|
+
readonly "--statusLineSep": "#6e6974";
|
|
103
|
+
readonly "--statusLineModel": "#ed4abf";
|
|
104
|
+
readonly "--statusLinePath": "#5ad8e5";
|
|
105
|
+
readonly "--statusLineGitClean": "#68ca80";
|
|
106
|
+
readonly "--statusLineGitDirty": "#e4b33f";
|
|
107
|
+
readonly "--statusLineContext": "#a49faa";
|
|
108
|
+
readonly "--statusLineSpend": "#5ad8e5";
|
|
109
|
+
readonly "--statusLineStaged": "#68ca80";
|
|
110
|
+
readonly "--statusLineDirty": "#e4b33f";
|
|
111
|
+
readonly "--statusLineUntracked": "#945ff9";
|
|
112
|
+
readonly "--statusLineOutput": "#b281d6";
|
|
113
|
+
readonly "--statusLineCost": "#b281d6";
|
|
114
|
+
readonly "--statusLineSubagents": "#ed4abf";
|
|
115
|
+
};
|
|
116
|
+
/** Serialize the palette as `--key: value;` declarations for `:root { … }`. */
|
|
117
|
+
export declare function webExportThemeVars(): string;
|
|
@@ -28,6 +28,13 @@ export interface RecallResultLike {
|
|
|
28
28
|
* retaining.
|
|
29
29
|
*/
|
|
30
30
|
export declare function stripMemoryTags(content: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* True when `content` carries at least one letter or digit. Used by retain
|
|
33
|
+
* and recall paths to drop placeholder assistant turns ("." / "..." / pure
|
|
34
|
+
* whitespace) that would otherwise pollute the bank and waste tokens on
|
|
35
|
+
* embeddings with no semantic content.
|
|
36
|
+
*/
|
|
37
|
+
export declare function hasSubstantiveContent(content: string): boolean;
|
|
31
38
|
/** Format recall results into a bullet list for context injection. */
|
|
32
39
|
export declare function formatMemories(results: RecallResultLike[]): string;
|
|
33
40
|
/** Format current UTC time for the recall preamble. */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* surviving message's `TextContent` parts are joined with newlines.
|
|
8
8
|
*/
|
|
9
9
|
import type { SessionEntry } from "../session/session-entries";
|
|
10
|
-
import type
|
|
10
|
+
import { type HindsightMessage } from "./content";
|
|
11
11
|
export interface ReadonlySessionManagerLike {
|
|
12
12
|
getEntries(): SessionEntry[];
|
|
13
13
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Supports Ctrl+G for external editor.
|
|
4
4
|
*
|
|
5
5
|
* Two modes:
|
|
6
|
-
* - Default (hook): Enter inserts newline,
|
|
6
|
+
* - Default (hook): Enter inserts newline, the `app.message.followUp` chord
|
|
7
|
+
* (Ctrl+Q / Ctrl+Enter) submits, bordered popup
|
|
7
8
|
* - Prompt-style (ask): Enter submits, Shift+Enter inserts newline, legacy ask chrome
|
|
8
9
|
*/
|
|
9
10
|
import { Container, type TUI } from "@oh-my-pi/pi-tui";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
3
3
|
import type { SessionObserverRegistry } from "../session-observer-registry";
|
|
4
|
-
export declare function formatTemporaryModelStatus(modelLabel: string, roleSelectorHint?: string): string;
|
|
5
4
|
export declare class SelectorController {
|
|
6
5
|
#private;
|
|
7
6
|
private ctx;
|
|
@@ -95,6 +95,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
95
95
|
hookWidgetContainerBelow: Container;
|
|
96
96
|
statusLine: StatusLineComponent;
|
|
97
97
|
isInitialized: boolean;
|
|
98
|
+
initialChatRendered: boolean;
|
|
98
99
|
isBashMode: boolean;
|
|
99
100
|
toolOutputExpanded: boolean;
|
|
100
101
|
todoExpanded: boolean;
|
|
@@ -183,6 +184,10 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
183
184
|
withLocalSubmission<T>(text: string, fn: () => Promise<T>, options?: {
|
|
184
185
|
imageCount?: number;
|
|
185
186
|
}): Promise<T>;
|
|
187
|
+
clearOptimisticUserMessage(): void;
|
|
188
|
+
replaceOptimisticUserMessage(message: AgentMessage, options?: {
|
|
189
|
+
imageLinks?: readonly (string | undefined)[];
|
|
190
|
+
}): void;
|
|
186
191
|
startPendingSubmission(input: {
|
|
187
192
|
text: string;
|
|
188
193
|
images?: ImageContent[];
|
|
@@ -118,6 +118,17 @@ export interface InteractiveModeContext {
|
|
|
118
118
|
eventController: EventController;
|
|
119
119
|
eventBus?: EventBus;
|
|
120
120
|
isInitialized: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* `true` once `renderInitialMessages` has rendered the session transcript
|
|
123
|
+
* into `chatContainer` at least once.
|
|
124
|
+
*
|
|
125
|
+
* Extension chat-rebuilds (`ExtensionUiController.#applyCustomMessageDisplay`)
|
|
126
|
+
* are gated on this: rebuilding before the initial render would plant a
|
|
127
|
+
* session-derived component into the chat that `renderInitialMessages` then
|
|
128
|
+
* both re-renders from session entries AND re-appends via
|
|
129
|
+
* `preserveExistingChat`, duplicating the message (issue #1955).
|
|
130
|
+
*/
|
|
131
|
+
initialChatRendered: boolean;
|
|
121
132
|
isBashMode: boolean;
|
|
122
133
|
toolOutputExpanded: boolean;
|
|
123
134
|
todoExpanded: boolean;
|
|
@@ -237,6 +248,12 @@ export interface InteractiveModeContext {
|
|
|
237
248
|
withLocalSubmission<T>(text: string, fn: () => Promise<T>, options?: {
|
|
238
249
|
imageCount?: number;
|
|
239
250
|
}): Promise<T>;
|
|
251
|
+
/** Clears bookkeeping for an optimistic local user message once the matching session event arrives. */
|
|
252
|
+
clearOptimisticUserMessage(): void;
|
|
253
|
+
/** Replaces the raw optimistic user render with the canonical message emitted by the session. */
|
|
254
|
+
replaceOptimisticUserMessage(message: AgentMessage, options?: {
|
|
255
|
+
imageLinks?: readonly (string | undefined)[];
|
|
256
|
+
}): void;
|
|
240
257
|
isKnownSlashCommand(text: string): boolean;
|
|
241
258
|
addMessageToChat(message: AgentMessage, options?: {
|
|
242
259
|
populateHistory?: boolean;
|
|
@@ -17,3 +17,16 @@ export declare function matchesSelectPageUp(data: string): boolean;
|
|
|
17
17
|
/** Match the generic selector page-down keybinding. */
|
|
18
18
|
export declare function matchesSelectPageDown(data: string): boolean;
|
|
19
19
|
export declare function matchesAppExternalEditor(data: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Match the "submit multi-line text input" keybinding (`app.message.followUp`).
|
|
22
|
+
*
|
|
23
|
+
* Used by forms where plain Enter inserts a newline and a modified-Enter chord
|
|
24
|
+
* submits — the main editor's follow-up handler, the agent dashboard's new-agent
|
|
25
|
+
* description, and the hook editor's hook-style mode. The keybinding defaults to
|
|
26
|
+
* `["ctrl+q", "ctrl+enter"]` so Windows Terminal (which can't deliver a distinct
|
|
27
|
+
* Ctrl+Enter event; #1903) still has a working chord without user remapping.
|
|
28
|
+
*
|
|
29
|
+
* Also recognizes modifier-tagged LF as Ctrl+Enter only when Ctrl+Enter is an
|
|
30
|
+
* effective follow-up binding.
|
|
31
|
+
*/
|
|
32
|
+
export declare function matchesAppFollowUp(data: string): boolean;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -156,6 +156,8 @@ export interface AgentSessionConfig {
|
|
|
156
156
|
modelRegistry: ModelRegistry;
|
|
157
157
|
/** Tool registry for LSP and settings */
|
|
158
158
|
toolRegistry?: Map<string, AgentTool>;
|
|
159
|
+
/** Tool names whose current registry entry is still the built-in implementation. */
|
|
160
|
+
builtInToolNames?: Iterable<string>;
|
|
159
161
|
/** Current session pre-LLM message transform pipeline */
|
|
160
162
|
transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => AgentMessage[] | Promise<AgentMessage[]>;
|
|
161
163
|
/** Provider payload hook used by the active session request path */
|
|
@@ -511,6 +513,8 @@ export declare class AgentSession {
|
|
|
511
513
|
* Get a tool by name from the registry.
|
|
512
514
|
*/
|
|
513
515
|
getToolByName(name: string): AgentTool | undefined;
|
|
516
|
+
/** True when the current registry entry for `name` came from a built-in factory. */
|
|
517
|
+
hasBuiltInTool(name: string): boolean;
|
|
514
518
|
/**
|
|
515
519
|
* Get all configured tool names (built-in via --tools or default, plus custom tools).
|
|
516
520
|
*/
|
|
@@ -4,6 +4,8 @@ import { type CompactionEntry, type SessionEntry } from "./session-entries";
|
|
|
4
4
|
export interface SessionContext {
|
|
5
5
|
messages: AgentMessage[];
|
|
6
6
|
thinkingLevel?: string;
|
|
7
|
+
/** Configured thinking selector (`"auto"` or a concrete level) from the latest change. */
|
|
8
|
+
configuredThinkingLevel?: string;
|
|
7
9
|
serviceTier?: ServiceTier;
|
|
8
10
|
/** Model roles: { default: "provider/modelId", small: "provider/modelId", ... } */
|
|
9
11
|
models: Record<string, string>;
|
|
@@ -30,6 +30,12 @@ export interface SessionMessageEntry extends SessionEntryBase {
|
|
|
30
30
|
export interface ThinkingLevelChangeEntry extends SessionEntryBase {
|
|
31
31
|
type: "thinking_level_change";
|
|
32
32
|
thinkingLevel?: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* The user-configured selector at the time of this change: `"auto"` when auto
|
|
35
|
+
* mode was active, otherwise the concrete level. Absent on entries written
|
|
36
|
+
* before auto-mode persistence existed; readers fall back to `thinkingLevel`.
|
|
37
|
+
*/
|
|
38
|
+
configured?: string | null;
|
|
33
39
|
}
|
|
34
40
|
export interface ModelChangeEntry extends SessionEntryBase {
|
|
35
41
|
type: "model_change";
|
|
@@ -138,7 +138,8 @@ export declare class SessionManager {
|
|
|
138
138
|
* top-level entries via appendCompaction()/branchWithSummary().
|
|
139
139
|
*/
|
|
140
140
|
appendMessage(message: Message | CustomMessage | HookMessage | BashExecutionMessage | PythonExecutionMessage | FileMentionMessage): string;
|
|
141
|
-
|
|
141
|
+
/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
|
|
142
|
+
appendThinkingLevelChange(thinkingLevel?: string, configured?: string): string;
|
|
142
143
|
appendServiceTierChange(serviceTier: ServiceTier | null): string;
|
|
143
144
|
appendModeChange(mode: string, data?: Record<string, unknown>): string;
|
|
144
145
|
/**
|
|
@@ -110,6 +110,8 @@ export interface BuildSystemPromptOptions {
|
|
|
110
110
|
model?: string;
|
|
111
111
|
/** Personality preset rendered into the default system prompt. "none" omits the block. Default: "default" */
|
|
112
112
|
personality?: Personality;
|
|
113
|
+
/** Whether to include the workspace directory tree in the system prompt. Default: false */
|
|
114
|
+
includeWorkspaceTree?: boolean;
|
|
113
115
|
}
|
|
114
116
|
/** Result of building provider-facing system prompt messages. */
|
|
115
117
|
export interface BuildSystemPromptResult {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ACP client bridge routing for file-write sites.
|
|
3
|
+
*
|
|
4
|
+
* When an ACP client (e.g. Zed) advertises the `fs.writeTextFile` capability,
|
|
5
|
+
* all write-mode tools must route through it so the editor's open buffer is
|
|
6
|
+
* updated immediately. Internal artifacts ('/Users/theo/.omp/agent/sessions/-Projects-oh-my-pi/2026-06-10T09-11-41-506Z_019eb0cd-3ec2-7000-92aa-1b82aa4d78f0/local' plan files, other scheme
|
|
7
|
+
* URLs) are always written directly to disk — those are OMP-owned and should
|
|
8
|
+
* never be pushed into the editor.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolSession } from ".";
|
|
11
|
+
/**
|
|
12
|
+
* Return `true` when an ACP client bridge write is appropriate for this path.
|
|
13
|
+
*
|
|
14
|
+
* Returns `false` for internal-URL paths (e.g. `'/Users/theo/.omp/agent/sessions/-Projects-oh-my-pi/2026-06-10T09-11-41-506Z_019eb0cd-3ec2-7000-92aa-1b82aa4d78f0/local/PLAN.md'`) and for the
|
|
15
|
+
* active plan file while plan mode is enabled — both are OMP-internal artifacts
|
|
16
|
+
* that must stay off the editor's buffer.
|
|
17
|
+
*/
|
|
18
|
+
export declare function shouldRouteWriteThroughBridge(session: ToolSession, requestedPath: string, absolutePath: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Try to route a file write through the ACP client bridge.
|
|
21
|
+
*
|
|
22
|
+
* Performs the full guard check, bridge call (wrapped in {@link ToolError}),
|
|
23
|
+
* FS-scan cache invalidation, and session mutation-version bump.
|
|
24
|
+
*
|
|
25
|
+
* Returns `true` when the bridge was used and the caller must skip the
|
|
26
|
+
* writethrough path. Returns `false` when the bridge is unavailable or the
|
|
27
|
+
* path should not be routed through it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function routeWriteThroughBridge(session: ToolSession, requestedPath: string, absolutePath: string, content: string): Promise<boolean>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ElementHandle, Page } from "puppeteer-core";
|
|
2
|
+
export interface AriaSnapshotOptions {
|
|
3
|
+
/** Maximum tree depth to render. */
|
|
4
|
+
depth?: number;
|
|
5
|
+
/** Append `[box=x,y,w,h]` bounding boxes to each node. */
|
|
6
|
+
boxes?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Capture a Playwright-format ARIA snapshot of `root` (or the whole document when
|
|
10
|
+
* null). Always runs in `ai` mode so every node carries a `[ref=eN]` id; resolve
|
|
11
|
+
* those to elements with {@link resolveAriaRefHandle}. Ids are renumbered from e1
|
|
12
|
+
* on each call and remain valid until the next snapshot.
|
|
13
|
+
*/
|
|
14
|
+
export declare function captureAriaSnapshot(page: Page, root: ElementHandle | null, options?: AriaSnapshotOptions): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a `[ref=eN]` id from the latest snapshot to a live `ElementHandle`, or
|
|
17
|
+
* null when the ref no longer matches any element. Runs in the main world so it
|
|
18
|
+
* sees the `_ariaRef` expandos the snapshot wrote.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveAriaRefHandle(page: Page, ref: string): Promise<ElementHandle | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Recognize the explicit `[ref=eN]` selector forms and return the bare ref id,
|
|
23
|
+
* else null. Accepts `aria-ref=e5` (Playwright-MCP style), `aria-ref/e5`, and
|
|
24
|
+
* `ariaref/e5` — lets `tab.click("aria-ref=e5")` etc. act on snapshot refs. A
|
|
25
|
+
* bare `e5` is intentionally NOT a ref selector: the cmux backend already uses
|
|
26
|
+
* bare `eN`/`@eN` for its own observe ids, so requiring the prefix keeps action
|
|
27
|
+
* selectors meaning the same thing on both backends. (`tab.ref("e5")` still
|
|
28
|
+
* accepts a bare id directly.)
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseAriaRefSelector(selector: string): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Build a self-contained expression script that runs the vendored bundle in the
|
|
33
|
+
* page and returns the ARIA snapshot YAML. Used by the cmux backend, whose
|
|
34
|
+
* `browser.eval` RPC takes a script string and returns the completion value (it
|
|
35
|
+
* has no ElementHandle to pass in). The script resolves `selector` via
|
|
36
|
+
* `document.querySelector` in-page (CSS selectors only) or falls back to the
|
|
37
|
+
* whole document. Like the puppeteer path it installs nothing on `window`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildAriaSnapshotScript(selector: string | undefined, options?: AriaSnapshotOptions): string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { JsRuntime } from "../../../eval/js/shared/runtime";
|
|
2
2
|
import type { ToolSession } from "../../../sdk";
|
|
3
|
+
import { type AriaSnapshotOptions } from "../aria/aria-snapshot";
|
|
3
4
|
import { type ReadableFormat } from "../readable";
|
|
4
5
|
import type { Observation, ReadyInfo, RunResultOk, ScreenshotResult, SessionSnapshot } from "../tab-protocol";
|
|
5
6
|
import type { CmuxSocketClient } from "./socket-client";
|
|
@@ -75,6 +76,8 @@ export declare class CmuxTab {
|
|
|
75
76
|
timeoutMs?: number;
|
|
76
77
|
}): Promise<void>;
|
|
77
78
|
observe(opts?: ObserveOptions): Promise<Observation>;
|
|
79
|
+
ariaSnapshot(selector?: string, opts?: AriaSnapshotOptions): Promise<string>;
|
|
80
|
+
ref(id: string): Promise<CmuxElementHandle>;
|
|
78
81
|
click(selector: string): Promise<void>;
|
|
79
82
|
dblclick(selector: string): Promise<void>;
|
|
80
83
|
hover(selector: string): Promise<void>;
|
|
@@ -90,6 +93,9 @@ export declare class CmuxTab {
|
|
|
90
93
|
waitFor(selector: string, opts?: {
|
|
91
94
|
timeout?: number;
|
|
92
95
|
}): Promise<CmuxElementHandle>;
|
|
96
|
+
waitForSelector(selector: string, opts?: {
|
|
97
|
+
timeout?: number;
|
|
98
|
+
}): Promise<CmuxElementHandle>;
|
|
93
99
|
evaluate<TResult, TArgs extends unknown[]>(fn: string | ((...args: TArgs) => TResult | Promise<TResult>), ...args: TArgs): Promise<TResult>;
|
|
94
100
|
scrollIntoView(selector: string): Promise<void>;
|
|
95
101
|
select(selector: string, ...values: string[]): Promise<string[]>;
|
|
@@ -98,6 +104,10 @@ export declare class CmuxTab {
|
|
|
98
104
|
waitForUrl(pattern: string | RegExp, opts?: {
|
|
99
105
|
timeout?: number;
|
|
100
106
|
}): Promise<string>;
|
|
107
|
+
waitForNavigation(opts?: {
|
|
108
|
+
waitUntil?: WaitUntil;
|
|
109
|
+
timeout?: number;
|
|
110
|
+
}): Promise<null>;
|
|
101
111
|
drag(from: DragTarget, to: DragTarget): Promise<void>;
|
|
102
112
|
uploadFile(selector: string, ...filePaths: string[]): Promise<void>;
|
|
103
113
|
waitForResponse(pattern: string | RegExp | ((response: CmuxResponse) => boolean | Promise<boolean>), opts?: {
|
|
@@ -11,12 +11,32 @@ declare global {
|
|
|
11
11
|
elementFromPoint(x: number, y: number): Element | null;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
export interface OpTimeouts {
|
|
15
|
+
/** Largest per-op deadline allowed — strictly below the cell budget. */
|
|
16
|
+
budgetBound: number;
|
|
17
|
+
/** Ceiling for quick page reads. */
|
|
18
|
+
quickOpMs: number;
|
|
19
|
+
/** Ceiling for interactive actions + default for waits. */
|
|
20
|
+
actionOpMs: number;
|
|
21
|
+
}
|
|
22
|
+
/** Resolve the per-op fail-fast ceilings for a given cell budget. */
|
|
23
|
+
export declare function resolveOpTimeouts(cellTimeoutMs: number): OpTimeouts;
|
|
24
|
+
/**
|
|
25
|
+
* Effective timeout for a wait helper (`waitFor*`). A positive explicit `{ timeout }` is
|
|
26
|
+
* honored but clamped to the cell budget so it still fails fast + named; raising the tool
|
|
27
|
+
* `timeout` raises that cap, so a longer budget stays meaningful. No `{ timeout }` → the
|
|
28
|
+
* action ceiling. Puppeteer's `{ timeout: 0 }` / `Infinity` ("disable") maps to the largest
|
|
29
|
+
* bounded wait (`budgetBound`) — the harness never permits an unbounded wait. Garbage input
|
|
30
|
+
* (negative, `NaN`) falls back to the action ceiling rather than the longest wait.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveWaitTimeout(cellTimeoutMs: number, explicit?: number): number;
|
|
14
33
|
interface ScreenshotOptions {
|
|
15
34
|
selector?: string;
|
|
16
35
|
fullPage?: boolean;
|
|
17
36
|
save?: string;
|
|
18
37
|
silent?: boolean;
|
|
19
38
|
}
|
|
39
|
+
export declare function normalizeSelector(selector: string): string;
|
|
20
40
|
export interface InflightOp {
|
|
21
41
|
label: string;
|
|
22
42
|
startedAt: number;
|
|
@@ -4,6 +4,7 @@ import type { ToolSession } from "../sdk";
|
|
|
4
4
|
import { type BrowserKindTag } from "./browser/registry";
|
|
5
5
|
import type { Observation, ScreenshotResult } from "./browser/tab-protocol";
|
|
6
6
|
import type { OutputMeta } from "./output-meta";
|
|
7
|
+
export { type AriaSnapshotOptions, buildAriaSnapshotScript, parseAriaRefSelector, } from "./browser/aria/aria-snapshot";
|
|
7
8
|
export { cmuxSnapshotToObservation, mapWaitUntil, resolveCmuxKind, serializeEval } from "./browser/cmux/rpc";
|
|
8
9
|
export { CmuxSocketClient } from "./browser/cmux/socket-client";
|
|
9
10
|
export { extractReadableFromHtml, type ReadableFormat, type ReadableResult } from "./browser/readable";
|
|
@@ -60,8 +60,7 @@ export declare class FindTool implements AgentTool<typeof findSchema, FindToolDe
|
|
|
60
60
|
private readonly session;
|
|
61
61
|
readonly name = "find";
|
|
62
62
|
readonly approval: "read";
|
|
63
|
-
readonly
|
|
64
|
-
readonly loadMode = "discoverable";
|
|
63
|
+
readonly loadMode = "essential";
|
|
65
64
|
readonly label = "Find";
|
|
66
65
|
readonly description: string;
|
|
67
66
|
readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
@@ -40,8 +40,7 @@ export declare class WriteTool implements AgentTool<typeof writeSchema, WriteToo
|
|
|
40
40
|
}, {}>;
|
|
41
41
|
readonly strict = true;
|
|
42
42
|
readonly concurrency = "exclusive";
|
|
43
|
-
readonly loadMode = "
|
|
44
|
-
readonly summary = "Write content to a file (creates or overwrites)";
|
|
43
|
+
readonly loadMode = "essential";
|
|
45
44
|
/** Stream matchers should see the real file content, not its JSON-escaped argument encoding. */
|
|
46
45
|
matcherDigest(args: unknown): string | undefined;
|
|
47
46
|
constructor(session: ToolSession);
|
|
@@ -4,9 +4,10 @@ export declare const MAX_IMAGE_INPUT_BYTES: number;
|
|
|
4
4
|
export declare const SUPPORTED_INPUT_IMAGE_MIME_TYPES: Set<string>;
|
|
5
5
|
/**
|
|
6
6
|
* Ollama and its local-backend family decode image input through llama.cpp /
|
|
7
|
-
* `stb_image`, which is compiled without WebP support
|
|
8
|
-
*
|
|
9
|
-
* to PNG/JPEG instead — the
|
|
7
|
+
* `stb_image`, which is compiled without WebP support. The first-party Codex
|
|
8
|
+
* Responses backend also rejects WebP `input_image.image_url` data URLs. Detect
|
|
9
|
+
* those models so the resize pipeline encodes to PNG/JPEG instead — the
|
|
10
|
+
* automatic equivalent of `OMP_NO_WEBP=1`.
|
|
10
11
|
*/
|
|
11
12
|
export declare function modelLacksWebpSupport(model: Pick<Model, "provider" | "api" | "imageInputDecoder"> | undefined): boolean;
|
|
12
13
|
/**
|
package/dist/types/utils/jj.d.ts
CHANGED
|
@@ -47,3 +47,28 @@ export declare const repo: {
|
|
|
47
47
|
/** Check whether `cwd` is inside a Jujutsu repository. */
|
|
48
48
|
is(cwd: string): Promise<boolean>;
|
|
49
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Detect a "pure" Jujutsu workspace — one where Git-mutating automation has
|
|
52
|
+
* no safe Git target. Invoking `git checkout -b`, `git worktree add`, or
|
|
53
|
+
* `git apply` against a pure jj workspace either fails outright (no `.git/`
|
|
54
|
+
* present) or mutates state that jj itself cannot reconcile.
|
|
55
|
+
*
|
|
56
|
+
* `cwd` is "pure jj" iff its nearest jj workspace ancestor is **closer than**
|
|
57
|
+
* its nearest Git checkout ancestor (or no Git checkout is present at all).
|
|
58
|
+
* Both lookups walk upward from `cwd`, so the deeper ancestor is the one the
|
|
59
|
+
* user is actually working inside.
|
|
60
|
+
*
|
|
61
|
+
* Returns:
|
|
62
|
+
* - `false` for plain Git checkouts (no jj metadata anywhere up the tree).
|
|
63
|
+
* - `false` for colocated jj-git workspaces — `jj git init --colocate` keeps
|
|
64
|
+
* `.jj/` and `.git/` at the same root.
|
|
65
|
+
* - `false` when a nested Git checkout (e.g. a vendored repo or fixture)
|
|
66
|
+
* lives **under** an outer jj workspace; Git automation targets the inner
|
|
67
|
+
* repo and never touches the surrounding jj tree.
|
|
68
|
+
* - `true` when jj is the deeper ancestor — either a standalone pure jj
|
|
69
|
+
* workspace, or a jj workspace nested under an unrelated outer Git
|
|
70
|
+
* checkout, where Git automation against the outer root would silently
|
|
71
|
+
* bypass jj.
|
|
72
|
+
* - `false` for directories backed by neither tool.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isPureJjRepo(cwd: string): Promise<boolean>;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type Api, type Model } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { ModelRegistry } from "../config/model-registry";
|
|
3
3
|
import type { Settings } from "../config/settings";
|
|
4
|
-
export declare const TITLE_LOCAL_FALLBACK_DELAY_MS = 10000;
|
|
5
|
-
export declare function raceFirstNonNull<T>(primary: Promise<T | null>, startFallback: () => Promise<T | null>, delayMs?: number, onPrimaryWinAfterFallback?: () => void): Promise<T | null>;
|
|
6
4
|
/**
|
|
7
5
|
* Generate a title for a session based on the first user message.
|
|
8
6
|
*
|