@oh-my-pi/pi-coding-agent 3.15.0 → 3.20.0
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 +61 -1
- package/docs/extensions.md +1055 -0
- package/docs/rpc.md +69 -13
- package/docs/session-tree-plan.md +1 -1
- package/examples/extensions/README.md +141 -0
- package/examples/extensions/api-demo.ts +87 -0
- package/examples/extensions/chalk-logger.ts +26 -0
- package/examples/extensions/hello.ts +33 -0
- package/examples/extensions/pirate.ts +44 -0
- package/examples/extensions/plan-mode.ts +551 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/todo.ts +299 -0
- package/examples/extensions/tools.ts +145 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +16 -0
- package/examples/sdk/02-custom-model.ts +3 -3
- package/examples/sdk/05-tools.ts +7 -3
- package/examples/sdk/06-extensions.ts +81 -0
- package/examples/sdk/06-hooks.ts +14 -13
- package/examples/sdk/08-prompt-templates.ts +42 -0
- package/examples/sdk/08-slash-commands.ts +17 -12
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
- package/examples/sdk/12-full-control.ts +6 -6
- package/package.json +11 -7
- package/src/capability/extension-module.ts +34 -0
- package/src/cli/args.ts +22 -7
- package/src/cli/file-processor.ts +38 -67
- package/src/cli/list-models.ts +1 -1
- package/src/config.ts +25 -14
- package/src/core/agent-session.ts +505 -242
- package/src/core/auth-storage.ts +33 -21
- package/src/core/compaction/branch-summarization.ts +4 -4
- package/src/core/compaction/compaction.ts +3 -3
- package/src/core/custom-commands/bundled/wt/index.ts +430 -0
- package/src/core/custom-commands/loader.ts +9 -0
- package/src/core/custom-tools/wrapper.ts +5 -0
- package/src/core/event-bus.ts +59 -0
- package/src/core/export-html/vendor/highlight.min.js +1213 -0
- package/src/core/export-html/vendor/marked.min.js +6 -0
- package/src/core/extensions/index.ts +100 -0
- package/src/core/extensions/loader.ts +501 -0
- package/src/core/extensions/runner.ts +477 -0
- package/src/core/extensions/types.ts +712 -0
- package/src/core/extensions/wrapper.ts +147 -0
- package/src/core/hooks/types.ts +2 -2
- package/src/core/index.ts +10 -21
- package/src/core/keybindings.ts +199 -0
- package/src/core/messages.ts +26 -7
- package/src/core/model-registry.ts +123 -46
- package/src/core/model-resolver.ts +7 -5
- package/src/core/prompt-templates.ts +242 -0
- package/src/core/sdk.ts +378 -295
- package/src/core/session-manager.ts +72 -58
- package/src/core/settings-manager.ts +118 -22
- package/src/core/system-prompt.ts +24 -1
- package/src/core/terminal-notify.ts +37 -0
- package/src/core/tools/context.ts +4 -4
- package/src/core/tools/exa/mcp-client.ts +5 -4
- package/src/core/tools/exa/render.ts +176 -131
- package/src/core/tools/gemini-image.ts +361 -0
- package/src/core/tools/git.ts +216 -0
- package/src/core/tools/index.ts +28 -15
- package/src/core/tools/lsp/config.ts +5 -4
- package/src/core/tools/lsp/index.ts +17 -12
- package/src/core/tools/lsp/render.ts +39 -47
- package/src/core/tools/read.ts +66 -29
- package/src/core/tools/render-utils.ts +268 -0
- package/src/core/tools/renderers.ts +243 -225
- package/src/core/tools/task/discovery.ts +2 -2
- package/src/core/tools/task/executor.ts +66 -58
- package/src/core/tools/task/index.ts +29 -10
- package/src/core/tools/task/model-resolver.ts +8 -13
- package/src/core/tools/task/omp-command.ts +24 -0
- package/src/core/tools/task/render.ts +35 -60
- package/src/core/tools/task/types.ts +3 -0
- package/src/core/tools/web-fetch.ts +29 -28
- package/src/core/tools/web-search/index.ts +6 -5
- package/src/core/tools/web-search/providers/exa.ts +6 -5
- package/src/core/tools/web-search/render.ts +66 -111
- package/src/core/voice-controller.ts +135 -0
- package/src/core/voice-supervisor.ts +1003 -0
- package/src/core/voice.ts +308 -0
- package/src/discovery/builtin.ts +75 -1
- package/src/discovery/claude.ts +47 -1
- package/src/discovery/codex.ts +54 -2
- package/src/discovery/gemini.ts +55 -2
- package/src/discovery/helpers.ts +100 -1
- package/src/discovery/index.ts +2 -0
- package/src/index.ts +14 -9
- package/src/lib/worktree/collapse.ts +179 -0
- package/src/lib/worktree/constants.ts +14 -0
- package/src/lib/worktree/errors.ts +23 -0
- package/src/lib/worktree/git.ts +110 -0
- package/src/lib/worktree/index.ts +23 -0
- package/src/lib/worktree/operations.ts +216 -0
- package/src/lib/worktree/session.ts +114 -0
- package/src/lib/worktree/stats.ts +67 -0
- package/src/main.ts +61 -37
- package/src/migrations.ts +37 -7
- package/src/modes/interactive/components/bash-execution.ts +6 -4
- package/src/modes/interactive/components/custom-editor.ts +55 -0
- package/src/modes/interactive/components/custom-message.ts +95 -0
- package/src/modes/interactive/components/extensions/extension-list.ts +5 -0
- package/src/modes/interactive/components/extensions/inspector-panel.ts +18 -12
- package/src/modes/interactive/components/extensions/state-manager.ts +12 -0
- package/src/modes/interactive/components/extensions/types.ts +1 -0
- package/src/modes/interactive/components/footer.ts +324 -0
- package/src/modes/interactive/components/hook-editor.ts +1 -0
- package/src/modes/interactive/components/hook-selector.ts +3 -3
- package/src/modes/interactive/components/model-selector.ts +7 -6
- package/src/modes/interactive/components/oauth-selector.ts +3 -3
- package/src/modes/interactive/components/settings-defs.ts +55 -6
- package/src/modes/interactive/components/status-line/separators.ts +4 -4
- package/src/modes/interactive/components/status-line.ts +45 -35
- package/src/modes/interactive/components/tool-execution.ts +95 -23
- package/src/modes/interactive/interactive-mode.ts +644 -113
- package/src/modes/interactive/theme/defaults/alabaster.json +99 -0
- package/src/modes/interactive/theme/defaults/amethyst.json +103 -0
- package/src/modes/interactive/theme/defaults/anthracite.json +100 -0
- package/src/modes/interactive/theme/defaults/basalt.json +90 -0
- package/src/modes/interactive/theme/defaults/birch.json +101 -0
- package/src/modes/interactive/theme/defaults/dark-abyss.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-aurora.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-cavern.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-copper.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-cosmos.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-eclipse.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-ember.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-equinox.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-lavender.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-lunar.json +95 -0
- package/src/modes/interactive/theme/defaults/dark-midnight.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-nebula.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-rainforest.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-reef.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-sakura.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-slate.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-solstice.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-starfall.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-swamp.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-taiga.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-terminal.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-tundra.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-twilight.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-volcanic.json +97 -0
- package/src/modes/interactive/theme/defaults/graphite.json +99 -0
- package/src/modes/interactive/theme/defaults/index.ts +128 -0
- package/src/modes/interactive/theme/defaults/light-aurora-day.json +97 -0
- package/src/modes/interactive/theme/defaults/light-canyon.json +97 -0
- package/src/modes/interactive/theme/defaults/light-cirrus.json +96 -0
- package/src/modes/interactive/theme/defaults/light-coral.json +94 -0
- package/src/modes/interactive/theme/defaults/light-dawn.json +96 -0
- package/src/modes/interactive/theme/defaults/light-dunes.json +97 -0
- package/src/modes/interactive/theme/defaults/light-eucalyptus.json +94 -0
- package/src/modes/interactive/theme/defaults/light-frost.json +94 -0
- package/src/modes/interactive/theme/defaults/light-glacier.json +97 -0
- package/src/modes/interactive/theme/defaults/light-haze.json +96 -0
- package/src/modes/interactive/theme/defaults/light-honeycomb.json +94 -0
- package/src/modes/interactive/theme/defaults/light-lagoon.json +97 -0
- package/src/modes/interactive/theme/defaults/light-lavender.json +94 -0
- package/src/modes/interactive/theme/defaults/light-meadow.json +97 -0
- package/src/modes/interactive/theme/defaults/light-mint.json +94 -0
- package/src/modes/interactive/theme/defaults/light-opal.json +97 -0
- package/src/modes/interactive/theme/defaults/light-orchard.json +97 -0
- package/src/modes/interactive/theme/defaults/light-paper.json +94 -0
- package/src/modes/interactive/theme/defaults/light-prism.json +96 -0
- package/src/modes/interactive/theme/defaults/light-sand.json +94 -0
- package/src/modes/interactive/theme/defaults/light-savanna.json +97 -0
- package/src/modes/interactive/theme/defaults/light-soleil.json +96 -0
- package/src/modes/interactive/theme/defaults/light-wetland.json +97 -0
- package/src/modes/interactive/theme/defaults/light-zenith.json +95 -0
- package/src/modes/interactive/theme/defaults/limestone.json +100 -0
- package/src/modes/interactive/theme/defaults/mahogany.json +104 -0
- package/src/modes/interactive/theme/defaults/marble.json +99 -0
- package/src/modes/interactive/theme/defaults/obsidian.json +90 -0
- package/src/modes/interactive/theme/defaults/onyx.json +90 -0
- package/src/modes/interactive/theme/defaults/pearl.json +99 -0
- package/src/modes/interactive/theme/defaults/porcelain.json +90 -0
- package/src/modes/interactive/theme/defaults/quartz.json +102 -0
- package/src/modes/interactive/theme/defaults/sandstone.json +101 -0
- package/src/modes/interactive/theme/defaults/titanium.json +89 -0
- package/src/modes/print-mode.ts +14 -72
- package/src/modes/rpc/rpc-client.ts +23 -9
- package/src/modes/rpc/rpc-mode.ts +137 -125
- package/src/modes/rpc/rpc-types.ts +46 -24
- package/src/prompts/task.md +1 -0
- package/src/prompts/tools/gemini-image.md +4 -0
- package/src/prompts/tools/git.md +9 -0
- package/src/prompts/voice-summary.md +12 -0
- package/src/utils/image-convert.ts +26 -0
- package/src/utils/image-resize.ts +215 -0
- package/src/utils/shell-snapshot.ts +22 -20
|
@@ -0,0 +1,712 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension system types.
|
|
3
|
+
*
|
|
4
|
+
* Extensions are TypeScript modules that can:
|
|
5
|
+
* - Subscribe to agent lifecycle events
|
|
6
|
+
* - Register LLM-callable tools
|
|
7
|
+
* - Register commands, keyboard shortcuts, and CLI flags
|
|
8
|
+
* - Interact with the user via UI primitives
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
12
|
+
import type { ImageContent, Model, TextContent, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
13
|
+
import type { Component, KeyId, TUI } from "@oh-my-pi/pi-tui";
|
|
14
|
+
import type { Static, TSchema } from "@sinclair/typebox";
|
|
15
|
+
import type { Theme } from "../../modes/interactive/theme/theme";
|
|
16
|
+
import type { CompactionPreparation, CompactionResult } from "../compaction";
|
|
17
|
+
import type { EventBus } from "../event-bus";
|
|
18
|
+
import type { ExecOptions, ExecResult } from "../exec";
|
|
19
|
+
import type { CustomMessage } from "../messages";
|
|
20
|
+
import type { ModelRegistry } from "../model-registry";
|
|
21
|
+
import type {
|
|
22
|
+
BranchSummaryEntry,
|
|
23
|
+
CompactionEntry,
|
|
24
|
+
ReadonlySessionManager,
|
|
25
|
+
SessionEntry,
|
|
26
|
+
SessionManager,
|
|
27
|
+
} from "../session-manager";
|
|
28
|
+
import type { BashToolDetails, FindToolDetails, GrepToolDetails, LsToolDetails, ReadToolDetails } from "../tools";
|
|
29
|
+
import type { EditToolDetails } from "../tools/edit";
|
|
30
|
+
|
|
31
|
+
export type { ExecOptions, ExecResult } from "../exec";
|
|
32
|
+
export type { AgentToolResult, AgentToolUpdateCallback };
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// UI Context
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* UI context for extensions to request interactive UI.
|
|
40
|
+
* Each mode (interactive, RPC, print) provides its own implementation.
|
|
41
|
+
*/
|
|
42
|
+
export interface ExtensionUIContext {
|
|
43
|
+
/** Show a selector and return the user's choice. */
|
|
44
|
+
select(title: string, options: string[]): Promise<string | undefined>;
|
|
45
|
+
|
|
46
|
+
/** Show a confirmation dialog. */
|
|
47
|
+
confirm(title: string, message: string): Promise<boolean>;
|
|
48
|
+
|
|
49
|
+
/** Show a text input dialog. */
|
|
50
|
+
input(title: string, placeholder?: string): Promise<string | undefined>;
|
|
51
|
+
|
|
52
|
+
/** Show a notification to the user. */
|
|
53
|
+
notify(message: string, type?: "info" | "warning" | "error"): void;
|
|
54
|
+
|
|
55
|
+
/** Set status text in the footer/status bar. Pass undefined to clear. */
|
|
56
|
+
setStatus(key: string, text: string | undefined): void;
|
|
57
|
+
|
|
58
|
+
/** Set a widget to display above the editor. Accepts string array or component factory. */
|
|
59
|
+
setWidget(key: string, content: string[] | undefined): void;
|
|
60
|
+
setWidget(key: string, content: ((tui: TUI, theme: Theme) => Component & { dispose?(): void }) | undefined): void;
|
|
61
|
+
|
|
62
|
+
/** Set the terminal window/tab title. */
|
|
63
|
+
setTitle(title: string): void;
|
|
64
|
+
|
|
65
|
+
/** Show a custom component with keyboard focus. */
|
|
66
|
+
custom<T>(
|
|
67
|
+
factory: (
|
|
68
|
+
tui: TUI,
|
|
69
|
+
theme: Theme,
|
|
70
|
+
done: (result: T) => void,
|
|
71
|
+
) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,
|
|
72
|
+
): Promise<T>;
|
|
73
|
+
|
|
74
|
+
/** Set the text in the core input editor. */
|
|
75
|
+
setEditorText(text: string): void;
|
|
76
|
+
|
|
77
|
+
/** Get the current text from the core input editor. */
|
|
78
|
+
getEditorText(): string;
|
|
79
|
+
|
|
80
|
+
/** Show a multi-line editor for text editing. */
|
|
81
|
+
editor(title: string, prefill?: string): Promise<string | undefined>;
|
|
82
|
+
|
|
83
|
+
/** Get the current theme for styling. */
|
|
84
|
+
readonly theme: Theme;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Extension Context
|
|
89
|
+
// ============================================================================
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Context passed to extension event handlers.
|
|
93
|
+
*/
|
|
94
|
+
export interface ExtensionContext {
|
|
95
|
+
/** UI methods for user interaction */
|
|
96
|
+
ui: ExtensionUIContext;
|
|
97
|
+
/** Whether UI is available (false in print/RPC mode) */
|
|
98
|
+
hasUI: boolean;
|
|
99
|
+
/** Current working directory */
|
|
100
|
+
cwd: string;
|
|
101
|
+
/** Session manager (read-only) */
|
|
102
|
+
sessionManager: ReadonlySessionManager;
|
|
103
|
+
/** Model registry for API key resolution */
|
|
104
|
+
modelRegistry: ModelRegistry;
|
|
105
|
+
/** Current model (may be undefined) */
|
|
106
|
+
model: Model<any> | undefined;
|
|
107
|
+
/** Whether the agent is idle (not streaming) */
|
|
108
|
+
isIdle(): boolean;
|
|
109
|
+
/** Abort the current agent operation */
|
|
110
|
+
abort(): void;
|
|
111
|
+
/** Whether there are queued messages waiting */
|
|
112
|
+
hasPendingMessages(): boolean;
|
|
113
|
+
/** @deprecated Use hasPendingMessages() instead */
|
|
114
|
+
hasQueuedMessages(): boolean;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Extended context for command handlers.
|
|
119
|
+
* Includes session control methods only safe in user-initiated commands.
|
|
120
|
+
*/
|
|
121
|
+
export interface ExtensionCommandContext extends ExtensionContext {
|
|
122
|
+
/** Wait for the agent to finish streaming */
|
|
123
|
+
waitForIdle(): Promise<void>;
|
|
124
|
+
|
|
125
|
+
/** Start a new session, optionally with initialization. */
|
|
126
|
+
newSession(options?: {
|
|
127
|
+
parentSession?: string;
|
|
128
|
+
setup?: (sessionManager: SessionManager) => Promise<void>;
|
|
129
|
+
}): Promise<{ cancelled: boolean }>;
|
|
130
|
+
|
|
131
|
+
/** Branch from a specific entry, creating a new session file. */
|
|
132
|
+
branch(entryId: string): Promise<{ cancelled: boolean }>;
|
|
133
|
+
|
|
134
|
+
/** Navigate to a different point in the session tree. */
|
|
135
|
+
navigateTree(targetId: string, options?: { summarize?: boolean }): Promise<{ cancelled: boolean }>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Tool Types
|
|
140
|
+
// ============================================================================
|
|
141
|
+
|
|
142
|
+
/** Rendering options for tool results */
|
|
143
|
+
export interface ToolRenderResultOptions {
|
|
144
|
+
/** Whether the result view is expanded */
|
|
145
|
+
expanded: boolean;
|
|
146
|
+
/** Whether this is a partial/streaming result */
|
|
147
|
+
isPartial: boolean;
|
|
148
|
+
/** Current spinner frame index for animated elements (optional) */
|
|
149
|
+
spinnerFrame?: number;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Session event for tool onSession lifecycle */
|
|
153
|
+
export interface ToolSessionEvent {
|
|
154
|
+
/** Reason for the session event */
|
|
155
|
+
reason: "start" | "switch" | "branch" | "tree" | "shutdown";
|
|
156
|
+
/** Previous session file path, or undefined for "start" and "shutdown" */
|
|
157
|
+
previousSessionFile: string | undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Tool definition for registerTool().
|
|
162
|
+
*/
|
|
163
|
+
export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = unknown> {
|
|
164
|
+
/** Tool name (used in LLM tool calls) */
|
|
165
|
+
name: string;
|
|
166
|
+
/** Human-readable label for UI */
|
|
167
|
+
label: string;
|
|
168
|
+
/** Description for LLM */
|
|
169
|
+
description: string;
|
|
170
|
+
/** Parameter schema (TypeBox) */
|
|
171
|
+
parameters: TParams;
|
|
172
|
+
/** If true, tool is excluded unless explicitly listed in --tools or agent's tools field */
|
|
173
|
+
hidden?: boolean;
|
|
174
|
+
|
|
175
|
+
/** Execute the tool. */
|
|
176
|
+
execute(
|
|
177
|
+
toolCallId: string,
|
|
178
|
+
params: Static<TParams>,
|
|
179
|
+
onUpdate: AgentToolUpdateCallback<TDetails> | undefined,
|
|
180
|
+
ctx: ExtensionContext,
|
|
181
|
+
signal?: AbortSignal,
|
|
182
|
+
): Promise<AgentToolResult<TDetails>>;
|
|
183
|
+
|
|
184
|
+
/** Called on session lifecycle events - use to reconstruct state or cleanup resources */
|
|
185
|
+
onSession?: (event: ToolSessionEvent, ctx: ExtensionContext) => void | Promise<void>;
|
|
186
|
+
|
|
187
|
+
/** Custom rendering for tool call display */
|
|
188
|
+
renderCall?: (args: Static<TParams>, theme: Theme) => Component;
|
|
189
|
+
|
|
190
|
+
/** Custom rendering for tool result display */
|
|
191
|
+
renderResult?: (result: AgentToolResult<TDetails>, options: ToolRenderResultOptions, theme: Theme) => Component;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Session Events
|
|
196
|
+
// ============================================================================
|
|
197
|
+
|
|
198
|
+
/** Fired on initial session load */
|
|
199
|
+
export interface SessionStartEvent {
|
|
200
|
+
type: "session_start";
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** Fired before switching to another session (can be cancelled) */
|
|
204
|
+
export interface SessionBeforeSwitchEvent {
|
|
205
|
+
type: "session_before_switch";
|
|
206
|
+
reason: "new" | "resume";
|
|
207
|
+
targetSessionFile?: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Fired after switching to another session */
|
|
211
|
+
export interface SessionSwitchEvent {
|
|
212
|
+
type: "session_switch";
|
|
213
|
+
reason: "new" | "resume";
|
|
214
|
+
previousSessionFile: string | undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Fired before branching a session (can be cancelled) */
|
|
218
|
+
export interface SessionBeforeBranchEvent {
|
|
219
|
+
type: "session_before_branch";
|
|
220
|
+
entryId: string;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Fired after branching a session */
|
|
224
|
+
export interface SessionBranchEvent {
|
|
225
|
+
type: "session_branch";
|
|
226
|
+
previousSessionFile: string | undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Fired before context compaction (can be cancelled or customized) */
|
|
230
|
+
export interface SessionBeforeCompactEvent {
|
|
231
|
+
type: "session_before_compact";
|
|
232
|
+
preparation: CompactionPreparation;
|
|
233
|
+
branchEntries: SessionEntry[];
|
|
234
|
+
customInstructions?: string;
|
|
235
|
+
signal: AbortSignal;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Fired after context compaction */
|
|
239
|
+
export interface SessionCompactEvent {
|
|
240
|
+
type: "session_compact";
|
|
241
|
+
compactionEntry: CompactionEntry;
|
|
242
|
+
fromExtension: boolean;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Fired on process exit */
|
|
246
|
+
export interface SessionShutdownEvent {
|
|
247
|
+
type: "session_shutdown";
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Preparation data for tree navigation */
|
|
251
|
+
export interface TreePreparation {
|
|
252
|
+
targetId: string;
|
|
253
|
+
oldLeafId: string | null;
|
|
254
|
+
commonAncestorId: string | null;
|
|
255
|
+
entriesToSummarize: SessionEntry[];
|
|
256
|
+
userWantsSummary: boolean;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Fired before navigating in the session tree (can be cancelled) */
|
|
260
|
+
export interface SessionBeforeTreeEvent {
|
|
261
|
+
type: "session_before_tree";
|
|
262
|
+
preparation: TreePreparation;
|
|
263
|
+
signal: AbortSignal;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Fired after navigating in the session tree */
|
|
267
|
+
export interface SessionTreeEvent {
|
|
268
|
+
type: "session_tree";
|
|
269
|
+
newLeafId: string | null;
|
|
270
|
+
oldLeafId: string | null;
|
|
271
|
+
summaryEntry?: BranchSummaryEntry;
|
|
272
|
+
fromExtension?: boolean;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export type SessionEvent =
|
|
276
|
+
| SessionStartEvent
|
|
277
|
+
| SessionBeforeSwitchEvent
|
|
278
|
+
| SessionSwitchEvent
|
|
279
|
+
| SessionBeforeBranchEvent
|
|
280
|
+
| SessionBranchEvent
|
|
281
|
+
| SessionBeforeCompactEvent
|
|
282
|
+
| SessionCompactEvent
|
|
283
|
+
| SessionShutdownEvent
|
|
284
|
+
| SessionBeforeTreeEvent
|
|
285
|
+
| SessionTreeEvent;
|
|
286
|
+
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// Agent Events
|
|
289
|
+
// ============================================================================
|
|
290
|
+
|
|
291
|
+
/** Fired before each LLM call. Can modify messages. */
|
|
292
|
+
export interface ContextEvent {
|
|
293
|
+
type: "context";
|
|
294
|
+
messages: AgentMessage[];
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Fired after user submits prompt but before agent loop. */
|
|
298
|
+
export interface BeforeAgentStartEvent {
|
|
299
|
+
type: "before_agent_start";
|
|
300
|
+
prompt: string;
|
|
301
|
+
images?: ImageContent[];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Fired when an agent loop starts */
|
|
305
|
+
export interface AgentStartEvent {
|
|
306
|
+
type: "agent_start";
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** Fired when an agent loop ends */
|
|
310
|
+
export interface AgentEndEvent {
|
|
311
|
+
type: "agent_end";
|
|
312
|
+
messages: AgentMessage[];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Fired at the start of each turn */
|
|
316
|
+
export interface TurnStartEvent {
|
|
317
|
+
type: "turn_start";
|
|
318
|
+
turnIndex: number;
|
|
319
|
+
timestamp: number;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Fired at the end of each turn */
|
|
323
|
+
export interface TurnEndEvent {
|
|
324
|
+
type: "turn_end";
|
|
325
|
+
turnIndex: number;
|
|
326
|
+
message: AgentMessage;
|
|
327
|
+
toolResults: ToolResultMessage[];
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// ============================================================================
|
|
331
|
+
// Tool Events
|
|
332
|
+
// ============================================================================
|
|
333
|
+
|
|
334
|
+
/** Fired before a tool executes. Can block. */
|
|
335
|
+
export interface ToolCallEvent {
|
|
336
|
+
type: "tool_call";
|
|
337
|
+
toolName: string;
|
|
338
|
+
toolCallId: string;
|
|
339
|
+
input: Record<string, unknown>;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
interface ToolResultEventBase {
|
|
343
|
+
type: "tool_result";
|
|
344
|
+
toolCallId: string;
|
|
345
|
+
input: Record<string, unknown>;
|
|
346
|
+
content: (TextContent | ImageContent)[];
|
|
347
|
+
isError: boolean;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface BashToolResultEvent extends ToolResultEventBase {
|
|
351
|
+
toolName: "bash";
|
|
352
|
+
details: BashToolDetails | undefined;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface ReadToolResultEvent extends ToolResultEventBase {
|
|
356
|
+
toolName: "read";
|
|
357
|
+
details: ReadToolDetails | undefined;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface EditToolResultEvent extends ToolResultEventBase {
|
|
361
|
+
toolName: "edit";
|
|
362
|
+
details: EditToolDetails | undefined;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface WriteToolResultEvent extends ToolResultEventBase {
|
|
366
|
+
toolName: "write";
|
|
367
|
+
details: undefined;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export interface GrepToolResultEvent extends ToolResultEventBase {
|
|
371
|
+
toolName: "grep";
|
|
372
|
+
details: GrepToolDetails | undefined;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface FindToolResultEvent extends ToolResultEventBase {
|
|
376
|
+
toolName: "find";
|
|
377
|
+
details: FindToolDetails | undefined;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface LsToolResultEvent extends ToolResultEventBase {
|
|
381
|
+
toolName: "ls";
|
|
382
|
+
details: LsToolDetails | undefined;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface CustomToolResultEvent extends ToolResultEventBase {
|
|
386
|
+
toolName: string;
|
|
387
|
+
details: unknown;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** Fired after a tool executes. Can modify result. */
|
|
391
|
+
export type ToolResultEvent =
|
|
392
|
+
| BashToolResultEvent
|
|
393
|
+
| ReadToolResultEvent
|
|
394
|
+
| EditToolResultEvent
|
|
395
|
+
| WriteToolResultEvent
|
|
396
|
+
| GrepToolResultEvent
|
|
397
|
+
| FindToolResultEvent
|
|
398
|
+
| LsToolResultEvent
|
|
399
|
+
| CustomToolResultEvent;
|
|
400
|
+
|
|
401
|
+
// Type guards
|
|
402
|
+
export function isBashToolResult(e: ToolResultEvent): e is BashToolResultEvent {
|
|
403
|
+
return e.toolName === "bash";
|
|
404
|
+
}
|
|
405
|
+
export function isReadToolResult(e: ToolResultEvent): e is ReadToolResultEvent {
|
|
406
|
+
return e.toolName === "read";
|
|
407
|
+
}
|
|
408
|
+
export function isEditToolResult(e: ToolResultEvent): e is EditToolResultEvent {
|
|
409
|
+
return e.toolName === "edit";
|
|
410
|
+
}
|
|
411
|
+
export function isWriteToolResult(e: ToolResultEvent): e is WriteToolResultEvent {
|
|
412
|
+
return e.toolName === "write";
|
|
413
|
+
}
|
|
414
|
+
export function isGrepToolResult(e: ToolResultEvent): e is GrepToolResultEvent {
|
|
415
|
+
return e.toolName === "grep";
|
|
416
|
+
}
|
|
417
|
+
export function isFindToolResult(e: ToolResultEvent): e is FindToolResultEvent {
|
|
418
|
+
return e.toolName === "find";
|
|
419
|
+
}
|
|
420
|
+
export function isLsToolResult(e: ToolResultEvent): e is LsToolResultEvent {
|
|
421
|
+
return e.toolName === "ls";
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/** Union of all event types */
|
|
425
|
+
export type ExtensionEvent =
|
|
426
|
+
| SessionEvent
|
|
427
|
+
| ContextEvent
|
|
428
|
+
| BeforeAgentStartEvent
|
|
429
|
+
| AgentStartEvent
|
|
430
|
+
| AgentEndEvent
|
|
431
|
+
| TurnStartEvent
|
|
432
|
+
| TurnEndEvent
|
|
433
|
+
| ToolCallEvent
|
|
434
|
+
| ToolResultEvent;
|
|
435
|
+
|
|
436
|
+
// ============================================================================
|
|
437
|
+
// Event Results
|
|
438
|
+
// ============================================================================
|
|
439
|
+
|
|
440
|
+
export interface ContextEventResult {
|
|
441
|
+
messages?: AgentMessage[];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export interface ToolCallEventResult {
|
|
445
|
+
block?: boolean;
|
|
446
|
+
reason?: string;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
export interface ToolResultEventResult {
|
|
450
|
+
content?: (TextContent | ImageContent)[];
|
|
451
|
+
details?: unknown;
|
|
452
|
+
isError?: boolean;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export interface BeforeAgentStartEventResult {
|
|
456
|
+
message?: Pick<CustomMessage, "customType" | "content" | "display" | "details">;
|
|
457
|
+
systemPromptAppend?: string;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export interface SessionBeforeSwitchResult {
|
|
461
|
+
cancel?: boolean;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface SessionBeforeBranchResult {
|
|
465
|
+
cancel?: boolean;
|
|
466
|
+
skipConversationRestore?: boolean;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export interface SessionBeforeCompactResult {
|
|
470
|
+
cancel?: boolean;
|
|
471
|
+
compaction?: CompactionResult;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
export interface SessionBeforeTreeResult {
|
|
475
|
+
cancel?: boolean;
|
|
476
|
+
summary?: {
|
|
477
|
+
summary: string;
|
|
478
|
+
details?: unknown;
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// ============================================================================
|
|
483
|
+
// Message Rendering
|
|
484
|
+
// ============================================================================
|
|
485
|
+
|
|
486
|
+
export interface MessageRenderOptions {
|
|
487
|
+
expanded: boolean;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export type MessageRenderer<T = unknown> = (
|
|
491
|
+
message: CustomMessage<T>,
|
|
492
|
+
options: MessageRenderOptions,
|
|
493
|
+
theme: Theme,
|
|
494
|
+
) => Component | undefined;
|
|
495
|
+
|
|
496
|
+
// ============================================================================
|
|
497
|
+
// Command Registration
|
|
498
|
+
// ============================================================================
|
|
499
|
+
|
|
500
|
+
export interface RegisteredCommand {
|
|
501
|
+
name: string;
|
|
502
|
+
description?: string;
|
|
503
|
+
handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// ============================================================================
|
|
507
|
+
// Extension API
|
|
508
|
+
// ============================================================================
|
|
509
|
+
|
|
510
|
+
/** Handler function type for events */
|
|
511
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: void allows bare return statements
|
|
512
|
+
export type ExtensionHandler<E, R = undefined> = (event: E, ctx: ExtensionContext) => Promise<R | void> | R | void;
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* ExtensionAPI passed to extension factory functions.
|
|
516
|
+
*/
|
|
517
|
+
export interface ExtensionAPI {
|
|
518
|
+
// =========================================================================
|
|
519
|
+
// Module Access
|
|
520
|
+
// =========================================================================
|
|
521
|
+
|
|
522
|
+
/** File logger for error/warning/debug messages */
|
|
523
|
+
logger: typeof import("../logger").logger;
|
|
524
|
+
|
|
525
|
+
/** Injected @sinclair/typebox module for defining tool parameters */
|
|
526
|
+
typebox: typeof import("@sinclair/typebox");
|
|
527
|
+
|
|
528
|
+
/** Injected pi-coding-agent exports for accessing SDK utilities */
|
|
529
|
+
pi: typeof import("../../index.js");
|
|
530
|
+
|
|
531
|
+
// =========================================================================
|
|
532
|
+
// Event Subscription
|
|
533
|
+
// =========================================================================
|
|
534
|
+
|
|
535
|
+
on(event: "session_start", handler: ExtensionHandler<SessionStartEvent>): void;
|
|
536
|
+
on(
|
|
537
|
+
event: "session_before_switch",
|
|
538
|
+
handler: ExtensionHandler<SessionBeforeSwitchEvent, SessionBeforeSwitchResult>,
|
|
539
|
+
): void;
|
|
540
|
+
on(event: "session_switch", handler: ExtensionHandler<SessionSwitchEvent>): void;
|
|
541
|
+
on(
|
|
542
|
+
event: "session_before_branch",
|
|
543
|
+
handler: ExtensionHandler<SessionBeforeBranchEvent, SessionBeforeBranchResult>,
|
|
544
|
+
): void;
|
|
545
|
+
on(event: "session_branch", handler: ExtensionHandler<SessionBranchEvent>): void;
|
|
546
|
+
on(
|
|
547
|
+
event: "session_before_compact",
|
|
548
|
+
handler: ExtensionHandler<SessionBeforeCompactEvent, SessionBeforeCompactResult>,
|
|
549
|
+
): void;
|
|
550
|
+
on(event: "session_compact", handler: ExtensionHandler<SessionCompactEvent>): void;
|
|
551
|
+
on(event: "session_shutdown", handler: ExtensionHandler<SessionShutdownEvent>): void;
|
|
552
|
+
on(event: "session_before_tree", handler: ExtensionHandler<SessionBeforeTreeEvent, SessionBeforeTreeResult>): void;
|
|
553
|
+
on(event: "session_tree", handler: ExtensionHandler<SessionTreeEvent>): void;
|
|
554
|
+
on(event: "context", handler: ExtensionHandler<ContextEvent, ContextEventResult>): void;
|
|
555
|
+
on(event: "before_agent_start", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;
|
|
556
|
+
on(event: "agent_start", handler: ExtensionHandler<AgentStartEvent>): void;
|
|
557
|
+
on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
|
|
558
|
+
on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
|
|
559
|
+
on(event: "turn_end", handler: ExtensionHandler<TurnEndEvent>): void;
|
|
560
|
+
on(event: "tool_call", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;
|
|
561
|
+
on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
|
|
562
|
+
|
|
563
|
+
// =========================================================================
|
|
564
|
+
// Tool Registration
|
|
565
|
+
// =========================================================================
|
|
566
|
+
|
|
567
|
+
/** Register a tool that the LLM can call. */
|
|
568
|
+
registerTool<TParams extends TSchema = TSchema, TDetails = unknown>(tool: ToolDefinition<TParams, TDetails>): void;
|
|
569
|
+
|
|
570
|
+
// =========================================================================
|
|
571
|
+
// Command, Shortcut, Flag Registration
|
|
572
|
+
// =========================================================================
|
|
573
|
+
|
|
574
|
+
/** Register a custom command. */
|
|
575
|
+
registerCommand(name: string, options: { description?: string; handler: RegisteredCommand["handler"] }): void;
|
|
576
|
+
|
|
577
|
+
/** Register a keyboard shortcut. */
|
|
578
|
+
registerShortcut(
|
|
579
|
+
shortcut: KeyId,
|
|
580
|
+
options: {
|
|
581
|
+
description?: string;
|
|
582
|
+
handler: (ctx: ExtensionContext) => Promise<void> | void;
|
|
583
|
+
},
|
|
584
|
+
): void;
|
|
585
|
+
|
|
586
|
+
/** Register a CLI flag. */
|
|
587
|
+
registerFlag(
|
|
588
|
+
name: string,
|
|
589
|
+
options: {
|
|
590
|
+
description?: string;
|
|
591
|
+
type: "boolean" | "string";
|
|
592
|
+
default?: boolean | string;
|
|
593
|
+
},
|
|
594
|
+
): void;
|
|
595
|
+
|
|
596
|
+
/** Get the value of a registered CLI flag. */
|
|
597
|
+
getFlag(name: string): boolean | string | undefined;
|
|
598
|
+
|
|
599
|
+
// =========================================================================
|
|
600
|
+
// Message Rendering
|
|
601
|
+
// =========================================================================
|
|
602
|
+
|
|
603
|
+
/** Register a custom renderer for CustomMessageEntry. */
|
|
604
|
+
registerMessageRenderer<T = unknown>(customType: string, renderer: MessageRenderer<T>): void;
|
|
605
|
+
|
|
606
|
+
// =========================================================================
|
|
607
|
+
// Actions
|
|
608
|
+
// =========================================================================
|
|
609
|
+
|
|
610
|
+
/** Send a custom message to the session. */
|
|
611
|
+
sendMessage<T = unknown>(
|
|
612
|
+
message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details">,
|
|
613
|
+
options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" },
|
|
614
|
+
): void;
|
|
615
|
+
|
|
616
|
+
/** Append a custom entry to the session for state persistence (not sent to LLM). */
|
|
617
|
+
appendEntry<T = unknown>(customType: string, data?: T): void;
|
|
618
|
+
|
|
619
|
+
/** Execute a shell command. */
|
|
620
|
+
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
621
|
+
|
|
622
|
+
/** Get the list of currently active tool names. */
|
|
623
|
+
getActiveTools(): string[];
|
|
624
|
+
|
|
625
|
+
/** Get all configured tools (built-in + extension tools). */
|
|
626
|
+
getAllTools(): string[];
|
|
627
|
+
|
|
628
|
+
/** Set the active tools by name. */
|
|
629
|
+
setActiveTools(toolNames: string[]): void;
|
|
630
|
+
|
|
631
|
+
/** Shared event bus for extension communication. */
|
|
632
|
+
events: EventBus;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/** Extension factory function type. */
|
|
636
|
+
export type ExtensionFactory = (pi: ExtensionAPI) => void;
|
|
637
|
+
|
|
638
|
+
// ============================================================================
|
|
639
|
+
// Loaded Extension Types
|
|
640
|
+
// ============================================================================
|
|
641
|
+
|
|
642
|
+
export interface RegisteredTool {
|
|
643
|
+
definition: ToolDefinition;
|
|
644
|
+
extensionPath: string;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export interface ExtensionFlag {
|
|
648
|
+
name: string;
|
|
649
|
+
description?: string;
|
|
650
|
+
type: "boolean" | "string";
|
|
651
|
+
default?: boolean | string;
|
|
652
|
+
extensionPath: string;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
export interface ExtensionShortcut {
|
|
656
|
+
shortcut: KeyId;
|
|
657
|
+
description?: string;
|
|
658
|
+
handler: (ctx: ExtensionContext) => Promise<void> | void;
|
|
659
|
+
extensionPath: string;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
type HandlerFn = (...args: unknown[]) => Promise<unknown>;
|
|
663
|
+
|
|
664
|
+
export type SendMessageHandler = <T = unknown>(
|
|
665
|
+
message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details">,
|
|
666
|
+
options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" },
|
|
667
|
+
) => void;
|
|
668
|
+
|
|
669
|
+
export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;
|
|
670
|
+
|
|
671
|
+
export type GetActiveToolsHandler = () => string[];
|
|
672
|
+
|
|
673
|
+
export type GetAllToolsHandler = () => string[];
|
|
674
|
+
|
|
675
|
+
export type SetActiveToolsHandler = (toolNames: string[]) => void;
|
|
676
|
+
|
|
677
|
+
/** Loaded extension with all registered items. */
|
|
678
|
+
export interface LoadedExtension {
|
|
679
|
+
path: string;
|
|
680
|
+
resolvedPath: string;
|
|
681
|
+
handlers: Map<string, HandlerFn[]>;
|
|
682
|
+
tools: Map<string, RegisteredTool>;
|
|
683
|
+
messageRenderers: Map<string, MessageRenderer>;
|
|
684
|
+
commands: Map<string, RegisteredCommand>;
|
|
685
|
+
flags: Map<string, ExtensionFlag>;
|
|
686
|
+
flagValues: Map<string, boolean | string>;
|
|
687
|
+
shortcuts: Map<KeyId, ExtensionShortcut>;
|
|
688
|
+
setSendMessageHandler: (handler: SendMessageHandler) => void;
|
|
689
|
+
setAppendEntryHandler: (handler: AppendEntryHandler) => void;
|
|
690
|
+
setGetActiveToolsHandler: (handler: GetActiveToolsHandler) => void;
|
|
691
|
+
setGetAllToolsHandler: (handler: GetAllToolsHandler) => void;
|
|
692
|
+
setSetActiveToolsHandler: (handler: SetActiveToolsHandler) => void;
|
|
693
|
+
setFlagValue: (name: string, value: boolean | string) => void;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/** Result of loading extensions. */
|
|
697
|
+
export interface LoadExtensionsResult {
|
|
698
|
+
extensions: LoadedExtension[];
|
|
699
|
+
errors: Array<{ path: string; error: string }>;
|
|
700
|
+
setUIContext(uiContext: ExtensionUIContext, hasUI: boolean): void;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// ============================================================================
|
|
704
|
+
// Extension Error
|
|
705
|
+
// ============================================================================
|
|
706
|
+
|
|
707
|
+
export interface ExtensionError {
|
|
708
|
+
extensionPath: string;
|
|
709
|
+
event: string;
|
|
710
|
+
error: string;
|
|
711
|
+
stack?: string;
|
|
712
|
+
}
|