@oh-my-pi/pi-coding-agent 16.1.15 → 16.1.17
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 +78 -0
- package/dist/cli.js +3531 -3812
- package/dist/types/auto-thinking/classifier.d.ts +4 -2
- package/dist/types/cli/args.d.ts +2 -5
- package/dist/types/cli/flag-tables.d.ts +2 -2
- package/dist/types/cli/session-picker.d.ts +4 -2
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/model-discovery.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/settings-schema.d.ts +12 -1
- package/dist/types/eval/agent-bridge.d.ts +19 -0
- package/dist/types/eval/js/shared/helpers.d.ts +1 -13
- package/dist/types/eval/js/shared/types.d.ts +1 -1
- package/dist/types/eval/js/worker-protocol.d.ts +1 -1
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +22 -7
- package/dist/types/extensibility/plugins/loader.d.ts +16 -9
- package/dist/types/extensibility/tool-event-input.d.ts +2 -0
- package/dist/types/hindsight/content.d.ts +2 -10
- package/dist/types/internal-urls/local-protocol.d.ts +18 -1
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -0
- package/dist/types/modes/components/plugin-settings.d.ts +5 -0
- package/dist/types/modes/components/session-selector.d.ts +25 -0
- package/dist/types/modes/components/status-line/types.d.ts +1 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +11 -0
- package/dist/types/session/agent-session.d.ts +6 -6
- package/dist/types/session/provider-image-budget.d.ts +3 -0
- package/dist/types/session/session-context.d.ts +6 -5
- package/dist/types/task/isolation-runner.d.ts +128 -0
- package/dist/types/task/parallel.d.ts +4 -0
- package/dist/types/task/worktree.d.ts +14 -1
- package/dist/types/thinking.d.ts +23 -1
- package/dist/types/tiny/title-client.d.ts +2 -2
- package/dist/types/tools/eval-render.d.ts +3 -0
- package/dist/types/tools/eval.d.ts +11 -17
- package/dist/types/tools/todo.d.ts +26 -28
- package/dist/types/tui/output-block.d.ts +8 -0
- package/dist/types/utils/image-resize.d.ts +2 -0
- package/dist/types/utils/tools-manager.d.ts +2 -0
- package/dist/types/web/search/providers/exa.d.ts +2 -0
- package/package.json +12 -12
- package/scripts/build-binary.ts +18 -4
- package/src/auto-thinking/classifier.ts +7 -2
- package/src/cli/args.ts +4 -5
- package/src/cli/flag-tables.ts +3 -3
- package/src/cli/gallery-fixtures/interaction.ts +6 -9
- package/src/cli/gallery-fixtures/shell.ts +15 -23
- package/src/cli/profile-alias.ts +38 -7
- package/src/cli/session-picker.ts +17 -3
- package/src/cli/usage-cli.ts +5 -1
- package/src/commands/launch.ts +3 -3
- package/src/config/model-discovery.ts +59 -8
- package/src/config/model-registry.ts +74 -3
- package/src/config/settings-schema.ts +13 -1
- package/src/discovery/omp-extension-roots.ts +1 -3
- package/src/edit/renderer.ts +34 -12
- package/src/eval/__tests__/agent-bridge.test.ts +462 -3
- package/src/eval/__tests__/helpers-local-roots.test.ts +2 -5
- package/src/eval/__tests__/julia-prelude.test.ts +1 -30
- package/src/eval/__tests__/prelude-agent.test.ts +42 -8
- package/src/eval/agent-bridge.ts +301 -71
- package/src/eval/jl/prelude.jl +32 -227
- package/src/eval/jl/runner.jl +38 -12
- package/src/eval/js/shared/helpers.ts +1 -114
- package/src/eval/js/shared/prelude.txt +13 -27
- package/src/eval/js/shared/runtime.ts +0 -6
- package/src/eval/js/shared/types.ts +1 -1
- package/src/eval/js/worker-protocol.ts +1 -1
- package/src/eval/py/__tests__/prelude.test.ts +13 -0
- package/src/eval/py/executor.ts +1 -1
- package/src/eval/py/prelude.py +47 -105
- package/src/eval/py/runner.py +0 -6
- package/src/eval/rb/prelude.rb +21 -189
- package/src/eval/rb/runner.rb +116 -9
- package/src/export/html/tool-views.generated.js +29 -29
- package/src/extensibility/extensions/wrapper.ts +3 -2
- package/src/extensibility/hooks/tool-wrapper.ts +4 -3
- package/src/extensibility/plugins/legacy-pi-compat.ts +40 -8
- package/src/extensibility/plugins/loader.ts +71 -23
- package/src/extensibility/plugins/marketplace/manager.ts +134 -0
- package/src/extensibility/tool-event-input.ts +57 -0
- package/src/hindsight/content.ts +21 -12
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/internal-urls/local-protocol.ts +100 -53
- package/src/main.ts +15 -4
- package/src/mcp/tool-bridge.ts +27 -2
- package/src/mnemopi/state.ts +5 -2
- package/src/modes/acp/acp-event-mapper.ts +7 -2
- package/src/modes/components/agent-transcript-viewer.ts +193 -41
- package/src/modes/components/chat-transcript-builder.ts +6 -0
- package/src/modes/components/custom-editor.test.ts +18 -1
- package/src/modes/components/custom-editor.ts +77 -45
- package/src/modes/components/hook-editor.ts +15 -2
- package/src/modes/components/plugin-settings.ts +7 -1
- package/src/modes/components/session-selector.ts +143 -29
- package/src/modes/components/settings-selector.ts +2 -2
- package/src/modes/components/status-line/component.ts +52 -8
- package/src/modes/components/status-line/segments.ts +5 -1
- package/src/modes/components/status-line/types.ts +1 -0
- package/src/modes/components/welcome.ts +12 -14
- package/src/modes/controllers/command-controller.ts +21 -5
- package/src/modes/controllers/input-controller.ts +115 -3
- package/src/modes/controllers/selector-controller.ts +19 -1
- package/src/modes/interactive-mode.ts +3 -3
- package/src/modes/rpc/rpc-mode.ts +6 -0
- package/src/modes/utils/copy-targets.ts +7 -2
- package/src/modes/utils/ui-helpers.ts +3 -3
- package/src/prompts/system/system-prompt.md +3 -3
- package/src/prompts/system/workflow-notice.md +3 -3
- package/src/prompts/tools/bash.md +16 -0
- package/src/prompts/tools/eval.md +19 -19
- package/src/prompts/tools/todo.md +1 -1
- package/src/sdk.ts +8 -10
- package/src/session/agent-session.ts +422 -97
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/session-context.ts +14 -7
- package/src/session/session-storage.ts +24 -2
- package/src/session/snapcompact-inline.ts +19 -3
- package/src/slash-commands/builtin-registry.ts +0 -22
- package/src/slash-commands/helpers/usage-report.ts +9 -1
- package/src/task/index.ts +61 -207
- package/src/task/isolation-runner.ts +354 -0
- package/src/task/parallel.ts +6 -1
- package/src/task/worktree.ts +46 -9
- package/src/thinking.ts +29 -2
- package/src/tiny/title-client.ts +75 -21
- package/src/tools/ask.ts +44 -38
- package/src/tools/bash.ts +9 -2
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/eval-render.ts +34 -27
- package/src/tools/eval.ts +100 -103
- package/src/tools/index.ts +8 -1
- package/src/tools/read.ts +136 -60
- package/src/tools/todo.ts +60 -64
- package/src/tui/code-cell.ts +1 -1
- package/src/tui/output-block.ts +11 -0
- package/src/utils/image-resize.ts +30 -0
- package/src/utils/tools-manager.ts +67 -10
- package/src/web/search/providers/exa.ts +85 -1
|
@@ -25,10 +25,12 @@ export interface ClassifyDifficultyDeps {
|
|
|
25
25
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Classify `promptText` and return a concrete effort clamped to `deps.model
|
|
28
|
+
* Classify `promptText` and return a concrete effort clamped to `deps.model`,
|
|
29
|
+
* or `undefined` when the model has no controllable effort surface (auto has
|
|
30
|
+
* nothing to pick — the caller leaves the prior reasoning level in place).
|
|
29
31
|
* @throws when the backend cannot produce a usable classification.
|
|
30
32
|
*/
|
|
31
|
-
export declare function classifyDifficulty(promptText: string, deps: ClassifyDifficultyDeps): Promise<Effort>;
|
|
33
|
+
export declare function classifyDifficulty(promptText: string, deps: ClassifyDifficultyDeps): Promise<Effort | undefined>;
|
|
32
34
|
/** Map the online 4-way level keyword to an {@link Effort}; earliest match wins. */
|
|
33
35
|
export declare function parseDifficultyLevel(text: string): Effort | undefined;
|
|
34
36
|
/** Map the local 3-way bucket keyword to an {@link Effort}; earliest match wins. */
|
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* CLI argument parsing and help display
|
|
3
|
-
*/
|
|
4
|
-
import { type Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
1
|
+
import { type ConfiguredThinkingLevel } from "../thinking";
|
|
5
2
|
export type Mode = "text" | "json" | "rpc" | "acp" | "rpc-ui";
|
|
6
3
|
export interface Args {
|
|
7
4
|
cwd?: string;
|
|
@@ -18,7 +15,7 @@ export interface Args {
|
|
|
18
15
|
apiKey?: string;
|
|
19
16
|
systemPrompt?: string;
|
|
20
17
|
appendSystemPrompt?: string;
|
|
21
|
-
thinking?:
|
|
18
|
+
thinking?: ConfiguredThinkingLevel;
|
|
22
19
|
hideThinking?: boolean;
|
|
23
20
|
advisor?: boolean;
|
|
24
21
|
continue?: boolean;
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* tables), they're passed in through {@link ParseDeps} and `args.ts` wires the
|
|
30
30
|
* real implementations at the dispatch site.
|
|
31
31
|
*/
|
|
32
|
-
import type {
|
|
32
|
+
import type { ConfiguredThinkingLevel } from "../thinking";
|
|
33
33
|
import type { Args } from "./args";
|
|
34
34
|
/**
|
|
35
35
|
* Runtime dependencies injected into setters that need to validate input or
|
|
@@ -44,7 +44,7 @@ export interface ParseDeps {
|
|
|
44
44
|
logger: {
|
|
45
45
|
warn: (message: string, meta?: Record<string, unknown>) => void;
|
|
46
46
|
};
|
|
47
|
-
|
|
47
|
+
parseThinking: (value: string | null | undefined) => ConfiguredThinkingLevel | undefined;
|
|
48
48
|
builtinToolNames: readonly string[];
|
|
49
49
|
thinkingEfforts: readonly string[];
|
|
50
50
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { SessionInfo } from "../session/session-listing";
|
|
2
2
|
/**
|
|
3
3
|
* Show the TUI session selector and return the selected session, or null if
|
|
4
|
-
* cancelled.
|
|
5
|
-
*
|
|
4
|
+
* cancelled. Rendered as a fullscreen overlay on the terminal's alternate
|
|
5
|
+
* screen, so the list scrolls and rows are clickable with the mouse. Tab
|
|
6
|
+
* toggles between current-folder and all-projects scope; the all-projects list
|
|
7
|
+
* is loaded lazily via `SessionManager.listAll`.
|
|
6
8
|
*/
|
|
7
9
|
export declare function selectSession(sessions: SessionInfo[], options?: {
|
|
8
10
|
allSessions?: SessionInfo[];
|
|
@@ -92,7 +92,7 @@ export default class Index extends Command {
|
|
|
92
92
|
};
|
|
93
93
|
thinking: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
94
94
|
description: string;
|
|
95
|
-
options:
|
|
95
|
+
options: string[];
|
|
96
96
|
};
|
|
97
97
|
"hide-thinking": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
98
98
|
description: string;
|
|
@@ -38,6 +38,7 @@ export interface DiscoveryContext {
|
|
|
38
38
|
export declare function discoverModelsByProviderType(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
39
39
|
export declare function discoverOllamaModels(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
40
40
|
export declare function discoverLlamaCppModels(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
41
|
+
export declare function discoverLlamaCppModelContextWindow(model: Pick<Model<Api>, "provider" | "id" | "baseUrl" | "headers">, ctx: DiscoveryContext): Promise<number | undefined>;
|
|
41
42
|
export declare function discoverOpenAIModelsList(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
42
43
|
/**
|
|
43
44
|
* Discover models from an Anthropic+OpenAI-compatible reseller proxy that
|
|
@@ -89,6 +89,10 @@ export declare class ModelRegistry {
|
|
|
89
89
|
refresh(strategy?: ModelRefreshStrategy): Promise<void>;
|
|
90
90
|
refreshInBackground(strategy?: ModelRefreshStrategy): void;
|
|
91
91
|
refreshProvider(providerId: string, strategy?: ModelRefreshStrategy): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Refresh dynamic metadata that can appear only after a local model loads.
|
|
94
|
+
*/
|
|
95
|
+
refreshSelectedModelMetadata(model: Model<Api>): Promise<Model<Api>>;
|
|
92
96
|
/**
|
|
93
97
|
* Discover models for providers registered at runtime via `fetchDynamicModels`
|
|
94
98
|
* (extension providers). Merges the discovered catalog into the existing model
|
|
@@ -3726,7 +3726,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3726
3726
|
readonly tab: "tools";
|
|
3727
3727
|
readonly group: "Discovery & MCP";
|
|
3728
3728
|
readonly label: "Essential Tools Override";
|
|
3729
|
-
readonly description: "Override the always-loaded built-in tools (default: read, bash, edit). Leave empty to use defaults.";
|
|
3729
|
+
readonly description: "Override the always-loaded built-in tools (default: read, bash, edit, write, find, eval). Leave empty to use defaults.";
|
|
3730
3730
|
};
|
|
3731
3731
|
};
|
|
3732
3732
|
readonly "mcp.enableProjectConfig": {
|
|
@@ -4935,6 +4935,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
4935
4935
|
readonly description: "Enable Exa basic search, deep search, code search, and crawl tools";
|
|
4936
4936
|
};
|
|
4937
4937
|
};
|
|
4938
|
+
readonly "exa.searchDelayMs": {
|
|
4939
|
+
readonly type: "number";
|
|
4940
|
+
readonly default: 1000;
|
|
4941
|
+
readonly ui: {
|
|
4942
|
+
readonly tab: "providers";
|
|
4943
|
+
readonly group: "Services";
|
|
4944
|
+
readonly label: "Exa Search Delay";
|
|
4945
|
+
readonly description: "Minimum delay between Exa web search requests in milliseconds; set 0 to disable pacing";
|
|
4946
|
+
};
|
|
4947
|
+
};
|
|
4938
4948
|
readonly "exa.enableResearcher": {
|
|
4939
4949
|
readonly type: "boolean";
|
|
4940
4950
|
readonly default: false;
|
|
@@ -5202,6 +5212,7 @@ export interface TtsrSettings {
|
|
|
5202
5212
|
export interface ExaSettings {
|
|
5203
5213
|
enabled: boolean;
|
|
5204
5214
|
enableSearch: boolean;
|
|
5215
|
+
searchDelayMs: number;
|
|
5205
5216
|
enableResearcher: boolean;
|
|
5206
5217
|
enableWebsets: boolean;
|
|
5207
5218
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type NestedRepoPatch } from "../task/worktree";
|
|
1
2
|
import type { ToolSession } from "../tools";
|
|
2
3
|
import type { JsStatusEvent } from "./js/shared/types";
|
|
3
4
|
import "../tools/review";
|
|
@@ -17,6 +18,24 @@ export interface EvalAgentResult {
|
|
|
17
18
|
id: string;
|
|
18
19
|
model?: string | string[];
|
|
19
20
|
structured: boolean;
|
|
21
|
+
/** True iff this run executed inside an isolation worktree. */
|
|
22
|
+
isolated?: boolean;
|
|
23
|
+
/** Captured patch artifact (patch mode) — surfaced regardless of `apply`. */
|
|
24
|
+
patchPath?: string;
|
|
25
|
+
/** Captured branch (branch mode) — surfaced regardless of `apply`. */
|
|
26
|
+
branchName?: string;
|
|
27
|
+
/** Captured nested repository patches — surfaced for isolated `apply=false` manual application. */
|
|
28
|
+
nestedPatches?: NestedRepoPatch[];
|
|
29
|
+
/**
|
|
30
|
+
* Tri-state apply outcome for isolated runs:
|
|
31
|
+
* - `true` — apply ran (or had nothing to do) and left the repo clean.
|
|
32
|
+
* - `false` — apply attempted and failed; artifacts preserved.
|
|
33
|
+
* - `null` — caller opted out via `apply=false`.
|
|
34
|
+
* Omitted for non-isolated runs.
|
|
35
|
+
*/
|
|
36
|
+
changesApplied?: boolean | null;
|
|
37
|
+
/** Human-readable isolation apply/merge summary; kept out of schema-backed `text`. */
|
|
38
|
+
isolationSummary?: string;
|
|
20
39
|
};
|
|
21
40
|
}
|
|
22
41
|
/**
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import type { JsStatusEvent } from "./types";
|
|
2
2
|
export interface HelperOptions {
|
|
3
|
-
path?: string;
|
|
4
|
-
hidden?: boolean;
|
|
5
|
-
maxDepth?: number;
|
|
6
3
|
limit?: number;
|
|
7
4
|
offset?: number;
|
|
8
|
-
reverse?: boolean;
|
|
9
|
-
unique?: boolean;
|
|
10
|
-
count?: boolean;
|
|
11
5
|
}
|
|
12
6
|
/**
|
|
13
7
|
* Inputs the helper factory needs from its host runtime. `cwd` is a getter so the runtime
|
|
@@ -27,18 +21,12 @@ export interface HelperContext {
|
|
|
27
21
|
}
|
|
28
22
|
/**
|
|
29
23
|
* The set of functions exposed to user code via `globalThis.__omp_helpers__`. The JS
|
|
30
|
-
* prelude reads from this bag and attaches short aliases (`read`, `write`, `
|
|
24
|
+
* prelude reads from this bag and attaches short aliases (`read`, `write`, `env`, ...)
|
|
31
25
|
* onto the global scope.
|
|
32
26
|
*/
|
|
33
27
|
export interface HelperBundle {
|
|
34
28
|
read(rawPath: string, options?: HelperOptions): Promise<string>;
|
|
35
29
|
writeFile(rawPath: string, data: unknown): Promise<string>;
|
|
36
|
-
append(rawPath: string, content: string): Promise<string>;
|
|
37
|
-
sortText(text: string, options?: HelperOptions): string;
|
|
38
|
-
uniqText(text: string, options?: HelperOptions): string | Array<[number, string]>;
|
|
39
|
-
counter(items: string | string[], options?: HelperOptions): Array<[number, string]>;
|
|
40
|
-
diff(rawA: string, rawB: string): Promise<string>;
|
|
41
|
-
tree(searchPath?: string, options?: HelperOptions): Promise<string>;
|
|
42
30
|
env(key?: string, value?: string): string | Record<string, string> | undefined;
|
|
43
31
|
}
|
|
44
32
|
export declare function createHelpers(ctx: HelperContext): HelperBundle;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Structured status payload emitted by helpers (`read`, `write`, `
|
|
2
|
+
* Structured status payload emitted by helpers (`read`, `write`, `env`, etc.) and the
|
|
3
3
|
* tool-call bridge. Surfaces to the model as part of `displays` so it has machine-readable
|
|
4
4
|
* context about what side effects happened.
|
|
5
5
|
*/
|
|
@@ -5,7 +5,7 @@ export interface SessionSnapshot {
|
|
|
5
5
|
sessionId: string;
|
|
6
6
|
/**
|
|
7
7
|
* On-disk roots the helpers substitute for internal-URL schemes
|
|
8
|
-
* (e.g. `{ local: "/…/artifacts/local" }`). Lets `read`/`write
|
|
8
|
+
* (e.g. `{ local: "/…/artifacts/local" }`). Lets `read`/`write`
|
|
9
9
|
* accept `local://…` paths instead of writing a literal `local:/` directory.
|
|
10
10
|
*/
|
|
11
11
|
localRoots?: Record<string, string>;
|
|
@@ -45,7 +45,7 @@ export interface PythonExecutorOptions {
|
|
|
45
45
|
artifactPath?: string;
|
|
46
46
|
artifactId?: string;
|
|
47
47
|
/**
|
|
48
|
-
* On-disk roots the prelude helpers (`read`/`write
|
|
48
|
+
* On-disk roots the prelude helpers (`read`/`write`) substitute for
|
|
49
49
|
* internal-URL schemes (e.g. `{ local: "/…/artifacts/local" }`). Exported to
|
|
50
50
|
* the kernel as `PI_EVAL_LOCAL_ROOTS` (JSON) so `write("local://x")` lands
|
|
51
51
|
* where `read local://x` resolves instead of a literal `local:/` directory.
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
/**
|
|
3
3
|
* Compute the bunfs package root from the compiled binary's `import.meta.dir`
|
|
4
|
-
* (or any stand-in supplied by tests). Bun
|
|
5
|
-
* (`/$bunfs/root` or `<drive>:\~BUN\root`) for imported modules as well as the
|
|
6
|
-
* entrypoint, so the normal path is `<root>/packages`.
|
|
4
|
+
* (or any stand-in supplied by tests). Bun compiled binaries report one of:
|
|
7
5
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
11
|
-
* `<
|
|
6
|
+
* - the bunfs mount root itself — `/$bunfs/root` or `<drive>:\~BUN\root` (Bun
|
|
7
|
+
* 1.2.x and early 1.3.x). Append `packages` for the canonical layout.
|
|
8
|
+
* - the bunfs mount root followed by the binary's basename — `//root/<bin>`
|
|
9
|
+
* on POSIX or `<drive>:\~BUN\root\<bin>.exe` on Windows (observed on Bun
|
|
10
|
+
* 1.3.14 with the cross-compiled `omp-darwin-arm64` release asset — issue
|
|
11
|
+
* #3329). The trailing segment is stripped so the result still lands on
|
|
12
|
+
* `<root>/packages`.
|
|
13
|
+
* - the module's own source directory if a future Bun release switches to
|
|
14
|
+
* module-specific `import.meta.dir` values:
|
|
15
|
+
* `<bunfs>/packages/coding-agent/src/extensibility/plugins`.
|
|
16
|
+
* The bunfs-root-with-binary branch slices the original `metaDir`, and
|
|
17
|
+
* `bunfsPath` uses a matching double-slash-preserving join, so the bunfs-native
|
|
18
|
+
* prefix is preserved verbatim — `path.posix.join` collapses `//root` to
|
|
19
|
+
* `/root`, but Bun's bunfs lookup is keyed on the exact `//root` form.
|
|
12
20
|
*
|
|
13
21
|
* Exported for tests; production callers use `BUNFS_PACKAGE_ROOT` below.
|
|
14
22
|
*/
|
|
@@ -22,6 +30,13 @@ export declare function __computeBunfsPackageRoot(metaDir: string, pathImpl?: ty
|
|
|
22
30
|
* older cache entry, recreating mixed-runtime plugin loading.
|
|
23
31
|
*/
|
|
24
32
|
export declare function __computeBundledSelfPackageRoot(metaDir: string, pathImpl?: typeof path): string;
|
|
33
|
+
/**
|
|
34
|
+
* Join a computed bunfs package root with descendants without collapsing
|
|
35
|
+
* Bun's POSIX `//root` mount prefix.
|
|
36
|
+
*
|
|
37
|
+
* Exported for tests; production callers use `bunfsPath` below.
|
|
38
|
+
*/
|
|
39
|
+
export declare function __joinBunfsPath(root: string, segments: readonly string[], pathImpl?: typeof path): string;
|
|
25
40
|
/**
|
|
26
41
|
* Drop overrides whose targets are missing on disk so they can fall through to
|
|
27
42
|
* the canonical-resolution path. Exported for the test seam in #2168.
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import type { InstalledPlugin } from "./types";
|
|
2
|
+
/** Installed plugin plus the root scope that supplied its runtime metadata. */
|
|
3
|
+
export interface ScopedInstalledPlugin extends InstalledPlugin {
|
|
4
|
+
scope: "user" | "project";
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* Get list of enabled plugins with their resolved configurations.
|
|
4
8
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Enumerates two plugin roots in order: the user root
|
|
10
|
+
* (`getPluginsDir(home)`) and, when a project anchor (`.omp/` or `.git/`)
|
|
11
|
+
* exists at or above `cwd`, the project root
|
|
12
|
+
* (`<projectAnchor>/.omp/plugins`). Each root contributes the union of its
|
|
13
|
+
* `package.json#dependencies` and `omp-plugins.lock.json#plugins`. Project
|
|
14
|
+
* entries shadow user entries with the same package name, matching the
|
|
15
|
+
* shadow semantics of `MarketplaceManager.listInstalledPlugins`.
|
|
16
|
+
*
|
|
17
|
+
* The optional `home` parameter pins the user plugins root for callers that
|
|
18
|
+
* need to enumerate plugins relative to a non-default home (tests with a
|
|
19
|
+
* tempdir, discovery loaders threaded with `LoadContext.home`).
|
|
13
20
|
*/
|
|
14
21
|
export declare function getEnabledPlugins(cwd: string, opts?: {
|
|
15
22
|
home?: string;
|
|
16
|
-
}): Promise<
|
|
23
|
+
}): Promise<ScopedInstalledPlugin[]>;
|
|
17
24
|
/**
|
|
18
25
|
* Declared manifest entries paired with their resolved file path. Returns one
|
|
19
26
|
* record per declared entry — base entries first, then enabled-feature entries
|
|
@@ -64,14 +64,6 @@ export interface RetentionTranscript {
|
|
|
64
64
|
transcript: string | null;
|
|
65
65
|
messageCount: number;
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Format messages into a retention transcript using `[role: ...]` markers.
|
|
69
|
-
*
|
|
70
|
-
* - When `retainFullWindow` is true, all messages are included (used when the
|
|
71
|
-
* caller pre-sliced the window itself).
|
|
72
|
-
* - Otherwise, only the last user turn (last user message → end) is retained.
|
|
73
|
-
*
|
|
74
|
-
* Messages are tag-stripped before framing to break the recall→retain loop.
|
|
75
|
-
* Returns `{ transcript: null }` when nothing meaningful survives.
|
|
76
|
-
*/
|
|
77
67
|
export declare function prepareRetentionTranscript(messages: HindsightMessage[], retainFullWindow?: boolean): RetentionTranscript;
|
|
68
|
+
/** Format only user-authored messages for memory fact/entity extraction. */
|
|
69
|
+
export declare function prepareUserRetentionTranscript(messages: HindsightMessage[]): RetentionTranscript;
|
|
@@ -8,7 +8,7 @@ export declare function resolveLocalRoot(options: LocalProtocolOptions, platform
|
|
|
8
8
|
/** Resolve a local:// URL to an on-disk path under the active session's local root. */
|
|
9
9
|
export declare function resolveLocalUrlToPath(input: string | InternalUrl, options: LocalProtocolOptions, platform?: NodeJS.Platform): string;
|
|
10
10
|
/**
|
|
11
|
-
* On-disk roots the eval helpers (`read`/`write
|
|
11
|
+
* On-disk roots the eval helpers (`read`/`write`) substitute for
|
|
12
12
|
* internal-URL schemes so e.g. `write("local://x.md")` lands where a later
|
|
13
13
|
* `read local://x.md` resolves — instead of a literal `local:/` directory under
|
|
14
14
|
* the cwd (a stdlib `pathlib.Path`/`path.resolve` collapses `local://` to
|
|
@@ -17,6 +17,23 @@ export declare function resolveLocalUrlToPath(input: string | InternalUrl, optio
|
|
|
17
17
|
* re-plumbing the worker boundary.
|
|
18
18
|
*/
|
|
19
19
|
export declare function buildEvalUrlRoots(options: LocalProtocolOptions): Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a local:// URL to a regular on-disk file, applying the same
|
|
22
|
+
* realpath + containment guarantees as {@link LocalProtocolHandler.resolve}
|
|
23
|
+
* but WITHOUT reading or UTF-8-decoding its contents. Returns null when there
|
|
24
|
+
* is no active session or when the URL targets the root listing or a directory;
|
|
25
|
+
* throws the handler's not-found and "escapes local root" errors for missing
|
|
26
|
+
* files and symlink escapes.
|
|
27
|
+
*
|
|
28
|
+
* Options are resolved via {@link LocalProtocolHandler.resolveOptions} so the
|
|
29
|
+
* caller-options → override → registry order matches router resolution exactly.
|
|
30
|
+
* The read tool uses this to detect and emit image files from their real path
|
|
31
|
+
* before the text-only resource contract would decode the binary into mojibake.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveLocalUrlToFile(input: string | InternalUrl, context?: ResolveContext): Promise<{
|
|
34
|
+
path: string;
|
|
35
|
+
size: number;
|
|
36
|
+
} | null>;
|
|
20
37
|
/**
|
|
21
38
|
* Protocol handler for local:// URLs.
|
|
22
39
|
*
|
package/dist/types/main.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Args } from "./cli/args";
|
|
2
|
+
import { selectSession } from "./cli/session-picker";
|
|
2
3
|
import { ModelRegistry } from "./config/model-registry";
|
|
3
4
|
import { type ScopedModel } from "./config/model-resolver";
|
|
4
5
|
import { Settings } from "./config/settings";
|
|
@@ -59,6 +60,7 @@ export declare function applyResolvedSystemPromptInputs(options: CreateAgentSess
|
|
|
59
60
|
interface RunRootCommandDependencies {
|
|
60
61
|
createAgentSession?: typeof createAgentSession;
|
|
61
62
|
discoverAuthStorage?: typeof discoverAuthStorage;
|
|
63
|
+
selectSession?: typeof selectSession;
|
|
62
64
|
runAcpMode?: RunAcpMode;
|
|
63
65
|
settings?: Settings;
|
|
64
66
|
forceSetupWizard?: boolean;
|
|
@@ -34,6 +34,8 @@ export declare class ChatTranscriptBuilder {
|
|
|
34
34
|
get isEmpty(): boolean;
|
|
35
35
|
/** Discard all components and rebuild the whole transcript from `entries`. */
|
|
36
36
|
rebuild(entries: SessionMessageEntry[]): void;
|
|
37
|
+
/** Append newly persisted entries without rebuilding already rendered rows. */
|
|
38
|
+
append(entries: SessionMessageEntry[]): void;
|
|
37
39
|
/** Toggle tool-output expansion across every expandable component. */
|
|
38
40
|
setExpanded(expanded: boolean): void;
|
|
39
41
|
get expanded(): boolean;
|
|
@@ -19,6 +19,7 @@ export declare const SPACE_HOLD_MECHANICAL_RUN = 2;
|
|
|
19
19
|
/** Idle gap (ms) after the last repeated space that counts as the space bar being released, ending
|
|
20
20
|
* the push-to-talk recording. Must comfortably exceed the OS key-repeat interval. */
|
|
21
21
|
export declare const SPACE_HOLD_RELEASE_MS = 250;
|
|
22
|
+
export declare function extractBracketedPastePaths(data: string): string[] | undefined;
|
|
22
23
|
export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
|
|
23
24
|
export declare function extractBracketedImagePastePath(data: string): string | undefined;
|
|
24
25
|
/**
|
|
@@ -86,6 +87,8 @@ export declare class CustomEditor extends Editor {
|
|
|
86
87
|
onPasteImage?: () => Promise<boolean>;
|
|
87
88
|
/** Called when a bracketed paste contains one or more image-file paths. */
|
|
88
89
|
onPasteImagePath?: (path: string) => void | Promise<void>;
|
|
90
|
+
/** Called when a bracketed paste contains one or more non-image file paths. */
|
|
91
|
+
onPasteFilePath?: (path: string) => void | Promise<void>;
|
|
89
92
|
/** Called when the configured raw text-paste shortcut is pressed. */
|
|
90
93
|
onPasteTextRaw?: () => void;
|
|
91
94
|
/** Called when the configured dequeue shortcut is pressed. */
|
|
@@ -14,6 +14,11 @@ import type { InstalledPluginSummary } from "../../extensibility/plugins/marketp
|
|
|
14
14
|
import type { InstalledPlugin } from "../../extensibility/plugins/types";
|
|
15
15
|
/**
|
|
16
16
|
* Forwards a keystroke to `input`, but cancels via `onCancel` when the user presses Escape.
|
|
17
|
+
*
|
|
18
|
+
* Escape is decoded via `matchesKey` rather than a raw `\x1b` compare: inside the
|
|
19
|
+
* fullscreen settings overlay the kitty keyboard protocol is active (ghostty/kitty),
|
|
20
|
+
* where the Escape key arrives as the CSI-u sequence `\x1b[27u`, not a bare `\x1b`.
|
|
21
|
+
* The literal fallbacks preserve legacy single/double-escape on terminals without it.
|
|
17
22
|
*/
|
|
18
23
|
export declare function handleInputOrEscape(data: string, input: {
|
|
19
24
|
handleInput(data: string): void;
|
|
@@ -39,6 +39,12 @@ declare class SessionList implements Component {
|
|
|
39
39
|
/** Replace the visible dataset, e.g. when toggling folder/all-projects scope. */
|
|
40
40
|
setSessions(sessions: SessionInfo[], showCwd: boolean): void;
|
|
41
41
|
removeSession(sessionPath: string): void;
|
|
42
|
+
/** Resolve a list-local rendered-line index to a filtered-session index. */
|
|
43
|
+
hitTestSession(line: number): number | undefined;
|
|
44
|
+
/** Wheel notch: move the selection one step (clamped, no wrap). */
|
|
45
|
+
handleWheel(delta: -1 | 1): void;
|
|
46
|
+
/** Mouse click: select the session under the pointer and resume it. */
|
|
47
|
+
selectAndConfirm(index: number): void;
|
|
42
48
|
invalidate(): void;
|
|
43
49
|
render(width: number): readonly string[];
|
|
44
50
|
handleInput(keyData: string): void;
|
|
@@ -55,6 +61,13 @@ export interface SessionSelectorOptions {
|
|
|
55
61
|
* Omitted only in tests; defaults to a conservative 24 rows.
|
|
56
62
|
*/
|
|
57
63
|
getTerminalRows?: () => number;
|
|
64
|
+
/**
|
|
65
|
+
* Fill the whole viewport and pin the footer (hint + bottom border) to the
|
|
66
|
+
* last rows, so the footer stops drifting as the list window changes height.
|
|
67
|
+
* Set by the standalone `--resume` picker (fullscreen alternate screen); the
|
|
68
|
+
* in-editor selector leaves it off and renders compactly.
|
|
69
|
+
*/
|
|
70
|
+
fillHeight?: boolean;
|
|
58
71
|
}
|
|
59
72
|
/**
|
|
60
73
|
* Component that renders a session selector with optional confirmation dialog
|
|
@@ -63,6 +76,18 @@ export declare class SessionSelectorComponent extends Container {
|
|
|
63
76
|
#private;
|
|
64
77
|
constructor(sessions: SessionInfo[], onSelect: (session: SessionInfo) => void, onCancel: () => void, onExit: () => void, options?: SessionSelectorOptions);
|
|
65
78
|
setOnRequestRender(callback: () => void): void;
|
|
79
|
+
/**
|
|
80
|
+
* Concatenate the children's renders (like {@link Container}) while recording
|
|
81
|
+
* the line where the session list begins, so the fullscreen picker can hit-
|
|
82
|
+
* test mouse rows against the live list window. SessionList rebuilds its lines
|
|
83
|
+
* every frame, so Container's reference-memoization never applied here.
|
|
84
|
+
*
|
|
85
|
+
* In fill-height mode the body is padded (or, on a cramped terminal, trimmed)
|
|
86
|
+
* to leave exactly enough room for the footer at the screen bottom, so the
|
|
87
|
+
* footer is always visible and never drifts as the list window resizes. The
|
|
88
|
+
* in-editor selector just appends the footer directly.
|
|
89
|
+
*/
|
|
90
|
+
render(width: number): readonly string[];
|
|
66
91
|
handleInput(keyData: string): void;
|
|
67
92
|
getSessionList(): SessionList;
|
|
68
93
|
}
|
|
@@ -3,6 +3,7 @@ import { type ProviderDetails, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
|
3
3
|
import type { CompactOptions } from "../../extensibility/extensions/types";
|
|
4
4
|
import { theme } from "../../modes/theme/theme";
|
|
5
5
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
6
|
+
import type { OAuthAccountIdentity } from "../../session/auth-storage";
|
|
6
7
|
import type { CompactMode } from "../../session/compact-modes";
|
|
7
8
|
import { type ShakeMode } from "../../session/shake-types";
|
|
8
9
|
export declare class CommandController {
|
|
@@ -43,3 +44,4 @@ export declare class CommandController {
|
|
|
43
44
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
44
45
|
}
|
|
45
46
|
export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
|
|
47
|
+
export declare function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs: number, availableWidth: number, resolveActiveAccount?: (provider: string) => OAuthAccountIdentity | undefined): string;
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { type AutocompleteProvider, type SlashCommand } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
3
3
|
import { readImageFromClipboard, readTextFromClipboard } from "../../utils/clipboard";
|
|
4
|
+
/**
|
|
5
|
+
* Slash commands that may carry secrets in their arguments should never be
|
|
6
|
+
* persisted to history.
|
|
7
|
+
*
|
|
8
|
+
* - /login accepts three callback forms (redirect URL, query string, raw auth
|
|
9
|
+
* code) — all can contain OAuth code=/state= params.
|
|
10
|
+
* - /join <link> carries a 32-byte room key and optional write token.
|
|
11
|
+
* - /mcp add --token <token> carries a bearer token.
|
|
12
|
+
*
|
|
13
|
+
* The command name is extracted the same way as parseSlashCommand() — splitting
|
|
14
|
+
* on the earliest whitespace or colon — so /login:?code=... is correctly matched.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldSkipHistory(slashText: string): boolean;
|
|
4
17
|
export declare class InputController {
|
|
5
18
|
#private;
|
|
6
19
|
private ctx;
|
|
@@ -25,6 +38,7 @@ export declare class InputController {
|
|
|
25
38
|
abort?: boolean;
|
|
26
39
|
currentText?: string;
|
|
27
40
|
}): number;
|
|
41
|
+
handleFilePathPaste(filePath: string): Promise<void>;
|
|
28
42
|
handleImagePathPaste(path: string): Promise<void>;
|
|
29
43
|
handleImagePaste(): Promise<boolean>;
|
|
30
44
|
handleClipboardTextRawPaste(): Promise<void>;
|
|
@@ -5,6 +5,17 @@ export declare class SelectorController {
|
|
|
5
5
|
#private;
|
|
6
6
|
private ctx;
|
|
7
7
|
constructor(ctx: InteractiveModeContext);
|
|
8
|
+
/**
|
|
9
|
+
* Restore keyboard focus to whatever currently owns the editor slot. The
|
|
10
|
+
* slot can hold the editor itself or a hook selector/input/editor pushed
|
|
11
|
+
* in by `ExtensionUiController` — e.g. an approval prompt that fired while
|
|
12
|
+
* a fullscreen overlay was up. `overlayHandle.hide()` restores focus to
|
|
13
|
+
* the component focused when the overlay opened, which is stale in that
|
|
14
|
+
* case (the editor was swapped out): keys land on a hidden editor and the
|
|
15
|
+
* visible prompt receives nothing (issue #3349). Call this after the
|
|
16
|
+
* overlay hides to re-target focus at the visible slot owner.
|
|
17
|
+
*/
|
|
18
|
+
focusActiveEditorArea(): void;
|
|
8
19
|
/**
|
|
9
20
|
* Shows a selector component in place of the editor.
|
|
10
21
|
* @param create Factory that receives a `done` callback and returns the component and focus target
|
|
@@ -46,7 +46,7 @@ import type { CheckpointState } from "../tools/checkpoint";
|
|
|
46
46
|
import { type TodoItem, type TodoPhase } from "../tools/todo";
|
|
47
47
|
import type { ClientBridge } from "./client-bridge";
|
|
48
48
|
import { type CustomMessage } from "./messages";
|
|
49
|
-
import type { SessionContext } from "./session-context";
|
|
49
|
+
import type { BuildSessionContextOptions, SessionContext } from "./session-context";
|
|
50
50
|
import type { BranchSummaryEntry, NewSessionOptions } from "./session-entries";
|
|
51
51
|
import type { SessionManager } from "./session-manager";
|
|
52
52
|
import type { ShakeMode, ShakeResult } from "./shake-types";
|
|
@@ -590,12 +590,12 @@ export declare class AgentSession {
|
|
|
590
590
|
}[];
|
|
591
591
|
buildDisplaySessionContext(): SessionContext;
|
|
592
592
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
593
|
+
* Transcript for TUI display. Full history is kept for export/resume-style
|
|
594
|
+
* callers; live chat can collapse compacted history to keep the hot render
|
|
595
|
+
* surface bounded. Display-only — NEVER feed the result to
|
|
596
|
+
* `agent.replaceMessages` or a provider.
|
|
597
597
|
*/
|
|
598
|
-
buildTranscriptSessionContext(): SessionContext;
|
|
598
|
+
buildTranscriptSessionContext(options?: Pick<BuildSessionContextOptions, "collapseCompactedHistory">): SessionContext;
|
|
599
599
|
/** Convert session messages using the same pre-LLM pipeline as the active session. */
|
|
600
600
|
convertMessagesToLlm(messages: AgentMessage[], signal?: AbortSignal): Promise<Message[]>;
|
|
601
601
|
/** Apply session-level stream hooks to a direct side request. */
|
|
@@ -32,13 +32,14 @@ export declare function getRestorableSessionModels(models: Readonly<Record<strin
|
|
|
32
32
|
export declare function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null;
|
|
33
33
|
export interface BuildSessionContextOptions {
|
|
34
34
|
/**
|
|
35
|
-
* Build the
|
|
36
|
-
* every path entry
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* result to a provider.
|
|
35
|
+
* Build the display transcript instead of the LLM context. By default this
|
|
36
|
+
* preserves every path entry with compactions inline; set
|
|
37
|
+
* `collapseCompactedHistory` for the live TUI surface to render only the
|
|
38
|
+
* latest compacted tail.
|
|
40
39
|
*/
|
|
41
40
|
transcript?: boolean;
|
|
41
|
+
/** In transcript mode, elide entries replaced by the latest compaction. */
|
|
42
|
+
collapseCompactedHistory?: boolean;
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
45
|
* Build the session context from entries using tree traversal.
|