@oh-my-pi/pi-coding-agent 17.2.1 → 17.2.2
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 +47 -0
- package/dist/{CHANGELOG-dj46zzrm.md → CHANGELOG-xfpkakrn.md} +47 -0
- package/dist/cli.js +3891 -3885
- package/dist/types/config/keybindings.d.ts +6 -1
- package/dist/types/config/settings-schema.d.ts +16 -5
- package/dist/types/edit/hashline/block-resolver.d.ts +5 -5
- package/dist/types/edit/hashline/diff.d.ts +4 -4
- package/dist/types/eval/executor-base.d.ts +27 -0
- package/dist/types/eval/js/context-manager.d.ts +7 -0
- package/dist/types/eval/js/executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/runner.d.ts +64 -5
- package/dist/types/extensibility/extensions/types.d.ts +15 -0
- package/dist/types/extensibility/extensions/wrapper.d.ts +1 -1
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +1 -1
- package/dist/types/live/visualizer.d.ts +3 -1
- package/dist/types/modes/acp/acp-agent.d.ts +3 -3
- package/dist/types/modes/components/keybinding-hints.d.ts +1 -1
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +13 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/secrets/index.d.ts +22 -0
- package/dist/types/secrets/obfuscator.d.ts +1 -1
- package/dist/types/session/agent-session-types.d.ts +4 -0
- package/dist/types/session/agent-session.d.ts +9 -0
- package/dist/types/session/codex-auto-reset.d.ts +182 -64
- package/dist/types/session/session-storage.d.ts +5 -2
- package/dist/types/session/session-tools.d.ts +2 -1
- package/dist/types/session/turn-recovery.d.ts +7 -1
- package/dist/types/system-prompt.d.ts +8 -0
- package/dist/types/task/executor.d.ts +27 -0
- package/dist/types/task/persisted-revive.d.ts +7 -0
- package/dist/types/tools/bash-interceptor.d.ts +1 -1
- package/dist/types/tools/browser/attach.d.ts +9 -1
- package/dist/types/tools/browser/launch.d.ts +20 -1
- package/dist/types/tools/browser/registry.d.ts +2 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +8 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +1 -0
- package/dist/types/tools/browser/tab-worker.d.ts +3 -1
- package/dist/types/tools/shell-tokenize.d.ts +11 -0
- package/dist/types/utils/image-loading.d.ts +2 -0
- package/dist/types/web/search/providers/duckduckgo.d.ts +9 -0
- package/dist/types/web/search/types.d.ts +2 -2
- package/package.json +12 -12
- package/src/commit/agentic/index.ts +2 -1
- package/src/commit/pipeline.ts +3 -2
- package/src/config/keybindings.ts +6 -1
- package/src/config/settings-schema.ts +16 -3
- package/src/edit/hashline/block-resolver.ts +5 -5
- package/src/edit/hashline/diff.ts +22 -15
- package/src/edit/hashline/execute.ts +14 -13
- package/src/edit/renderer.ts +3 -3
- package/src/eval/executor-base.ts +39 -0
- package/src/eval/jl/executor.ts +13 -2
- package/src/eval/js/context-manager.ts +97 -14
- package/src/eval/js/executor.ts +3 -0
- package/src/eval/js/index.ts +1 -0
- package/src/eval/py/executor.ts +55 -15
- package/src/eval/rb/executor.ts +8 -1
- package/src/extensibility/extensions/runner.ts +121 -4
- package/src/extensibility/extensions/types.ts +15 -0
- package/src/extensibility/extensions/wrapper.ts +19 -2
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +5 -5
- package/src/live/visualizer.ts +8 -1
- package/src/lsp/index.ts +51 -11
- package/src/main.ts +3 -0
- package/src/modes/acp/acp-agent.ts +16 -5
- package/src/modes/components/assistant-message.ts +5 -10
- package/src/modes/components/custom-editor.ts +1 -1
- package/src/modes/components/keybinding-hints.ts +4 -13
- package/src/modes/components/status-line/segments.ts +4 -5
- package/src/modes/components/tool-execution.ts +4 -5
- package/src/modes/controllers/input-controller.ts +18 -40
- package/src/modes/controllers/live-command-controller.ts +1 -0
- package/src/modes/controllers/mcp-command-controller.ts +28 -11
- package/src/modes/interactive-mode.ts +59 -2
- package/src/modes/theme/theme.ts +13 -6
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/prompts/system/plan-mode-active.md +5 -5
- package/src/sdk.ts +47 -16
- package/src/secrets/index.ts +83 -3
- package/src/secrets/obfuscator.ts +70 -15
- package/src/session/agent-session-types.ts +7 -1
- package/src/session/agent-session.ts +393 -112
- package/src/session/codex-auto-reset.ts +594 -123
- package/src/session/eval-runner.ts +2 -0
- package/src/session/messages.ts +1 -1
- package/src/session/session-maintenance.ts +48 -1
- package/src/session/session-manager.ts +4 -3
- package/src/session/session-stats.ts +14 -3
- package/src/session/session-storage.ts +47 -15
- package/src/session/session-tools.ts +30 -2
- package/src/session/turn-recovery.ts +15 -2
- package/src/slash-commands/builtin-registry.ts +21 -15
- package/src/slash-commands/helpers/reset-usage.ts +2 -0
- package/src/system-prompt.ts +13 -1
- package/src/task/executor.ts +168 -15
- package/src/task/persisted-revive.ts +26 -1
- package/src/telemetry-export.ts +8 -4
- package/src/tools/bash-interceptor.ts +85 -8
- package/src/tools/bash.ts +1 -1
- package/src/tools/browser/attach.ts +35 -10
- package/src/tools/browser/launch.ts +60 -11
- package/src/tools/browser/registry.ts +18 -2
- package/src/tools/browser/tab-protocol.ts +8 -0
- package/src/tools/browser/tab-supervisor.ts +31 -4
- package/src/tools/browser/tab-worker.ts +32 -2
- package/src/tools/output-meta.ts +16 -1
- package/src/tools/shell-tokenize.ts +101 -0
- package/src/utils/image-loading.ts +8 -3
- package/src/utils/shell-snapshot.ts +31 -21
- package/src/web/search/providers/duckduckgo.ts +183 -15
- package/src/web/search/types.ts +6 -1
|
@@ -40,6 +40,7 @@ interface AppKeybindings {
|
|
|
40
40
|
"app.plan.toggle": true;
|
|
41
41
|
"app.history.search": true;
|
|
42
42
|
"app.stt.toggle": true;
|
|
43
|
+
"app.live.toggle": true;
|
|
43
44
|
}
|
|
44
45
|
export type AppKeybinding = keyof AppKeybindings;
|
|
45
46
|
declare module "@oh-my-pi/pi-tui" {
|
|
@@ -195,7 +196,7 @@ export declare const KEYBINDINGS: {
|
|
|
195
196
|
readonly description: "Suspend application";
|
|
196
197
|
};
|
|
197
198
|
readonly "app.display.reset": {
|
|
198
|
-
readonly defaultKeys: "
|
|
199
|
+
readonly defaultKeys: "alt+l";
|
|
199
200
|
readonly description: "Reset terminal display";
|
|
200
201
|
};
|
|
201
202
|
readonly "app.thinking.cycle": {
|
|
@@ -322,6 +323,10 @@ export declare const KEYBINDINGS: {
|
|
|
322
323
|
readonly defaultKeys: [];
|
|
323
324
|
readonly description: "Toggle speech-to-text (default gesture: hold Space)";
|
|
324
325
|
};
|
|
326
|
+
readonly "app.live.toggle": {
|
|
327
|
+
readonly defaultKeys: "ctrl+l";
|
|
328
|
+
readonly description: "Start or stop live voice mode (/live)";
|
|
329
|
+
};
|
|
325
330
|
};
|
|
326
331
|
/** Controls inherited keybinding lookup when creating a manager for a named profile. */
|
|
327
332
|
export interface KeybindingsCreateOptions {
|
|
@@ -5006,7 +5006,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5006
5006
|
} | {
|
|
5007
5007
|
readonly value: "xai";
|
|
5008
5008
|
readonly label: "xAI";
|
|
5009
|
-
readonly description: "Grok web search via xAI Responses API (
|
|
5009
|
+
readonly description: "Grok web search via xAI Responses API (uses SuperGrok/X Premium+ OAuth via /login xai-oauth, or XAI_API_KEY)";
|
|
5010
5010
|
} | {
|
|
5011
5011
|
readonly value: "zai";
|
|
5012
5012
|
readonly label: "Z.AI";
|
|
@@ -5110,7 +5110,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5110
5110
|
} | {
|
|
5111
5111
|
readonly value: "xai";
|
|
5112
5112
|
readonly label: "xAI";
|
|
5113
|
-
readonly description: "Grok web search via xAI Responses API (
|
|
5113
|
+
readonly description: "Grok web search via xAI Responses API (uses SuperGrok/X Premium+ OAuth via /login xai-oauth, or XAI_API_KEY)";
|
|
5114
5114
|
} | {
|
|
5115
5115
|
readonly value: "zai";
|
|
5116
5116
|
readonly label: "Z.AI";
|
|
@@ -5856,7 +5856,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5856
5856
|
readonly tab: "providers";
|
|
5857
5857
|
readonly group: "Services";
|
|
5858
5858
|
readonly label: "Codex Auto-Redeem Saved Resets";
|
|
5859
|
-
readonly description: "
|
|
5859
|
+
readonly description: "Spend saved Codex rate-limit resets automatically: restore an account blocked by an exhausted 5h or weekly window when a turn is stuck and no other account can take over, and salvage credits that are about to expire. unset asks before the first spend, yes spends without prompting, and no disables both checks.";
|
|
5860
5860
|
readonly options: readonly [{
|
|
5861
5861
|
readonly value: "unset";
|
|
5862
5862
|
readonly label: "Unset";
|
|
@@ -5879,7 +5879,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5879
5879
|
readonly tab: "providers";
|
|
5880
5880
|
readonly group: "Services";
|
|
5881
5881
|
readonly label: "Codex Auto-Redeem Min Block";
|
|
5882
|
-
readonly description: "Only auto-redeem when the natural
|
|
5882
|
+
readonly description: "Only auto-redeem when the natural unblock — the latest reset among the exhausted 5h/weekly windows — is at least this many minutes away (don't spend a scarce credit to save a short wait). Raise it (e.g. 360) to ignore 5h-only blocks.";
|
|
5883
5883
|
};
|
|
5884
5884
|
};
|
|
5885
5885
|
readonly "codexResets.keepCredits": {
|
|
@@ -5889,7 +5889,17 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5889
5889
|
readonly tab: "providers";
|
|
5890
5890
|
readonly group: "Services";
|
|
5891
5891
|
readonly label: "Codex Auto-Redeem Reserve";
|
|
5892
|
-
readonly description: "Never auto-spend below this many saved resets (0 = the last credit may be spent automatically).";
|
|
5892
|
+
readonly description: "Never auto-spend below this many saved resets (0 = the last credit may be spent automatically). Credits about to expire are exempt — a reserved credit that expires preserves nothing.";
|
|
5893
|
+
};
|
|
5894
|
+
};
|
|
5895
|
+
readonly "codexResets.salvageHorizonHours": {
|
|
5896
|
+
readonly type: "number";
|
|
5897
|
+
readonly default: 12;
|
|
5898
|
+
readonly ui: {
|
|
5899
|
+
readonly tab: "providers";
|
|
5900
|
+
readonly group: "Services";
|
|
5901
|
+
readonly label: "Codex Reset Salvage Horizon";
|
|
5902
|
+
readonly description: "Spend a saved Codex reset automatically when it would otherwise expire within this many hours and either chat window (5h or weekly) has meaningful usage to restore (0 disables expiry salvage).";
|
|
5893
5903
|
};
|
|
5894
5904
|
};
|
|
5895
5905
|
readonly "provider.appendOnlyContext": {
|
|
@@ -6319,6 +6329,7 @@ export interface CodexResetsSettings {
|
|
|
6319
6329
|
autoRedeem: CodexAutoRedeemMode;
|
|
6320
6330
|
minBlockedMinutes: number;
|
|
6321
6331
|
keepCredits: number;
|
|
6332
|
+
salvageHorizonHours: number;
|
|
6322
6333
|
}
|
|
6323
6334
|
export interface GcSettings {
|
|
6324
6335
|
blobs: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tree-sitter-backed {@link BlockResolver} for the hashline
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Tree-sitter-backed {@link BlockResolver} for the hashline `N*` locator.
|
|
3
|
+
* Bridges the pure hashline seam to the native `blockRangeAt` primitive in
|
|
4
|
+
* `@oh-my-pi/pi-natives`, which infers the language from the file path and
|
|
5
|
+
* returns the 1-indexed line span of the syntactic block beginning on the
|
|
6
|
+
* requested line (or `null` when none can be resolved).
|
|
7
7
|
*/
|
|
8
8
|
import type { BlockResolver } from "@oh-my-pi/hashline";
|
|
9
9
|
export declare const nativeBlockResolver: BlockResolver;
|
|
@@ -14,10 +14,10 @@ export interface HashlineDiffOptions {
|
|
|
14
14
|
skipHashValidation?: boolean;
|
|
15
15
|
/**
|
|
16
16
|
* Clipboard register shared across the sections of one patch preview.
|
|
17
|
-
* `CUT` in an earlier section feeds `
|
|
18
|
-
* matches apply. Multi-section previews MUST thread one
|
|
19
|
-
* sections in patch order; omitted, each section gets a
|
|
20
|
-
* private register (same-file cut/
|
|
17
|
+
* `CUT` in an earlier section feeds a register-backed `PUT` in a later one,
|
|
18
|
+
* so the preview matches apply. Multi-section previews MUST thread one
|
|
19
|
+
* register through sections in patch order; omitted, each section gets a
|
|
20
|
+
* private register (same-file cut/put still previews correctly).
|
|
21
21
|
*/
|
|
22
22
|
clipboard?: Clipboard;
|
|
23
23
|
}
|
|
@@ -90,6 +90,33 @@ export declare function attachSessionOwner(session: {
|
|
|
90
90
|
ownerIds: Set<string>;
|
|
91
91
|
hasFallbackOwner: boolean;
|
|
92
92
|
}, sessionId: string, ownerId: string | undefined): void;
|
|
93
|
+
/** Owner registry shared by every language's live/starting session records. */
|
|
94
|
+
export interface SessionOwners {
|
|
95
|
+
ownerIds: Set<string>;
|
|
96
|
+
hasFallbackOwner: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the session key an owner's eval cell runs on, forking `reset` away
|
|
100
|
+
* from shared kernels.
|
|
101
|
+
*
|
|
102
|
+
* Eval sessions are shared across agents by design (subagents inherit the
|
|
103
|
+
* parent's eval session id), so honoring `reset` on a co-owned kernel would
|
|
104
|
+
* destroy every other agent's state — including cells executing at that
|
|
105
|
+
* moment. When the requester does not exclusively own the live base session,
|
|
106
|
+
* its reset resolves to a deterministic per-owner fork key: the requester
|
|
107
|
+
* starts a fresh private kernel while co-owners keep the shared one. Once
|
|
108
|
+
* forked, the owner keeps resolving to its fork, and per-owner dispose reaps
|
|
109
|
+
* the fork since the requester is its only registered owner.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resolveOwnerScopedSessionKey(options: {
|
|
112
|
+
baseKey: string;
|
|
113
|
+
ownerId: string | undefined;
|
|
114
|
+
reset: boolean;
|
|
115
|
+
/** True when a live or starting session exists under `key`. */
|
|
116
|
+
hasSession: (key: string) => boolean;
|
|
117
|
+
/** Owner registry for the session under `key`, when inspectable. */
|
|
118
|
+
getOwners: (key: string) => SessionOwners | undefined;
|
|
119
|
+
}): string;
|
|
93
120
|
export interface ExecuteWithKernelBaseParams<TOptions extends KernelExecutorBaseOptions, TEnv extends KernelEnvPatch = Record<string, string | null>> {
|
|
94
121
|
kernel: GenericKernel<TEnv>;
|
|
95
122
|
code: string;
|
|
@@ -18,6 +18,8 @@ export declare function setJsEvalWorkerThreadForTests(enabled: boolean): boolean
|
|
|
18
18
|
export declare function executeInVmContext(options: {
|
|
19
19
|
sessionKey: string;
|
|
20
20
|
sessionId: string;
|
|
21
|
+
/** Logical owner identifier; scopes `reset` on shared contexts and retained-worker cleanup. */
|
|
22
|
+
ownerId?: string;
|
|
21
23
|
cwd: string;
|
|
22
24
|
session: ToolSession;
|
|
23
25
|
localRoots?: Record<string, string>;
|
|
@@ -31,6 +33,11 @@ export declare function executeInVmContext(options: {
|
|
|
31
33
|
}>;
|
|
32
34
|
export declare function resetVmContext(sessionKey: string): Promise<void>;
|
|
33
35
|
export declare function disposeAllVmContexts(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Shut down retained JS contexts owned solely by `ownerId` (e.g. a subagent's
|
|
38
|
+
* private fork); shared contexts just drop the owner registration.
|
|
39
|
+
*/
|
|
40
|
+
export declare function disposeVmContextsByOwner(ownerId: string): Promise<void>;
|
|
34
41
|
/**
|
|
35
42
|
* Smoke probe: spawn the JS evaluator through the worker-host entry and prove
|
|
36
43
|
* it answers the `init` handshake in a real isolated subprocess (not the inline
|
|
@@ -15,6 +15,8 @@ export interface JsExecutorOptions {
|
|
|
15
15
|
onStatus?: (event: JsStatusEvent) => void;
|
|
16
16
|
signal?: AbortSignal;
|
|
17
17
|
sessionId: string;
|
|
18
|
+
/** Logical owner identifier; scopes `reset` on shared contexts and retained-worker cleanup. */
|
|
19
|
+
kernelOwnerId?: string;
|
|
18
20
|
reset?: boolean;
|
|
19
21
|
sessionFile?: string;
|
|
20
22
|
artifactPath?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extension runner - executes extensions and manages their lifecycle.
|
|
3
3
|
*/
|
|
4
|
-
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
4
|
+
import type { AgentMessage, AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
5
5
|
import type { CredentialDisabledEvent, ImageContent, Model, ProviderResponseMetadata } from "@oh-my-pi/pi-ai";
|
|
6
6
|
import type { KeyId } from "@oh-my-pi/pi-tui";
|
|
7
7
|
import type { ModelRegistry } from "../../config/model-registry.js";
|
|
@@ -65,7 +65,6 @@ export declare class ExtensionRunner {
|
|
|
65
65
|
#private;
|
|
66
66
|
private readonly extensions;
|
|
67
67
|
private readonly runtime;
|
|
68
|
-
private readonly cwd;
|
|
69
68
|
private readonly sessionManager;
|
|
70
69
|
private readonly modelRegistry;
|
|
71
70
|
private readonly settings?;
|
|
@@ -74,7 +73,51 @@ export declare class ExtensionRunner {
|
|
|
74
73
|
markToolCallEmitted(toolCallId: string, toolName: string): void;
|
|
75
74
|
/** Consumes a {@link markToolCallEmitted} marker; true when the loop already emitted. */
|
|
76
75
|
consumeToolCallEmitted(toolCallId: string, toolName: string): boolean;
|
|
77
|
-
|
|
76
|
+
/** Wires the native-tool resolver used by {@link invokeNativeTool}. */
|
|
77
|
+
setNativeToolResolver(resolve: (name: string) => {
|
|
78
|
+
tool: AgentTool;
|
|
79
|
+
makeContext: () => AgentToolContext;
|
|
80
|
+
} | undefined): void;
|
|
81
|
+
/** Whether a native built-in of `name` is available to delegate to. */
|
|
82
|
+
hasNativeTool(name: string): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Run the native built-in of `name` with `params` and return its result — the delegation target
|
|
85
|
+
* of a same-tool `ctx.invokeTool`. Calls the unwrapped native `execute` directly with the loop's
|
|
86
|
+
* ordinary tool context, so it inherits the caller's already-granted approval (the caller is the
|
|
87
|
+
* same tool) rather than re-running the gate. `depth` guards a wrapper that recurses into itself;
|
|
88
|
+
* it is per call chain (threaded from the caller), not session-global, so concurrent independent
|
|
89
|
+
* delegations do not interfere.
|
|
90
|
+
*/
|
|
91
|
+
invokeNativeTool<TDetails = unknown>(name: string, params: Record<string, unknown>, options?: {
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
onUpdate?: AgentToolUpdateCallback<TDetails>;
|
|
94
|
+
depth?: number;
|
|
95
|
+
/**
|
|
96
|
+
* The caller tool's own context. Reused for the native call so metadata the native tool
|
|
97
|
+
* reads — `toolCall` (write/edit LSP batch flushing) and provider metadata /
|
|
98
|
+
* `providerSafetyApproved` (computer) — is preserved. Falls back to a fresh session tool
|
|
99
|
+
* context only when the caller had none.
|
|
100
|
+
*/
|
|
101
|
+
callerContext?: AgentToolContext;
|
|
102
|
+
}): Promise<AgentToolResult<TDetails>>;
|
|
103
|
+
constructor(extensions: Extension[], runtime: ExtensionRuntime,
|
|
104
|
+
/** Ignored: `cwd` is always read live via the `cwd` getter below, not cached here. */
|
|
105
|
+
_initialCwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry, getMemory?: () => MemoryRuntimeContext | undefined, settings?: Settings | undefined, localProtocolOptions?: LocalProtocolOptions | undefined, getAsyncJobSnapshot?: () => AsyncJobSnapshot | null);
|
|
106
|
+
/**
|
|
107
|
+
* Live session directory, not a session-start snapshot: `/move`
|
|
108
|
+
* (`SessionManager.moveTo()`) relocates the owning session by updating
|
|
109
|
+
* `sessionManager`'s own `#cwd`, not a process-global. Reading it here
|
|
110
|
+
* via the getter — instead of caching the constructor-time value in a
|
|
111
|
+
* field — keeps every `ExtensionContext` built below in sync with this
|
|
112
|
+
* session's actual, current directory. Deliberately `sessionManager.getCwd()`
|
|
113
|
+
* rather than `getProjectDir()`: the latter is a single process-wide value
|
|
114
|
+
* that only the interactive TUI's `/move` handler happens to also update
|
|
115
|
+
* (`InteractiveModeContext#applyCwdChange`) — an SDK/ACP host running
|
|
116
|
+
* several concurrent sessions each with their own `cwd` (see
|
|
117
|
+
* `CreateAgentSessionOptions.cwd`) must never have one session's move
|
|
118
|
+
* leak into another's `ctx.cwd` by reading a shared global.
|
|
119
|
+
*/
|
|
120
|
+
get cwd(): string;
|
|
78
121
|
initialize(actions: ExtensionActions, contextActions: ExtensionContextActions, commandContextActions?: ExtensionCommandContextActions, uiContext?: ExtensionUIContext): void;
|
|
79
122
|
/**
|
|
80
123
|
* Forward a `credential_disabled` event from `AuthStorage` to extension handlers.
|
|
@@ -137,8 +180,24 @@ export declare class ExtensionRunner {
|
|
|
137
180
|
path: string;
|
|
138
181
|
}>;
|
|
139
182
|
getCommand(name: string): RegisteredCommand | undefined;
|
|
140
|
-
/**
|
|
141
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Creates an extension context, optionally scoped to a provider request model.
|
|
185
|
+
*
|
|
186
|
+
* `delegation` wires the same-tool `ctx.invokeTool` for a re-registered built-in: when `toolName`
|
|
187
|
+
* names an existing native built-in, the context carries an `invokeTool` that runs it (see
|
|
188
|
+
* {@link invokeNativeTool}). The rest inherits the wrapper's own call so a bare
|
|
189
|
+
* `ctx.invokeTool(params)` behaves like the outer call — `context` preserves `toolCall`/provider
|
|
190
|
+
* metadata, `signal`/`onUpdate` default to the wrapper's own channels so aborting the outer tool
|
|
191
|
+
* call stops the native one and native progress still streams, and `depth` bounds recursion per
|
|
192
|
+
* call chain. Explicit options passed to `invokeTool` override the inherited `signal`/`onUpdate`.
|
|
193
|
+
*/
|
|
194
|
+
createContext(model?: Model, delegation?: {
|
|
195
|
+
toolName: string;
|
|
196
|
+
depth?: number;
|
|
197
|
+
context?: AgentToolContext;
|
|
198
|
+
signal?: AbortSignal;
|
|
199
|
+
onUpdate?: AgentToolUpdateCallback;
|
|
200
|
+
}): ExtensionContext;
|
|
142
201
|
/**
|
|
143
202
|
* Request a graceful shutdown. Called by extension tools and event handlers.
|
|
144
203
|
*/
|
|
@@ -325,6 +325,21 @@ export interface ExtensionContext {
|
|
|
325
325
|
setTimeout(callback: (...args: unknown[]) => void, ms?: number, ...args: unknown[]): Timer;
|
|
326
326
|
/** Clear a timer scheduled via {@link setInterval} or {@link setTimeout}. */
|
|
327
327
|
clearTimer(timer: Timer): void;
|
|
328
|
+
/**
|
|
329
|
+
* Run the NATIVE built-in implementation of the tool this handler re-registered, with `params`,
|
|
330
|
+
* and return its result. Lets a tool that re-registers a built-in (e.g. wrapping `write` to add
|
|
331
|
+
* logging or a policy check) delegate to the original instead of reimplementing it — the native
|
|
332
|
+
* tool performs its own side effects and internal bookkeeping.
|
|
333
|
+
*
|
|
334
|
+
* Delegation is same-tool only: it invokes the built-in of the SAME name as the registering tool,
|
|
335
|
+
* never an arbitrary target, so it cannot escalate past the approval already granted for this
|
|
336
|
+
* call. Present only when a native built-in of that name exists (undefined otherwise, e.g. for a
|
|
337
|
+
* net-new tool that shadows no built-in). Recursion is depth-guarded per call chain.
|
|
338
|
+
*/
|
|
339
|
+
invokeTool?<TDetails = unknown>(params: Record<string, unknown>, options?: {
|
|
340
|
+
signal?: AbortSignal;
|
|
341
|
+
onUpdate?: AgentToolUpdateCallback<TDetails>;
|
|
342
|
+
}): Promise<AgentToolResult<TDetails>>;
|
|
328
343
|
}
|
|
329
344
|
/**
|
|
330
345
|
* Extended context for command handlers.
|
|
@@ -20,7 +20,7 @@ export declare class RegisteredToolAdapter implements AgentTool<any, any, any> {
|
|
|
20
20
|
renderResult?: (result: any, options: any, theme: any, args?: any) => any;
|
|
21
21
|
readonly loadMode: ToolLoadMode;
|
|
22
22
|
constructor(registeredTool: RegisteredTool, runner: ExtensionRunner);
|
|
23
|
-
execute(toolCallId: string, params: any, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<any>,
|
|
23
|
+
execute(toolCallId: string, params: any, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<any>, context?: AgentToolContext): Promise<AgentToolResult<unknown, unknown>>;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Backward-compatible factory function wrapper.
|
|
@@ -398,7 +398,7 @@ export { getProjectDir } from "@oh-my-pi/pi-utils";
|
|
|
398
398
|
* canonical helper.
|
|
399
399
|
*/
|
|
400
400
|
export declare function getPackageDir(): string;
|
|
401
|
-
export { estimateTokens } from "@oh-my-pi/pi-agent-core/compaction";
|
|
401
|
+
export { compact, estimateTokens } from "@oh-my-pi/pi-agent-core/compaction";
|
|
402
402
|
export { CONFIG_DIR_NAME } from "@oh-my-pi/pi-utils";
|
|
403
403
|
export { parseArgs } from "../cli/args.js";
|
|
404
404
|
export * from "../index.js";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type Component } from "@oh-my-pi/pi-tui";
|
|
1
|
+
import { type Component, type KeyId } from "@oh-my-pi/pi-tui";
|
|
2
2
|
/** Distinct states of a realtime call connection. */
|
|
3
3
|
export type LivePhase = "connecting" | "listening" | "working" | "speaking" | "muted" | "error";
|
|
4
4
|
/** Configuration callbacks for user interactions in the visualizer. */
|
|
5
5
|
export interface LiveVisualizerOptions {
|
|
6
6
|
onStop(): void;
|
|
7
7
|
onToggleMute(): void;
|
|
8
|
+
/** Configured `app.live.toggle` chords that also end the call (Ctrl+L by default). */
|
|
9
|
+
stopKeys?: readonly KeyId[];
|
|
8
10
|
}
|
|
9
11
|
/** A compact, fixed-height terminal component for displaying a realtime call. */
|
|
10
12
|
export declare class LiveVisualizer implements Component {
|
|
@@ -23,9 +23,9 @@ type CreateAcpSession = (cwd: string) => Promise<AgentSession>;
|
|
|
23
23
|
* symmetric with every other `sessionUpdate` call in this file
|
|
24
24
|
* (`record.session.sessionId` is always evaluated at emit time).
|
|
25
25
|
*
|
|
26
|
-
* The non-elicitation surface (custom components,
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* The non-elicitation surface (custom components, theming, terminal
|
|
27
|
+
* input) remains stubbed — ACP clients render those themselves or not
|
|
28
|
+
* at all. Capability gating respects the client's `initialize`
|
|
29
29
|
* advertisement.
|
|
30
30
|
*/
|
|
31
31
|
export declare function createAcpExtensionUiContext(connection: AgentSideConnection, getSessionId: () => string, clientCapabilities: ClientCapabilities | undefined): ExtensionUIContext;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Utilities for formatting keybinding hints in the UI.
|
|
3
3
|
*/
|
|
4
4
|
import { type Keybinding } from "@oh-my-pi/pi-tui";
|
|
5
|
-
import type
|
|
5
|
+
import { type AppKeybinding, type KeybindingsManager } from "../../config/keybindings.js";
|
|
6
6
|
/**
|
|
7
7
|
* Get display string for an editor action.
|
|
8
8
|
*/
|
|
@@ -69,4 +69,17 @@ export declare class MCPCommandController {
|
|
|
69
69
|
handle(text: string): Promise<void>;
|
|
70
70
|
/** Reauthorize a server after a tool-level OAuth challenge. */
|
|
71
71
|
handleMCPAuthChallenge(name: string, challenge: MCPAuthChallenge): Promise<MCPServerConfig | undefined>;
|
|
72
|
+
/**
|
|
73
|
+
* Reconnect every configured MCP server and rebind the session's MCP tools.
|
|
74
|
+
*
|
|
75
|
+
* Disconnects all live connections, rediscovers `.mcp.json` configs, and
|
|
76
|
+
* calls `session.refreshMCPTools(...)` so config edits take effect without a
|
|
77
|
+
* restart. Public because `/reload-plugins` reuses it alongside `/mcp reload`
|
|
78
|
+
* and the config-mutation flows in this controller.
|
|
79
|
+
*
|
|
80
|
+
* Discovery options are derived from settings so the reload honors the same
|
|
81
|
+
* opt-outs as startup — notably `mcp.enableProjectConfig: false`, which must
|
|
82
|
+
* keep project `.mcp.json` servers from being started on reload.
|
|
83
|
+
*/
|
|
84
|
+
reloadServers(): Promise<void>;
|
|
72
85
|
}
|
|
@@ -382,6 +382,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
382
382
|
handleCtrlC(): void;
|
|
383
383
|
handleCtrlD(): void;
|
|
384
384
|
handleCtrlZ(): void;
|
|
385
|
+
resetDisplayAfterAppearanceRefresh(): void;
|
|
385
386
|
handleDequeue(): void;
|
|
386
387
|
handleImagePaste(): Promise<boolean>;
|
|
387
388
|
/** Queue slash-command input behind the active turn. */
|
|
@@ -292,7 +292,7 @@ export declare function setAutoThemeMapping(mode: "dark" | "light", themeName: s
|
|
|
292
292
|
* The terminal layer queries OSC 11 (background color) and computes luminance;
|
|
293
293
|
* Mode 2031 notifications trigger re-queries rather than providing the value directly.
|
|
294
294
|
*/
|
|
295
|
-
export declare function onTerminalAppearanceChange(mode: "dark" | "light"): void;
|
|
295
|
+
export declare function onTerminalAppearanceChange(mode: "dark" | "light", event?: ThemeChangeEvent): void;
|
|
296
296
|
export declare function setThemeInstance(themeInstance: Theme): void;
|
|
297
297
|
/**
|
|
298
298
|
* Set the symbol preset override, recreating the theme with the new preset.
|
|
@@ -375,6 +375,8 @@ export interface InteractiveModeContext {
|
|
|
375
375
|
handleCtrlC(): void;
|
|
376
376
|
handleCtrlD(): void;
|
|
377
377
|
handleCtrlZ(): void;
|
|
378
|
+
/** Re-query terminal appearance for an explicit display reset, then immediately replay the display. */
|
|
379
|
+
resetDisplayAfterAppearanceRefresh(): void;
|
|
378
380
|
handleDequeue(): void;
|
|
379
381
|
handleImagePaste(): Promise<boolean>;
|
|
380
382
|
/** Queue a message for delivery only after the active agent turn would stop. */
|
|
@@ -12,6 +12,14 @@ import { type SecretEntry } from "./obfuscator.js";
|
|
|
12
12
|
export declare function getSecretPlaceholderKey(keyDir?: string): Promise<string>;
|
|
13
13
|
/** Return an existing placeholder key for redaction without creating a new key file. */
|
|
14
14
|
export declare function getExistingSecretPlaceholderKey(keyDir?: string): Promise<string | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Synchronous variant of `getSecretPlaceholderKey` for the lazy key provider
|
|
17
|
+
* `SecretObfuscator` invokes inside its synchronous `obfuscate()` path when a
|
|
18
|
+
* built-in credential-pattern entry first matches session content. Never
|
|
19
|
+
* throws: an unreadable or unwritable key file degrades to a process-ephemeral
|
|
20
|
+
* key (with a warning) instead of breaking the session.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getSecretPlaceholderKeySync(keyDir?: string): string;
|
|
15
23
|
export { deobfuscateSessionContext, deobfuscateToolArguments, obfuscateMessages, obfuscateProviderContext, type SecretEntry, SecretObfuscator, secretEntriesNeedPlaceholderKey, secretEntryNeedsPlaceholderKey, } from "./obfuscator.js";
|
|
16
24
|
/**
|
|
17
25
|
* Load secrets from project-local and global secrets.yml files.
|
|
@@ -20,3 +28,17 @@ export { deobfuscateSessionContext, deobfuscateToolArguments, obfuscateMessages,
|
|
|
20
28
|
export declare function loadSecrets(cwd: string, agentDir: string): Promise<SecretEntry[]>;
|
|
21
29
|
/** Collect environment variable values that look like secrets. */
|
|
22
30
|
export declare function collectEnvSecrets(): SecretEntry[];
|
|
31
|
+
/**
|
|
32
|
+
* Built-in entries covering credential-shaped tokens (GitHub/GitLab/OpenAI-style
|
|
33
|
+
* API keys) that are NOT configured via secrets.yml or the environment. Without
|
|
34
|
+
* these, such a token in a tool result falls through to pi-ai's irreversible
|
|
35
|
+
* provider-boundary redaction (`[openai_token_redacted]`); the model then echoes
|
|
36
|
+
* that placeholder into edit-tool `old_text`, which can never match the real
|
|
37
|
+
* bytes on disk (issue #6968). Routing the same shapes through the obfuscator
|
|
38
|
+
* mints reversible keyed placeholders that `deobfuscateToolArguments` restores
|
|
39
|
+
* before tool execution, keeping exact-match edits working while the credential
|
|
40
|
+
* bytes still never reach the provider. Unlike the pi-ai redaction there is no
|
|
41
|
+
* entropy gate here — a false positive only over-obfuscates, which stays
|
|
42
|
+
* transparent because the round trip is lossless.
|
|
43
|
+
*/
|
|
44
|
+
export declare function builtinCredentialSecretEntries(): SecretEntry[];
|
|
@@ -86,7 +86,7 @@ export declare function secretEntriesNeedPlaceholderKey(entries: SecretEntry[]):
|
|
|
86
86
|
export declare function stripPendingSecretPlaceholderSuffix(text: string): string;
|
|
87
87
|
export declare class SecretObfuscator {
|
|
88
88
|
#private;
|
|
89
|
-
constructor(entries: SecretEntry[], key?: string);
|
|
89
|
+
constructor(entries: SecretEntry[], key?: string | (() => string));
|
|
90
90
|
hasSecrets(): boolean;
|
|
91
91
|
/** Obfuscate all secrets in text. Bidirectional placeholders for obfuscate mode, one-way for replace. */
|
|
92
92
|
obfuscate(text: string, sharedRegexSecretValues?: ReadonlySet<string>): string;
|
|
@@ -17,6 +17,7 @@ import type { FileSlashCommand } from "../extensibility/slash-commands.js";
|
|
|
17
17
|
import type { SecretObfuscator } from "../secrets/obfuscator.js";
|
|
18
18
|
import type { ConfiguredThinkingLevel } from "../thinking.js";
|
|
19
19
|
import type { XdevState } from "../tools/xdev.js";
|
|
20
|
+
import type { CodexAutoRedeemCoordinator } from "./codex-auto-reset.js";
|
|
20
21
|
import type { SessionManager } from "./session-manager.js";
|
|
21
22
|
/** Maximum time the interactive shutdown path waits for Mnemopi consolidation. */
|
|
22
23
|
export declare const SHUTDOWN_CONSOLIDATE_BUDGET_MS = 1500;
|
|
@@ -148,6 +149,8 @@ export interface AgentSessionConfig {
|
|
|
148
149
|
initialAdvisorCosts?: ReadonlyMap<string, number>;
|
|
149
150
|
/** Prefer websocket transport for OpenAI Codex requests when supported. */
|
|
150
151
|
preferWebsockets?: boolean;
|
|
152
|
+
/** Codex saved-reset coordinator; defaults to the process-wide singleton so concurrent sessions can't double-spend. Inject a fresh one in tests. */
|
|
153
|
+
codexResetCoordinator?: CodexAutoRedeemCoordinator;
|
|
151
154
|
/** Provider payload hook used by the active session request path. */
|
|
152
155
|
onPayload?: SimpleStreamOptions["onPayload"];
|
|
153
156
|
/** Provider response hook used by the active session request path. */
|
|
@@ -161,6 +164,7 @@ export interface AgentSessionConfig {
|
|
|
161
164
|
/** System prompt builder that can consider tool availability. */
|
|
162
165
|
rebuildSystemPrompt?: (toolNames: string[], tools: Map<string, AgentTool>) => Promise<{
|
|
163
166
|
systemPrompt: string[];
|
|
167
|
+
xdevCatalogNames?: readonly string[];
|
|
164
168
|
}>;
|
|
165
169
|
/** Local calendar date provider used by prompt-cache invalidation. */
|
|
166
170
|
getLocalCalendarDate?: () => string;
|
|
@@ -540,6 +540,13 @@ export declare class AgentSession {
|
|
|
540
540
|
get skillWarnings(): readonly SkillWarning[];
|
|
541
541
|
getTodoPhases(): TodoPhase[];
|
|
542
542
|
setTodoPhases(phases: TodoPhase[]): void;
|
|
543
|
+
/**
|
|
544
|
+
* Start automatic title generation when the session and input are eligible.
|
|
545
|
+
* Interactive and CLI-bootstrap submissions share this gate so every first
|
|
546
|
+
* user message persists titles with the same environment, signal, and local
|
|
547
|
+
* extension-command policy.
|
|
548
|
+
*/
|
|
549
|
+
maybeStartTitleGeneration(firstMessage: string, onStart?: () => void): void;
|
|
543
550
|
/**
|
|
544
551
|
* Generate an automatic session title tied to this session's lifecycle.
|
|
545
552
|
* Input and replan callers share the signal so disposal cancels provider and
|
|
@@ -744,6 +751,8 @@ export declare class AgentSession {
|
|
|
744
751
|
deliverIrcMessage(msg: IrcMessage, opts?: {
|
|
745
752
|
expectsReply?: boolean;
|
|
746
753
|
}): Promise<"injected" | "woken">;
|
|
754
|
+
/** Installs task-executor monitoring around autonomous IRC wake turns. */
|
|
755
|
+
setIrcWakeTurnObserver(observer: ((records: CustomMessage[]) => ((error?: unknown) => void | Promise<void>) | undefined) | undefined): void;
|
|
747
756
|
/** Emits an IRC relay observation for UI rendering without persisting it. */
|
|
748
757
|
emitIrcRelayObservation(record: CustomMessage): void;
|
|
749
758
|
/**
|