@oh-my-pi/pi-coding-agent 15.10.11 → 15.10.12
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 +44 -0
- package/dist/cli.js +5349 -5328
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli-commands.d.ts +12 -0
- package/dist/types/commands/launch.d.ts +4 -0
- package/dist/types/config/api-key-resolver.d.ts +3 -0
- package/dist/types/config/model-registry.d.ts +1 -0
- package/dist/types/config/model-resolver.d.ts +18 -0
- package/dist/types/config/settings-schema.d.ts +29 -1
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
- package/dist/types/eval/py/executor.d.ts +5 -0
- package/dist/types/eval/py/kernel.d.ts +6 -1
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -2
- package/dist/types/extensibility/extensions/types.d.ts +3 -0
- package/dist/types/memory-backend/index.d.ts +1 -0
- package/dist/types/memory-backend/runtime.d.ts +4 -0
- package/dist/types/memory-backend/types.d.ts +66 -1
- package/dist/types/modes/index.d.ts +3 -3
- package/dist/types/modes/interactive-mode.d.ts +7 -2
- package/dist/types/modes/oauth-manual-input.d.ts +7 -0
- package/dist/types/modes/rpc/rpc-client.d.ts +39 -2
- package/dist/types/modes/rpc/rpc-mode.d.ts +31 -2
- package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +75 -1
- package/dist/types/modes/setup-wizard/index.d.ts +5 -1
- package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/secrets/index.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +8 -2
- package/dist/types/session/agent-session.d.ts +14 -2
- package/dist/types/session/streaming-output.d.ts +23 -0
- package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -0
- package/dist/types/slash-commands/types.d.ts +1 -1
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +1 -0
- package/dist/types/task/index.d.ts +2 -2
- package/dist/types/task/types.d.ts +8 -0
- package/dist/types/thinking.d.ts +4 -0
- package/dist/types/tiny/title-client.d.ts +11 -0
- package/dist/types/tiny/title-protocol.d.ts +1 -0
- package/dist/types/tools/index.d.ts +6 -0
- package/dist/types/utils/git.d.ts +15 -2
- package/dist/types/utils/title-generator.d.ts +3 -2
- package/package.json +10 -10
- package/src/auto-thinking/classifier.ts +1 -0
- package/src/cli/args.ts +3 -0
- package/src/cli-commands.ts +29 -0
- package/src/cli.ts +8 -9
- package/src/commands/launch.ts +4 -0
- package/src/commit/model-selection.ts +3 -2
- package/src/config/api-key-resolver.ts +8 -6
- package/src/config/model-registry.ts +97 -30
- package/src/config/model-resolver.ts +60 -0
- package/src/config/settings-schema.ts +43 -15
- package/src/config/settings.ts +61 -3
- package/src/edit/hashline/execute.ts +39 -2
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/eval/completion-bridge.ts +1 -0
- package/src/eval/py/executor.ts +29 -7
- package/src/eval/py/index.ts +6 -1
- package/src/eval/py/kernel.ts +31 -11
- package/src/eval/py/runtime.ts +37 -0
- package/src/exec/bash-executor.ts +82 -3
- package/src/extensibility/extensions/get-commands-handler.ts +2 -1
- package/src/extensibility/extensions/runner.ts +6 -1
- package/src/extensibility/extensions/types.ts +3 -0
- package/src/hindsight/bank.ts +17 -2
- package/src/internal-urls/docs-index.generated.ts +3 -3
- package/src/main.ts +18 -6
- package/src/memories/index.ts +2 -0
- package/src/memory-backend/index.ts +1 -0
- package/src/memory-backend/local-backend.ts +9 -0
- package/src/memory-backend/off-backend.ts +9 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/types.ts +81 -1
- package/src/mnemopi/backend.ts +151 -4
- package/src/modes/acp/acp-agent.ts +119 -11
- package/src/modes/components/assistant-message.ts +19 -21
- package/src/modes/components/footer.ts +3 -1
- package/src/modes/components/status-line/component.ts +118 -34
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +1 -0
- package/src/modes/controllers/mcp-command-controller.ts +38 -3
- package/src/modes/index.ts +3 -21
- package/src/modes/interactive-mode.ts +39 -9
- package/src/modes/oauth-manual-input.ts +30 -3
- package/src/modes/rpc/rpc-client.ts +154 -3
- package/src/modes/rpc/rpc-mode.ts +97 -12
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +81 -1
- package/src/modes/setup-wizard/index.ts +12 -2
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/types.ts +2 -0
- package/src/sdk.ts +8 -1
- package/src/secrets/index.ts +8 -1
- package/src/secrets/obfuscator.ts +39 -18
- package/src/session/agent-session.ts +179 -54
- package/src/session/streaming-output.ts +166 -10
- package/src/slash-commands/acp-builtins.ts +24 -0
- package/src/slash-commands/builtin-registry.ts +20 -0
- package/src/slash-commands/types.ts +1 -1
- package/src/system-prompt.ts +14 -0
- package/src/task/executor.ts +13 -12
- package/src/task/index.ts +9 -8
- package/src/task/render.ts +18 -3
- package/src/task/types.ts +9 -0
- package/src/thinking.ts +7 -0
- package/src/tiny/title-client.ts +34 -5
- package/src/tiny/title-protocol.ts +1 -1
- package/src/tiny/worker.ts +6 -4
- package/src/tools/bash.ts +46 -5
- package/src/tools/image-gen.ts +11 -4
- package/src/tools/index.ts +13 -1
- package/src/tools/inspect-image.ts +1 -0
- package/src/utils/commit-message-generator.ts +1 -0
- package/src/utils/git.ts +267 -13
- package/src/utils/title-generator.ts +24 -5
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type SubagentEventPayload, type SubagentLifecyclePayload, type SubagentProgressPayload } from "../../task";
|
|
2
|
+
import type { EventBus } from "../../utils/event-bus";
|
|
3
|
+
import type { RpcSubagentFrame, RpcSubagentMessagesResult, RpcSubagentSnapshot, RpcSubagentSubscriptionLevel } from "./rpc-types";
|
|
4
|
+
export interface RpcSubagentTranscriptSelector {
|
|
5
|
+
subagentId?: string;
|
|
6
|
+
sessionFile?: string;
|
|
7
|
+
fromByte?: number;
|
|
8
|
+
}
|
|
9
|
+
type RpcSubagentOutput = (frame: RpcSubagentFrame) => void;
|
|
10
|
+
export declare function readRpcSubagentTranscript(sessionFile: string, fromByte?: number): Promise<RpcSubagentMessagesResult>;
|
|
11
|
+
export declare class RpcSubagentRegistry {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(eventBus: EventBus, output: RpcSubagentOutput);
|
|
14
|
+
dispose(): void;
|
|
15
|
+
clear(): void;
|
|
16
|
+
setSubscriptionLevel(level: RpcSubagentSubscriptionLevel): void;
|
|
17
|
+
getSubscriptionLevel(): RpcSubagentSubscriptionLevel;
|
|
18
|
+
getSubagents(): RpcSubagentSnapshot[];
|
|
19
|
+
handleLifecycle(payload: SubagentLifecyclePayload): void;
|
|
20
|
+
handleProgress(payload: SubagentProgressPayload): void;
|
|
21
|
+
handleEvent(payload: SubagentEventPayload): void;
|
|
22
|
+
resolveSessionFile(selector: RpcSubagentTranscriptSelector): string;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -9,7 +9,9 @@ import type { CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
|
9
9
|
import type { Effort, ImageContent, Model } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import type { BashResult } from "../../exec/bash-executor";
|
|
11
11
|
import type { ContextUsage } from "../../extensibility/extensions/types";
|
|
12
|
-
import type { SessionStats } from "../../session/agent-session";
|
|
12
|
+
import type { AgentSessionEvent, SessionStats } from "../../session/agent-session";
|
|
13
|
+
import type { FileEntry } from "../../session/session-manager";
|
|
14
|
+
import type { AgentProgress, SubagentEventPayload, SubagentLifecyclePayload, SubagentProgressPayload } from "../../task";
|
|
13
15
|
import type { TodoPhase } from "../../tools/todo";
|
|
14
16
|
export type RpcCommand = {
|
|
15
17
|
id?: string;
|
|
@@ -54,6 +56,19 @@ export type RpcCommand = {
|
|
|
54
56
|
id?: string;
|
|
55
57
|
type: "set_host_uri_schemes";
|
|
56
58
|
schemes: RpcHostUriSchemeDefinition[];
|
|
59
|
+
} | {
|
|
60
|
+
id?: string;
|
|
61
|
+
type: "set_subagent_subscription";
|
|
62
|
+
level: RpcSubagentSubscriptionLevel;
|
|
63
|
+
} | {
|
|
64
|
+
id?: string;
|
|
65
|
+
type: "get_subagents";
|
|
66
|
+
} | {
|
|
67
|
+
id?: string;
|
|
68
|
+
type: "get_subagent_messages";
|
|
69
|
+
subagentId?: string;
|
|
70
|
+
sessionFile?: string;
|
|
71
|
+
fromByte?: number;
|
|
57
72
|
} | {
|
|
58
73
|
id?: string;
|
|
59
74
|
type: "set_model";
|
|
@@ -174,6 +189,29 @@ export interface RpcSessionState {
|
|
|
174
189
|
export interface RpcHandoffResult {
|
|
175
190
|
savedPath?: string;
|
|
176
191
|
}
|
|
192
|
+
export type RpcSubagentSubscriptionLevel = "off" | "progress" | "events";
|
|
193
|
+
export interface RpcSubagentSnapshot {
|
|
194
|
+
id: string;
|
|
195
|
+
index: number;
|
|
196
|
+
agent: string;
|
|
197
|
+
agentSource: AgentProgress["agentSource"];
|
|
198
|
+
description?: string;
|
|
199
|
+
status: AgentProgress["status"];
|
|
200
|
+
task?: string;
|
|
201
|
+
assignment?: string;
|
|
202
|
+
sessionFile?: string;
|
|
203
|
+
lastUpdate: number;
|
|
204
|
+
progress?: AgentProgress;
|
|
205
|
+
parentToolCallId?: string;
|
|
206
|
+
}
|
|
207
|
+
export interface RpcSubagentMessagesResult {
|
|
208
|
+
sessionFile: string;
|
|
209
|
+
fromByte: number;
|
|
210
|
+
nextByte: number;
|
|
211
|
+
reset: boolean;
|
|
212
|
+
entries: FileEntry[];
|
|
213
|
+
messages: AgentMessage[];
|
|
214
|
+
}
|
|
177
215
|
export type RpcResponse = {
|
|
178
216
|
id?: string;
|
|
179
217
|
type: "response";
|
|
@@ -237,6 +275,28 @@ export type RpcResponse = {
|
|
|
237
275
|
data: {
|
|
238
276
|
schemes: string[];
|
|
239
277
|
};
|
|
278
|
+
} | {
|
|
279
|
+
id?: string;
|
|
280
|
+
type: "response";
|
|
281
|
+
command: "set_subagent_subscription";
|
|
282
|
+
success: true;
|
|
283
|
+
data: {
|
|
284
|
+
level: RpcSubagentSubscriptionLevel;
|
|
285
|
+
};
|
|
286
|
+
} | {
|
|
287
|
+
id?: string;
|
|
288
|
+
type: "response";
|
|
289
|
+
command: "get_subagents";
|
|
290
|
+
success: true;
|
|
291
|
+
data: {
|
|
292
|
+
subagents: RpcSubagentSnapshot[];
|
|
293
|
+
};
|
|
294
|
+
} | {
|
|
295
|
+
id?: string;
|
|
296
|
+
type: "response";
|
|
297
|
+
command: "get_subagent_messages";
|
|
298
|
+
success: true;
|
|
299
|
+
data: RpcSubagentMessagesResult;
|
|
240
300
|
} | {
|
|
241
301
|
id?: string;
|
|
242
302
|
type: "response";
|
|
@@ -418,6 +478,20 @@ export type RpcResponse = {
|
|
|
418
478
|
success: false;
|
|
419
479
|
error: string;
|
|
420
480
|
};
|
|
481
|
+
export interface RpcSubagentLifecycleFrame {
|
|
482
|
+
type: "subagent_lifecycle";
|
|
483
|
+
payload: SubagentLifecyclePayload;
|
|
484
|
+
}
|
|
485
|
+
export interface RpcSubagentProgressFrame {
|
|
486
|
+
type: "subagent_progress";
|
|
487
|
+
payload: SubagentProgressPayload;
|
|
488
|
+
}
|
|
489
|
+
export interface RpcSubagentEventFrame {
|
|
490
|
+
type: "subagent_event";
|
|
491
|
+
payload: SubagentEventPayload;
|
|
492
|
+
}
|
|
493
|
+
export type RpcSubagentFrame = RpcSubagentLifecycleFrame | RpcSubagentProgressFrame | RpcSubagentEventFrame;
|
|
494
|
+
export type RpcSessionEventFrame = AgentSessionEvent | RpcSubagentFrame;
|
|
421
495
|
/** Emitted when an extension needs user input */
|
|
422
496
|
export type RpcExtensionUIRequest = {
|
|
423
497
|
type: "extension_ui_request";
|
|
@@ -14,4 +14,8 @@ export interface SetupSceneSelectionOptions {
|
|
|
14
14
|
}
|
|
15
15
|
export declare function selectSetupScenes(storedVersion: number, scenes: readonly SetupScene[], ctx?: InteractiveModeContext, options?: SetupSceneSelectionOptions): Promise<SetupScene[]>;
|
|
16
16
|
export declare function markSetupWizardComplete(settings: Settings, version?: number): Promise<void>;
|
|
17
|
-
export
|
|
17
|
+
export interface RunSetupWizardOptions {
|
|
18
|
+
markComplete?: boolean;
|
|
19
|
+
playWelcomeIntro?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function runSetupWizard(ctx: InteractiveModeContext, scenes?: readonly SetupScene[], options?: RunSetupWizardOptions): Promise<void>;
|
|
@@ -82,6 +82,7 @@ export interface InteractiveModeContext {
|
|
|
82
82
|
historyStorage?: HistoryStorage;
|
|
83
83
|
mcpManager?: MCPManager;
|
|
84
84
|
lspServers?: LspStartupServerInfo[];
|
|
85
|
+
titleSystemPrompt?: string;
|
|
85
86
|
isInitialized: boolean;
|
|
86
87
|
isBashMode: boolean;
|
|
87
88
|
toolOutputExpanded: boolean;
|
|
@@ -262,6 +263,7 @@ export interface InteractiveModeContext {
|
|
|
262
263
|
handleResumeSession(sessionPath: string): Promise<void>;
|
|
263
264
|
handleSessionDeleteCommand(): Promise<void>;
|
|
264
265
|
showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
|
|
266
|
+
showProviderSetup(): Promise<void>;
|
|
265
267
|
showHookConfirm(title: string, message: string): Promise<boolean>;
|
|
266
268
|
showDebugSelector(): Promise<void>;
|
|
267
269
|
showSessionObserver(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SecretEntry } from "./obfuscator";
|
|
2
|
-
export { deobfuscateSessionContext, obfuscateMessages, type SecretEntry, SecretObfuscator } from "./obfuscator";
|
|
2
|
+
export { deobfuscateSessionContext, obfuscateMessages, obfuscateProviderContext, obfuscateProviderTools, type SecretEntry, SecretObfuscator, } from "./obfuscator";
|
|
3
3
|
/**
|
|
4
4
|
* Load secrets from project-local and global secrets.yml files.
|
|
5
5
|
* Project-local entries override global entries with matching content.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Message } from "@oh-my-pi/pi-ai";
|
|
1
|
+
import type { Context, Message, Tool } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { SessionContext } from "../session/session-manager";
|
|
3
3
|
export interface SecretEntry {
|
|
4
4
|
type: "plain" | "regex";
|
|
@@ -17,7 +17,13 @@ export declare class SecretObfuscator {
|
|
|
17
17
|
deobfuscate(text: string): string;
|
|
18
18
|
/** Deep-walk an object, deobfuscating all string values. */
|
|
19
19
|
deobfuscateObject<T>(obj: T): T;
|
|
20
|
+
/** Deep-walk an object, obfuscating all string values. */
|
|
21
|
+
obfuscateObject<T>(obj: T): T;
|
|
20
22
|
}
|
|
21
23
|
export declare function deobfuscateSessionContext(sessionContext: SessionContext, obfuscator: SecretObfuscator | undefined): SessionContext;
|
|
22
|
-
/** Obfuscate all
|
|
24
|
+
/** Obfuscate all string content in LLM messages (for outbound interception). */
|
|
23
25
|
export declare function obfuscateMessages(obfuscator: SecretObfuscator, messages: Message[]): Message[];
|
|
26
|
+
/** Obfuscate provider request context without walking live tool schema instances. */
|
|
27
|
+
export declare function obfuscateProviderContext(obfuscator: SecretObfuscator | undefined, context: Context): Context;
|
|
28
|
+
/** Convert tool schemas to wire JSON Schema before obfuscating provider-visible strings. */
|
|
29
|
+
export declare function obfuscateProviderTools(obfuscator: SecretObfuscator | undefined, tools: Tool[] | undefined): Tool[] | undefined;
|
|
@@ -127,6 +127,8 @@ export interface AgentSessionConfig {
|
|
|
127
127
|
agent: Agent;
|
|
128
128
|
sessionManager: SessionManager;
|
|
129
129
|
settings: Settings;
|
|
130
|
+
/** Whether the caller explicitly requested yolo/auto-approve behavior for this session. */
|
|
131
|
+
autoApprove?: boolean;
|
|
130
132
|
/** Models to cycle through with Ctrl+P (from --models flag) */
|
|
131
133
|
scopedModels?: Array<{
|
|
132
134
|
model: Model;
|
|
@@ -548,7 +550,14 @@ export declare class AgentSession {
|
|
|
548
550
|
* @throws Error if streaming and no streamingBehavior specified
|
|
549
551
|
* @throws Error if no model selected or no API key available (when not streaming)
|
|
550
552
|
*/
|
|
551
|
-
|
|
553
|
+
/**
|
|
554
|
+
* Returns `false` when the command was fully handled locally (extension or
|
|
555
|
+
* custom-TS command consumed without calling the LLM). Returns `true` when
|
|
556
|
+
* the prompt was forwarded to the agent — either directly or queued as a
|
|
557
|
+
* steer/follow-up. Callers that render a UI or manage turn lifecycle (e.g.
|
|
558
|
+
* the ACP agent) use this to know whether to expect an `agent_end` event.
|
|
559
|
+
*/
|
|
560
|
+
prompt(text: string, options?: PromptOptions): Promise<boolean>;
|
|
552
561
|
promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice">): Promise<void>;
|
|
553
562
|
/**
|
|
554
563
|
* Queue a steering message to interrupt the agent mid-run.
|
|
@@ -700,7 +709,8 @@ export declare class AgentSession {
|
|
|
700
709
|
*/
|
|
701
710
|
cycleRoleModels(roleOrder: readonly string[], direction?: "forward" | "backward"): Promise<RoleModelCycleResult | undefined>;
|
|
702
711
|
/**
|
|
703
|
-
* Get all available models with valid API keys.
|
|
712
|
+
* Get all available models with valid API keys, filtered by `enabledModels` when configured.
|
|
713
|
+
* See {@link filterAvailableModelsByEnabledPatterns} for supported pattern forms and limitations.
|
|
704
714
|
*/
|
|
705
715
|
getAvailableModels(): Model[];
|
|
706
716
|
/**
|
|
@@ -849,9 +859,11 @@ export declare class AgentSession {
|
|
|
849
859
|
* @param command The bash command to execute
|
|
850
860
|
* @param onChunk Optional streaming callback for output
|
|
851
861
|
* @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix)
|
|
862
|
+
* @param options.useUserShell If true, allow caller to request configured user-shell routing
|
|
852
863
|
*/
|
|
853
864
|
executeBash(command: string, onChunk?: (chunk: string) => void, options?: {
|
|
854
865
|
excludeFromContext?: boolean;
|
|
866
|
+
useUserShell?: boolean;
|
|
855
867
|
}): Promise<BashResult>;
|
|
856
868
|
/**
|
|
857
869
|
* Record a bash execution result in session history.
|
|
@@ -2,6 +2,15 @@ import type { AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
|
2
2
|
export declare const DEFAULT_MAX_LINES = 3000;
|
|
3
3
|
export declare const DEFAULT_MAX_BYTES: number;
|
|
4
4
|
export declare const DEFAULT_MAX_COLUMN = 512;
|
|
5
|
+
/**
|
|
6
|
+
* Default artifact-on-disk cap for {@link OutputSink}.
|
|
7
|
+
*
|
|
8
|
+
* `0` means unbounded: by default, `artifact://<id>` references preserve the
|
|
9
|
+
* complete raw stream instead of a capped head/tail sample.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ARTIFACT_DEFAULT_MAX_BYTES = 0;
|
|
12
|
+
/** Default head budget; the remainder becomes the rolling tail window. */
|
|
13
|
+
export declare const ARTIFACT_DEFAULT_HEAD_BYTES: number;
|
|
5
14
|
export interface OutputSummary {
|
|
6
15
|
output: string;
|
|
7
16
|
truncated: boolean;
|
|
@@ -41,6 +50,20 @@ export interface OutputSinkOptions {
|
|
|
41
50
|
onChunk?: (chunk: string) => void;
|
|
42
51
|
/** Minimum ms between onChunk calls. 0 = every chunk (default). */
|
|
43
52
|
chunkThrottleMs?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Optional cap on bytes written to the artifact-on-disk file. When the cap
|
|
55
|
+
* is hit, the head window is preserved verbatim and subsequent output feeds
|
|
56
|
+
* a rolling tail window; on close, the sink writes a single
|
|
57
|
+
* `[ARTIFACT TRUNCATED: …]` notice between them. Default
|
|
58
|
+
* {@link ARTIFACT_DEFAULT_MAX_BYTES} (unbounded).
|
|
59
|
+
*/
|
|
60
|
+
artifactMaxBytes?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Bytes reserved for the head window of the capped artifact file. The
|
|
63
|
+
* tail window receives `artifactMaxBytes - artifactHeadBytes`. Default
|
|
64
|
+
* {@link ARTIFACT_DEFAULT_HEAD_BYTES}; clamped to `[0, artifactMaxBytes]`.
|
|
65
|
+
*/
|
|
66
|
+
artifactHeadBytes?: number;
|
|
44
67
|
}
|
|
45
68
|
export interface TruncationResult {
|
|
46
69
|
content: string;
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import type { AvailableCommand } from "@agentclientprotocol/sdk";
|
|
2
2
|
import type { AcpBuiltinSlashCommandResult, SlashCommandRuntime } from "./types";
|
|
3
3
|
export type { AcpBuiltinSlashCommandResult } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* All names (primary + aliases) that are reserved by ACP builtins. Used to
|
|
6
|
+
* filter out extension commands that would shadow a builtin or its alias at
|
|
7
|
+
* dispatch time (e.g. `models` is an alias for `/model`, so an extension
|
|
8
|
+
* registering `models` would appear in the palette but execute the builtin).
|
|
9
|
+
*/
|
|
10
|
+
export declare const ACP_BUILTIN_RESERVED_NAMES: ReadonlySet<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Whether an extension command named `name` would be captured by ACP builtin
|
|
13
|
+
* dispatch before reaching the extension handler. Beyond exact name/alias
|
|
14
|
+
* collisions, `parseSlashCommand` treats `:` as a name/args separator, so a
|
|
15
|
+
* colon-namespaced name whose prefix is a handled builtin (e.g. `model:foo`)
|
|
16
|
+
* executes the `/model` builtin with `foo` as args. Such names must not be
|
|
17
|
+
* advertised to ACP clients.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isAcpBuiltinShadowedName(name: string): boolean;
|
|
4
20
|
/**
|
|
5
21
|
* Commands advertised to ACP clients. Entries without a text-mode `handle`
|
|
6
22
|
* (e.g. `/quit`, `/login`, dashboards) are filtered out so the client doesn't
|
|
@@ -2,6 +2,7 @@ import type { BuiltinSlashCommand, ParsedSlashCommand, SlashCommandResult, Slash
|
|
|
2
2
|
export type { BuiltinSlashCommand, SubcommandDef } from "./types";
|
|
3
3
|
/** TUI-specific runtime accepted by `executeBuiltinSlashCommand`. */
|
|
4
4
|
export type BuiltinSlashCommandRuntime = TuiSlashCommandRuntime;
|
|
5
|
+
export declare const BUILTIN_SLASH_COMMAND_RESERVED_NAMES: ReadonlySet<string>;
|
|
5
6
|
/** Builtin command metadata used for slash-command autocomplete and help text. */
|
|
6
7
|
export declare const BUILTIN_SLASH_COMMAND_DEFS: ReadonlyArray<BuiltinSlashCommand>;
|
|
7
8
|
/**
|
|
@@ -12,6 +12,7 @@ export interface SubcommandDef {
|
|
|
12
12
|
/** Declarative builtin slash command metadata used by autocomplete and help UI. */
|
|
13
13
|
export interface BuiltinSlashCommand {
|
|
14
14
|
name: string;
|
|
15
|
+
aliases?: string[];
|
|
15
16
|
description: string;
|
|
16
17
|
/** Subcommands for dropdown completion (e.g. /mcp add, /mcp list). */
|
|
17
18
|
subcommands?: SubcommandDef[];
|
|
@@ -79,7 +80,6 @@ export interface TuiSlashCommandRuntime {
|
|
|
79
80
|
}
|
|
80
81
|
/** Unified slash-command spec consumed by both TUI and ACP dispatchers. */
|
|
81
82
|
export interface SlashCommandSpec extends BuiltinSlashCommand {
|
|
82
|
-
aliases?: string[];
|
|
83
83
|
/** When false, the dispatcher refuses to handle invocations that include arguments. */
|
|
84
84
|
allowArgs?: boolean;
|
|
85
85
|
/**
|
|
@@ -10,6 +10,8 @@ interface AlwaysApplyRule {
|
|
|
10
10
|
content: string;
|
|
11
11
|
path: string;
|
|
12
12
|
}
|
|
13
|
+
/** Discover TITLE_SYSTEM.md file for automatic session-title prompt overrides */
|
|
14
|
+
export declare function discoverTitleSystemPromptFile(cwd?: string): string | undefined;
|
|
13
15
|
/** Resolve input as file path or literal string */
|
|
14
16
|
export declare function resolvePromptInput(input: string | undefined, description: string): Promise<string | undefined>;
|
|
15
17
|
export interface LoadContextFilesOptions {
|
|
@@ -8,7 +8,7 @@ export { loadBundledAgents as BUNDLED_AGENTS } from "./agents";
|
|
|
8
8
|
export { discoverCommands, expandCommand, getCommand } from "./commands";
|
|
9
9
|
export { discoverAgents, getAgent } from "./discovery";
|
|
10
10
|
export { AgentOutputManager } from "./output-manager";
|
|
11
|
-
export type { AgentDefinition, AgentProgress, SingleResult, SubagentLifecyclePayload, SubagentProgressPayload, TaskParams, TaskToolDetails, } from "./types";
|
|
11
|
+
export type { AgentDefinition, AgentProgress, SingleResult, SubagentEventPayload, SubagentLifecyclePayload, SubagentProgressPayload, TaskParams, TaskToolDetails, } from "./types";
|
|
12
12
|
export { TASK_SUBAGENT_EVENT_CHANNEL, TASK_SUBAGENT_LIFECYCLE_CHANNEL, TASK_SUBAGENT_PROGRESS_CHANNEL, taskSchema, } from "./types";
|
|
13
13
|
export declare const READ_ONLY_TOOL_NAMES: ReadonlySet<string>;
|
|
14
14
|
export declare function isReadOnlyAgent(agent: AgentDefinition): boolean;
|
|
@@ -39,5 +39,5 @@ export declare class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskT
|
|
|
39
39
|
* Create a TaskTool instance with async agent discovery.
|
|
40
40
|
*/
|
|
41
41
|
static create(session: ToolSession): Promise<TaskTool>;
|
|
42
|
-
execute(
|
|
42
|
+
execute(toolCallId: string, rawParams: unknown, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<TaskToolDetails>): Promise<AgentToolResult<TaskToolDetails>>;
|
|
43
43
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Usage } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
|
+
import type { AgentSessionEvent } from "../session/agent-session";
|
|
4
5
|
import { type TaskSimpleMode } from "./simple-mode";
|
|
5
6
|
import type { NestedRepoPatch } from "./worktree";
|
|
6
7
|
/** Source of an agent definition */
|
|
@@ -21,10 +22,16 @@ export interface SubagentProgressPayload {
|
|
|
21
22
|
agent: string;
|
|
22
23
|
agentSource: AgentSource;
|
|
23
24
|
task: string;
|
|
25
|
+
parentToolCallId?: string;
|
|
24
26
|
assignment?: string;
|
|
25
27
|
progress: AgentProgress;
|
|
26
28
|
sessionFile?: string;
|
|
27
29
|
}
|
|
30
|
+
/** Payload emitted on TASK_SUBAGENT_EVENT_CHANNEL */
|
|
31
|
+
export interface SubagentEventPayload {
|
|
32
|
+
id: string;
|
|
33
|
+
event: AgentSessionEvent;
|
|
34
|
+
}
|
|
28
35
|
/** Payload emitted on TASK_SUBAGENT_LIFECYCLE_CHANNEL */
|
|
29
36
|
export interface SubagentLifecyclePayload {
|
|
30
37
|
id: string;
|
|
@@ -33,6 +40,7 @@ export interface SubagentLifecyclePayload {
|
|
|
33
40
|
description?: string;
|
|
34
41
|
status: "started" | "completed" | "failed" | "aborted";
|
|
35
42
|
sessionFile?: string;
|
|
43
|
+
parentToolCallId?: string;
|
|
36
44
|
index: number;
|
|
37
45
|
}
|
|
38
46
|
/** Single task item for parallel execution (default shape with context enabled). */
|
package/dist/types/thinking.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export declare function getThinkingLevelMetadata(level: ThinkingLevel): Thinking
|
|
|
24
24
|
* Converts an agent-local selector into the effort sent to providers.
|
|
25
25
|
*/
|
|
26
26
|
export declare function toReasoningEffort(level: ThinkingLevel | undefined): Effort | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* True when a selector explicitly requests provider-side reasoning disablement.
|
|
29
|
+
*/
|
|
30
|
+
export declare function shouldDisableReasoning(level: ThinkingLevel | undefined): boolean;
|
|
27
31
|
/**
|
|
28
32
|
* Resolves a selector against the current model while preserving explicit "off".
|
|
29
33
|
*/
|
|
@@ -18,6 +18,16 @@ export interface TinyTitleDownloadOptions {
|
|
|
18
18
|
signal?: AbortSignal;
|
|
19
19
|
onProgress?: (event: TinyTitleProgressEvent) => void;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Per-request controls for {@link TinyTitleClient.generate}.
|
|
23
|
+
*
|
|
24
|
+
* Carries the optional abort signal and title-system-prompt override used by
|
|
25
|
+
* callers that customize automatic session-title generation.
|
|
26
|
+
*/
|
|
27
|
+
export interface TinyTitleGenerateOptions {
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
systemPrompt?: string;
|
|
30
|
+
}
|
|
21
31
|
/**
|
|
22
32
|
* Hidden subcommand on the main CLI that boots the tiny-model worker in the
|
|
23
33
|
* spawned subprocess. Kept in sync with the dispatch in `cli.ts`.
|
|
@@ -56,6 +66,7 @@ export declare class TinyTitleClient {
|
|
|
56
66
|
constructor(spawnWorker?: () => WorkerHandle);
|
|
57
67
|
onProgress(listener: (event: TinyTitleProgressEvent) => void): () => void;
|
|
58
68
|
generate(modelKey: string, message: string, signal?: AbortSignal): Promise<string | null>;
|
|
69
|
+
generate(modelKey: string, message: string, options?: TinyTitleGenerateOptions): Promise<string | null>;
|
|
59
70
|
complete(modelKey: string, prompt: string, options?: {
|
|
60
71
|
maxTokens?: number;
|
|
61
72
|
signal?: AbortSignal;
|
|
@@ -279,6 +279,12 @@ export interface ToolSession {
|
|
|
279
279
|
/** Per-session ledger of post-edit LSP diagnostics already surfaced to the
|
|
280
280
|
* model for each file. Lazily initialized by `getDiagnosticsLedger`. */
|
|
281
281
|
diagnosticsLedger?: import("../lsp/diagnostics-ledger").DiagnosticsLedger;
|
|
282
|
+
/** Per-session ledger of consecutive byte-identical no-op edits, keyed by
|
|
283
|
+
* canonical file path. The hashline executor escalates a soft no-op hint
|
|
284
|
+
* to a thrown error once the same payload no-ops `NOOP_HARD_LIMIT` times,
|
|
285
|
+
* breaking subagent loops that ignore the textual hint (issue #2081).
|
|
286
|
+
* Lazily initialized by `getNoopLoopGuard`. */
|
|
287
|
+
noopLoopGuard?: import("../edit/hashline/noop-loop-guard").NoopLoopGuard;
|
|
282
288
|
/** Queue a hidden message to be injected at the next agent turn. */
|
|
283
289
|
queueDeferredMessage?(message: CustomMessage): void;
|
|
284
290
|
/** Queue late LSP diagnostics (arrived after an edit/write returned) to be shown
|
|
@@ -10,6 +10,7 @@ export interface GitRepository {
|
|
|
10
10
|
gitEntryPath: string;
|
|
11
11
|
headPath: string;
|
|
12
12
|
repoRoot: string;
|
|
13
|
+
isReftable?: boolean;
|
|
13
14
|
}
|
|
14
15
|
export interface GitStatusSummary {
|
|
15
16
|
staged: number;
|
|
@@ -327,7 +328,7 @@ export declare const ls: {
|
|
|
327
328
|
};
|
|
328
329
|
export declare const head: {
|
|
329
330
|
/** Full HEAD state (branch, commit, repo info). */
|
|
330
|
-
resolve(cwd: string): Promise<GitHeadState | null>;
|
|
331
|
+
resolve(cwd: string, signal?: AbortSignal): Promise<GitHeadState | null>;
|
|
331
332
|
/** Full HEAD state (synchronous). */
|
|
332
333
|
resolveSync(cwd: string): GitHeadState | null;
|
|
333
334
|
/** Current HEAD commit SHA. */
|
|
@@ -338,12 +339,24 @@ export declare const head: {
|
|
|
338
339
|
export declare const repo: {
|
|
339
340
|
/** Resolve the repository root (may be a worktree root). */
|
|
340
341
|
root(cwd: string, signal?: AbortSignal): Promise<string | null>;
|
|
341
|
-
/** Resolve the primary
|
|
342
|
+
/** Resolve the primary checkout root, or the shared common dir for bare-repo worktrees. */
|
|
342
343
|
primaryRoot(cwd: string, signal?: AbortSignal): Promise<string | null>;
|
|
344
|
+
/**
|
|
345
|
+
* Sync sibling of {@link primaryRoot}. Resolves only via on-disk `.git`/
|
|
346
|
+
* `commondir` walking — no subprocess fallback — so it stays usable from
|
|
347
|
+
* paths where async I/O is impractical (e.g. `computeBankScope`). Returns
|
|
348
|
+
* `null` when `cwd` is outside a repository. Bare-repo worktrees resolve to
|
|
349
|
+
* the shared common dir (`foo.git`) because they have no primary checkout.
|
|
350
|
+
*/
|
|
351
|
+
primaryRootSync(cwd: string): string | null;
|
|
343
352
|
/** Full GitRepository metadata (sync). */
|
|
344
353
|
resolveSync(cwd: string): GitRepository | null;
|
|
345
354
|
/** Full GitRepository metadata. */
|
|
346
355
|
resolve(cwd: string): Promise<GitRepository | null>;
|
|
356
|
+
/** Check if the repository uses the reftable reference storage format (sync). */
|
|
357
|
+
isReftableSync(repository: GitRepository): boolean;
|
|
358
|
+
/** Check if the repository uses the reftable reference storage format. */
|
|
359
|
+
isReftable(repository: GitRepository): Promise<boolean>;
|
|
347
360
|
};
|
|
348
361
|
export interface GhCommandResult {
|
|
349
362
|
exitCode: number;
|
|
@@ -15,9 +15,10 @@ export declare function raceFirstNonNull<T>(primary: Promise<T | null>, startFal
|
|
|
15
15
|
* to produce request metadata (e.g. user_id for session attribution). Using a
|
|
16
16
|
* resolver instead of a pre-evaluated value ensures the metadata's account_uuid
|
|
17
17
|
* reflects the credential actually selected for this request.
|
|
18
|
+
* @param customSystemPrompt Optional title-specific system prompt override
|
|
18
19
|
*/
|
|
19
|
-
export declare function generateSessionTitle(firstMessage: string, registry: ModelRegistry, settings: Settings, sessionId?: string, currentModel?: Model<Api>, metadataResolver?: (provider: string) => Record<string, unknown> | undefined): Promise<string | null>;
|
|
20
|
-
export declare function generateTitleOnline(firstMessage: string, registry: ModelRegistry, settings: Settings, sessionId?: string, currentModel?: Model<Api>, metadataResolver?: (provider: string) => Record<string, unknown> | undefined, signal?: AbortSignal): Promise<string | null>;
|
|
20
|
+
export declare function generateSessionTitle(firstMessage: string, registry: ModelRegistry, settings: Settings, sessionId?: string, currentModel?: Model<Api>, metadataResolver?: (provider: string) => Record<string, unknown> | undefined, customSystemPrompt?: string): Promise<string | null>;
|
|
21
|
+
export declare function generateTitleOnline(firstMessage: string, registry: ModelRegistry, settings: Settings, sessionId?: string, currentModel?: Model<Api>, metadataResolver?: (provider: string) => Record<string, unknown> | undefined, signal?: AbortSignal, customSystemPrompt?: string): Promise<string | null>;
|
|
21
22
|
export declare function formatSessionTerminalTitle(sessionName: string | undefined, cwd?: string): string;
|
|
22
23
|
/**
|
|
23
24
|
* Set the terminal title using OSC 0 (sets both tab and window title). Unsupported terminals ignore it.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.10.
|
|
4
|
+
"version": "15.10.12",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.22.1",
|
|
48
48
|
"@babel/parser": "^7.29.7",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/hashline": "15.10.
|
|
51
|
-
"@oh-my-pi/omp-stats": "15.10.
|
|
52
|
-
"@oh-my-pi/pi-agent-core": "15.10.
|
|
53
|
-
"@oh-my-pi/pi-ai": "15.10.
|
|
54
|
-
"@oh-my-pi/pi-catalog": "15.10.
|
|
55
|
-
"@oh-my-pi/pi-mnemopi": "15.10.
|
|
56
|
-
"@oh-my-pi/pi-natives": "15.10.
|
|
57
|
-
"@oh-my-pi/pi-tui": "15.10.
|
|
58
|
-
"@oh-my-pi/pi-utils": "15.10.
|
|
50
|
+
"@oh-my-pi/hashline": "15.10.12",
|
|
51
|
+
"@oh-my-pi/omp-stats": "15.10.12",
|
|
52
|
+
"@oh-my-pi/pi-agent-core": "15.10.12",
|
|
53
|
+
"@oh-my-pi/pi-ai": "15.10.12",
|
|
54
|
+
"@oh-my-pi/pi-catalog": "15.10.12",
|
|
55
|
+
"@oh-my-pi/pi-mnemopi": "15.10.12",
|
|
56
|
+
"@oh-my-pi/pi-natives": "15.10.12",
|
|
57
|
+
"@oh-my-pi/pi-tui": "15.10.12",
|
|
58
|
+
"@oh-my-pi/pi-utils": "15.10.12",
|
|
59
59
|
"@opentelemetry/api": "^1.9.1",
|
|
60
60
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
61
61
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
package/src/cli/args.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface Args {
|
|
|
14
14
|
allowHome?: boolean;
|
|
15
15
|
provider?: string;
|
|
16
16
|
model?: string;
|
|
17
|
+
config?: string[];
|
|
17
18
|
smol?: string;
|
|
18
19
|
slow?: string;
|
|
19
20
|
plan?: string;
|
|
@@ -111,6 +112,8 @@ export function parseArgs(inputArgs: string[], extensionFlags?: Map<string, { ty
|
|
|
111
112
|
result.allowHome = true;
|
|
112
113
|
} else if (arg === "--cwd" && i + 1 < args.length) {
|
|
113
114
|
result.cwd = args[++i];
|
|
115
|
+
} else if (arg === "--config" && i + 1 < args.length) {
|
|
116
|
+
result.config = [...(result.config ?? []), args[++i]];
|
|
114
117
|
} else if (arg === "--mode" && i + 1 < args.length) {
|
|
115
118
|
const mode = args[++i];
|
|
116
119
|
if (mode === "text" || mode === "json" || mode === "rpc" || mode === "acp" || mode === "rpc-ui") {
|
package/src/cli-commands.ts
CHANGED
|
@@ -38,6 +38,18 @@ export const commands: CommandEntry[] = [
|
|
|
38
38
|
{ name: "search", load: () => import("./commands/web-search").then(m => m.default), aliases: ["q"] },
|
|
39
39
|
];
|
|
40
40
|
|
|
41
|
+
const RESERVED_TOP_LEVEL_WORDS = new Map<string, string>([
|
|
42
|
+
[
|
|
43
|
+
"extensions",
|
|
44
|
+
'`omp extensions` is not a management command. Use `omp plugin list` / `omp plugin install`, or run `omp launch extensions` if you meant to send "extensions" as a prompt.',
|
|
45
|
+
],
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
export function reservedTopLevelWordMessage(first: string | undefined, argc = 1): string | undefined {
|
|
49
|
+
if (argc !== 1 || !first || first.startsWith("-") || first.startsWith("@")) return undefined;
|
|
50
|
+
return RESERVED_TOP_LEVEL_WORDS.get(first);
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
/**
|
|
42
54
|
* Return true when `first` matches a registered subcommand name or alias.
|
|
43
55
|
*
|
|
@@ -48,3 +60,20 @@ export function isSubcommand(first: string | undefined): boolean {
|
|
|
48
60
|
if (!first || first.startsWith("-") || first.startsWith("@")) return false;
|
|
49
61
|
return commands.some(entry => entry.name === first || entry.aliases?.includes(first));
|
|
50
62
|
}
|
|
63
|
+
|
|
64
|
+
export type ResolvedCliArgv = { argv: string[] } | { error: string };
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Decide what the CLI runner should do with raw argv: reject bare reserved
|
|
68
|
+
* management words, pass help/version through untouched, and route everything
|
|
69
|
+
* that is not a known subcommand to `launch`.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveCliArgv(argv: string[]): ResolvedCliArgv {
|
|
72
|
+
const first = argv[0];
|
|
73
|
+
const reservedMessage = reservedTopLevelWordMessage(first, argv.length);
|
|
74
|
+
if (reservedMessage) return { error: reservedMessage };
|
|
75
|
+
if (first === "--help" || first === "-h" || first === "--version" || first === "-v" || first === "help") {
|
|
76
|
+
return { argv };
|
|
77
|
+
}
|
|
78
|
+
return { argv: isSubcommand(first) ? argv : ["launch", ...argv] };
|
|
79
|
+
}
|