@dyyz1993/pi-coding-agent 0.70.6 → 0.74.5
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 +266 -80
- package/README.md +48 -20
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +4 -2
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts +13 -0
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
- package/dist/bun/restore-sandbox-env.js +32 -0
- package/dist/bun/restore-sandbox-env.js.map +1 -0
- package/dist/cli/args.d.ts +2 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +34 -22
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -4
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +16 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +238 -66
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +10 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +14 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +2 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +37 -26
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1068 -1116
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +21 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +9 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +20 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +9 -6
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +0 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/template.css +53 -4
- package/dist/core/export-html/template.js +84 -20
- package/dist/core/export-html/tool-renderer.d.ts +0 -6
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +15 -2
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +0 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +49 -137
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +24 -20
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +128 -253
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +88 -60
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +10 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/file-store/file-snapshot-manager.d.ts +95 -0
- package/dist/core/file-store/file-snapshot-manager.d.ts.map +1 -0
- package/dist/core/file-store/file-snapshot-manager.js +508 -0
- package/dist/core/file-store/file-snapshot-manager.js.map +1 -0
- package/dist/core/file-store/index.d.ts +5 -0
- package/dist/core/file-store/index.d.ts.map +1 -0
- package/dist/core/file-store/index.js +3 -0
- package/dist/core/file-store/index.js.map +1 -0
- package/dist/core/messages.d.ts +10 -2
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +23 -6
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +19 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +97 -16
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +24 -15
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +61 -35
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/provider-display-names.d.ts +2 -0
- package/dist/core/provider-display-names.d.ts.map +1 -0
- package/dist/core/provider-display-names.js +32 -0
- package/dist/core/provider-display-names.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +9 -21
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +9 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +39 -18
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +27 -17
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +133 -47
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +22 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +54 -6
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +3 -8
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +4 -3
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts +0 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +155 -110
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +3 -2
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +50 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +178 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +70 -13
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -39
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +3 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +3 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -4
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +14 -56
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +19 -4
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +18 -6
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +93 -25
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +3 -7
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +5 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +53 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +20 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +423 -186
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/light.json +1 -1
- package/dist/modes/print-mode.d.ts +3 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +62 -19
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +80 -60
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +108 -93
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +106 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +115 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +238 -12
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/child-process.d.ts +1 -0
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +8 -0
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +2 -2
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +84 -45
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/paths.d.ts +9 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +31 -0
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/utils/pi-user-agent.d.ts.map +1 -0
- package/dist/utils/pi-user-agent.js +5 -0
- package/dist/utils/pi-user-agent.js.map +1 -0
- package/dist/utils/structured-output.d.ts +10 -0
- package/dist/utils/structured-output.d.ts.map +1 -0
- package/dist/utils/structured-output.js +57 -0
- package/dist/utils/structured-output.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +6 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +77 -0
- package/dist/utils/version-check.js.map +1 -0
- package/docs/compaction.md +14 -14
- package/docs/custom-provider.md +40 -31
- package/docs/development.md +1 -1
- package/docs/docs.json +148 -0
- package/docs/extensions.md +116 -56
- package/docs/index.md +70 -0
- package/docs/json.md +4 -4
- package/docs/models.md +150 -3
- package/docs/packages.md +10 -5
- package/docs/providers.md +62 -17
- package/docs/quickstart.md +142 -0
- package/docs/rollback-architecture.md +693 -0
- package/docs/rollback-test-cases.md +412 -0
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +26 -26
- package/docs/{session.md → session-format.md} +6 -6
- package/docs/sessions.md +137 -0
- package/docs/settings.md +52 -9
- package/docs/termux.md +1 -1
- package/docs/themes.md +2 -2
- package/docs/tui.md +20 -20
- package/docs/usage.md +277 -0
- package/examples/extensions/README.md +2 -4
- package/examples/extensions/border-status-editor.ts +150 -0
- package/examples/extensions/commands.ts +2 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/git-checkpoint.ts +1 -1
- package/examples/extensions/handoff.ts +49 -11
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +5 -5
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/README.md +2 -2
- package/package.json +7 -16
- package/docs/tree.md +0 -233
- package/examples/extensions/antigravity-image-gen.ts +0 -418
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extension runner - executes extensions and manages their lifecycle.
|
|
3
3
|
*/
|
|
4
|
-
import { randomUUID } from "node:crypto";
|
|
5
4
|
import { theme } from "../../modes/interactive/theme/theme.js";
|
|
6
|
-
import { getCwdDataDir, getGlobalDataDir, getProjectDataDir, getSessionDataDir, resolveProjectRoot, } from "../storage.js";
|
|
7
5
|
// Extension shortcuts compete with canonical keybinding ids from keybindings.json.
|
|
8
6
|
// Only editor-global shortcuts are reserved here. Picker-specific bindings are not.
|
|
9
7
|
const RESERVED_KEYBINDINGS_FOR_EXTENSION_CONFLICTS = [
|
|
@@ -66,6 +64,7 @@ const noOpUIContext = {
|
|
|
66
64
|
onTerminalInput: () => () => { },
|
|
67
65
|
setStatus: () => { },
|
|
68
66
|
setWorkingMessage: () => { },
|
|
67
|
+
setWorkingVisible: () => { },
|
|
69
68
|
setWorkingIndicator: () => { },
|
|
70
69
|
setHiddenThinkingLabel: () => { },
|
|
71
70
|
setWidget: () => { },
|
|
@@ -79,6 +78,7 @@ const noOpUIContext = {
|
|
|
79
78
|
editor: async () => undefined,
|
|
80
79
|
addAutocompleteProvider: () => { },
|
|
81
80
|
setEditorComponent: () => { },
|
|
81
|
+
getEditorComponent: () => undefined,
|
|
82
82
|
get theme() {
|
|
83
83
|
return theme;
|
|
84
84
|
},
|
|
@@ -92,7 +92,6 @@ export class ExtensionRunner {
|
|
|
92
92
|
extensions;
|
|
93
93
|
runtime;
|
|
94
94
|
uiContext;
|
|
95
|
-
uiContextOriginal;
|
|
96
95
|
cwd;
|
|
97
96
|
sessionManager;
|
|
98
97
|
modelRegistry;
|
|
@@ -100,13 +99,20 @@ export class ExtensionRunner {
|
|
|
100
99
|
getModel = () => undefined;
|
|
101
100
|
isIdleFn = () => true;
|
|
102
101
|
getSignalFn = () => undefined;
|
|
103
|
-
getSessionSignalFn = () => AbortSignal.abort();
|
|
104
102
|
waitForIdleFn = async () => { };
|
|
105
103
|
abortFn = () => { };
|
|
106
104
|
hasPendingMessagesFn = () => false;
|
|
107
105
|
getContextUsageFn = () => undefined;
|
|
108
106
|
compactFn = () => { };
|
|
109
107
|
getSystemPromptFn = () => "";
|
|
108
|
+
getSessionSignalFn = () => AbortSignal.abort();
|
|
109
|
+
getExtensionNameFn = () => "";
|
|
110
|
+
getProjectRootFn = () => this.cwd;
|
|
111
|
+
getSessionDataDirFn = () => "";
|
|
112
|
+
getProjectDataDirFn = () => "";
|
|
113
|
+
getCwdDataDirFn = () => "";
|
|
114
|
+
getGlobalDataDirFn = () => "";
|
|
115
|
+
respondUIFn = () => { };
|
|
110
116
|
newSessionHandler = async () => ({ cancelled: false });
|
|
111
117
|
forkHandler = async () => ({ cancelled: false });
|
|
112
118
|
navigateTreeHandler = async () => ({ cancelled: false });
|
|
@@ -116,12 +122,30 @@ export class ExtensionRunner {
|
|
|
116
122
|
shortcutDiagnostics = [];
|
|
117
123
|
commandDiagnostics = [];
|
|
118
124
|
staleMessage;
|
|
119
|
-
|
|
125
|
+
_fileSnapshotManager = null;
|
|
126
|
+
setFileSnapshotManager(manager) {
|
|
127
|
+
this._fileSnapshotManager = manager;
|
|
128
|
+
}
|
|
129
|
+
setContextDirFns(fns) {
|
|
130
|
+
if (fns.getExtensionName)
|
|
131
|
+
this.getExtensionNameFn = fns.getExtensionName;
|
|
132
|
+
if (fns.getProjectRoot)
|
|
133
|
+
this.getProjectRootFn = fns.getProjectRoot;
|
|
134
|
+
if (fns.getSessionDataDir)
|
|
135
|
+
this.getSessionDataDirFn = fns.getSessionDataDir;
|
|
136
|
+
if (fns.getProjectDataDir)
|
|
137
|
+
this.getProjectDataDirFn = fns.getProjectDataDir;
|
|
138
|
+
if (fns.getCwdDataDir)
|
|
139
|
+
this.getCwdDataDirFn = fns.getCwdDataDir;
|
|
140
|
+
if (fns.getGlobalDataDir)
|
|
141
|
+
this.getGlobalDataDirFn = fns.getGlobalDataDir;
|
|
142
|
+
if (fns.respondUI)
|
|
143
|
+
this.respondUIFn = fns.respondUI;
|
|
144
|
+
}
|
|
120
145
|
constructor(extensions, runtime, cwd, sessionManager, modelRegistry) {
|
|
121
146
|
this.extensions = extensions;
|
|
122
147
|
this.runtime = runtime;
|
|
123
148
|
this.uiContext = noOpUIContext;
|
|
124
|
-
this.uiContextOriginal = undefined;
|
|
125
149
|
this.cwd = cwd;
|
|
126
150
|
this.sessionManager = sessionManager;
|
|
127
151
|
this.modelRegistry = modelRegistry;
|
|
@@ -131,7 +155,6 @@ export class ExtensionRunner {
|
|
|
131
155
|
this.runtime.sendMessage = actions.sendMessage;
|
|
132
156
|
this.runtime.sendUserMessage = actions.sendUserMessage;
|
|
133
157
|
this.runtime.appendEntry = actions.appendEntry;
|
|
134
|
-
this.runtime.foldEntry = actions.foldEntry;
|
|
135
158
|
this.runtime.setSessionName = actions.setSessionName;
|
|
136
159
|
this.runtime.getSessionName = actions.getSessionName;
|
|
137
160
|
this.runtime.setLabel = actions.setLabel;
|
|
@@ -143,21 +166,19 @@ export class ExtensionRunner {
|
|
|
143
166
|
this.runtime.setModel = actions.setModel;
|
|
144
167
|
this.runtime.getThinkingLevel = actions.getThinkingLevel;
|
|
145
168
|
this.runtime.setThinkingLevel = actions.setThinkingLevel;
|
|
146
|
-
this.runtime.registerChannel = actions.registerChannel;
|
|
147
|
-
this.runtime.callLLM = actions.callLLM;
|
|
148
|
-
this.runtime.callLLMStructured = actions.callLLMStructured;
|
|
149
|
-
this.runtime.background = actions.background;
|
|
150
169
|
// Context actions (required)
|
|
151
170
|
this.getModel = contextActions.getModel;
|
|
152
171
|
this.isIdleFn = contextActions.isIdle;
|
|
153
172
|
this.getSignalFn = contextActions.getSignal;
|
|
154
|
-
this.getSessionSignalFn = contextActions.getSessionSignal;
|
|
155
173
|
this.abortFn = contextActions.abort;
|
|
156
174
|
this.hasPendingMessagesFn = contextActions.hasPendingMessages;
|
|
157
175
|
this.shutdownHandler = contextActions.shutdown;
|
|
158
176
|
this.getContextUsageFn = contextActions.getContextUsage;
|
|
159
177
|
this.compactFn = contextActions.compact;
|
|
160
178
|
this.getSystemPromptFn = contextActions.getSystemPrompt;
|
|
179
|
+
if (contextActions.getSessionSignal) {
|
|
180
|
+
this.getSessionSignalFn = contextActions.getSessionSignal;
|
|
181
|
+
}
|
|
161
182
|
// Flush provider registrations queued during extension loading
|
|
162
183
|
for (const { name, config, extensionPath } of this.runtime.pendingProviderRegistrations) {
|
|
163
184
|
try {
|
|
@@ -178,10 +199,6 @@ export class ExtensionRunner {
|
|
|
178
199
|
}
|
|
179
200
|
}
|
|
180
201
|
this.runtime.pendingProviderRegistrations = [];
|
|
181
|
-
// Set registerChannel on the runtime. If this is the throwing stub (non-RPC mode),
|
|
182
|
-
// pending channel registrations remain queued until bindExtensions() provides the
|
|
183
|
-
// real implementation via flushPendingChannels().
|
|
184
|
-
this.runtime.registerChannel = actions.registerChannel;
|
|
185
202
|
// From this point on, provider registration/unregistration takes effect immediately
|
|
186
203
|
// without requiring a /reload.
|
|
187
204
|
this.runtime.registerProvider = (name, config) => {
|
|
@@ -216,51 +233,18 @@ export class ExtensionRunner {
|
|
|
216
233
|
this.switchSessionHandler = async () => ({ cancelled: false });
|
|
217
234
|
this.reloadHandler = async () => { };
|
|
218
235
|
}
|
|
219
|
-
/**
|
|
220
|
-
* Flush pending channel registrations with the real registerChannel implementation.
|
|
221
|
-
* Called from bindCore() and again from bindExtensions() when the real registerChannel
|
|
222
|
-
* becomes available (e.g. in RPC mode).
|
|
223
|
-
*/
|
|
224
|
-
flushPendingChannels(registerChannel) {
|
|
225
|
-
if (this.runtime.pendingChannelRegistrations.length === 0)
|
|
226
|
-
return;
|
|
227
|
-
for (const pending of this.runtime.pendingChannelRegistrations) {
|
|
228
|
-
try {
|
|
229
|
-
const channel = registerChannel(pending.name);
|
|
230
|
-
this.runtime.resolvedChannels.set(pending.name, channel);
|
|
231
|
-
pending.resolve(channel);
|
|
232
|
-
}
|
|
233
|
-
catch (err) {
|
|
234
|
-
pending.reject(err instanceof Error ? err : new Error(String(err)));
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
this.runtime.pendingChannelRegistrations = [];
|
|
238
|
-
this.runtime.registerChannel = registerChannel;
|
|
239
|
-
}
|
|
240
|
-
updateRegisterChannel(registerChannel) {
|
|
241
|
-
this.runtime.registerChannel = registerChannel;
|
|
242
|
-
}
|
|
243
236
|
setUIContext(uiContext) {
|
|
244
|
-
this.
|
|
245
|
-
this.uiContext = this.wrapUIForInterception(uiContext ?? noOpUIContext);
|
|
237
|
+
this.uiContext = uiContext ?? noOpUIContext;
|
|
246
238
|
}
|
|
247
239
|
getUIContext() {
|
|
248
240
|
return this.uiContext;
|
|
249
241
|
}
|
|
250
242
|
hasUI() {
|
|
251
|
-
return this.
|
|
243
|
+
return this.uiContext !== noOpUIContext;
|
|
252
244
|
}
|
|
253
245
|
getExtensionPaths() {
|
|
254
246
|
return this.extensions.map((e) => e.path);
|
|
255
247
|
}
|
|
256
|
-
getExtensionNameByPath(extensionPath) {
|
|
257
|
-
for (const ext of this.extensions) {
|
|
258
|
-
if (ext.path === extensionPath) {
|
|
259
|
-
return ext.name;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
return undefined;
|
|
263
|
-
}
|
|
264
248
|
/** Get all registered tools from all extensions (first registration per name wins). */
|
|
265
249
|
getAllRegisteredTools() {
|
|
266
250
|
const toolsByName = new Map();
|
|
@@ -333,7 +317,7 @@ export class ExtensionRunner {
|
|
|
333
317
|
getShortcutDiagnostics() {
|
|
334
318
|
return this.shortcutDiagnostics;
|
|
335
319
|
}
|
|
336
|
-
invalidate(message = "This extension
|
|
320
|
+
invalidate(message = "This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().") {
|
|
337
321
|
if (!this.staleMessage) {
|
|
338
322
|
this.staleMessage = message;
|
|
339
323
|
this.runtime.invalidate(message);
|
|
@@ -421,7 +405,7 @@ export class ExtensionRunner {
|
|
|
421
405
|
* Create an ExtensionContext for use in event handlers and tool execution.
|
|
422
406
|
* Context values are resolved at call time, so changes via bindCore/bindUI are reflected.
|
|
423
407
|
*/
|
|
424
|
-
createContext(
|
|
408
|
+
createContext() {
|
|
425
409
|
const runner = this;
|
|
426
410
|
const getModel = this.getModel;
|
|
427
411
|
return {
|
|
@@ -437,32 +421,6 @@ export class ExtensionRunner {
|
|
|
437
421
|
runner.assertActive();
|
|
438
422
|
return runner.cwd;
|
|
439
423
|
},
|
|
440
|
-
get extensionName() {
|
|
441
|
-
runner.assertActive();
|
|
442
|
-
return ext?.name ?? "unknown";
|
|
443
|
-
},
|
|
444
|
-
get projectRoot() {
|
|
445
|
-
runner.assertActive();
|
|
446
|
-
return resolveProjectRoot(runner.cwd);
|
|
447
|
-
},
|
|
448
|
-
get sessionDataDir() {
|
|
449
|
-
runner.assertActive();
|
|
450
|
-
const sessionDir = runner.sessionManager.getSessionDir();
|
|
451
|
-
const sessionId = runner.sessionManager.getSessionId();
|
|
452
|
-
return getSessionDataDir(sessionDir, sessionId, ext?.name ?? "unknown");
|
|
453
|
-
},
|
|
454
|
-
get projectDataDir() {
|
|
455
|
-
runner.assertActive();
|
|
456
|
-
return getProjectDataDir(resolveProjectRoot(runner.cwd), ext?.name ?? "unknown");
|
|
457
|
-
},
|
|
458
|
-
get cwdDataDir() {
|
|
459
|
-
runner.assertActive();
|
|
460
|
-
return getCwdDataDir(runner.cwd, ext?.name ?? "unknown");
|
|
461
|
-
},
|
|
462
|
-
get globalDataDir() {
|
|
463
|
-
runner.assertActive();
|
|
464
|
-
return getGlobalDataDir(ext?.name ?? "unknown");
|
|
465
|
-
},
|
|
466
424
|
get sessionManager() {
|
|
467
425
|
runner.assertActive();
|
|
468
426
|
return runner.sessionManager;
|
|
@@ -483,10 +441,6 @@ export class ExtensionRunner {
|
|
|
483
441
|
runner.assertActive();
|
|
484
442
|
return runner.getSignalFn();
|
|
485
443
|
},
|
|
486
|
-
get sessionSignal() {
|
|
487
|
-
runner.assertActive();
|
|
488
|
-
return runner.getSessionSignalFn();
|
|
489
|
-
},
|
|
490
444
|
abort: () => {
|
|
491
445
|
runner.assertActive();
|
|
492
446
|
runner.abortFn();
|
|
@@ -511,23 +465,49 @@ export class ExtensionRunner {
|
|
|
511
465
|
runner.assertActive();
|
|
512
466
|
return runner.getSystemPromptFn();
|
|
513
467
|
},
|
|
514
|
-
|
|
468
|
+
get extensionName() {
|
|
469
|
+
runner.assertActive();
|
|
470
|
+
return runner.getExtensionNameFn();
|
|
471
|
+
},
|
|
472
|
+
get projectRoot() {
|
|
473
|
+
runner.assertActive();
|
|
474
|
+
return runner.getProjectRootFn();
|
|
475
|
+
},
|
|
476
|
+
get sessionDataDir() {
|
|
477
|
+
runner.assertActive();
|
|
478
|
+
return runner.getSessionDataDirFn();
|
|
479
|
+
},
|
|
480
|
+
get projectDataDir() {
|
|
481
|
+
runner.assertActive();
|
|
482
|
+
return runner.getProjectDataDirFn();
|
|
483
|
+
},
|
|
484
|
+
get cwdDataDir() {
|
|
515
485
|
runner.assertActive();
|
|
516
|
-
runner.
|
|
486
|
+
return runner.getCwdDataDirFn();
|
|
487
|
+
},
|
|
488
|
+
get globalDataDir() {
|
|
489
|
+
runner.assertActive();
|
|
490
|
+
return runner.getGlobalDataDirFn();
|
|
491
|
+
},
|
|
492
|
+
get sessionSignal() {
|
|
493
|
+
runner.assertActive();
|
|
494
|
+
return runner.getSessionSignalFn();
|
|
495
|
+
},
|
|
496
|
+
respondUI(id, result) {
|
|
497
|
+
runner.assertActive();
|
|
498
|
+
runner.respondUIFn(id, result);
|
|
499
|
+
},
|
|
500
|
+
get fileSnapshotManager() {
|
|
501
|
+
runner.assertActive();
|
|
502
|
+
return runner._fileSnapshotManager;
|
|
517
503
|
},
|
|
518
504
|
};
|
|
519
505
|
}
|
|
520
|
-
createCommandContext(
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
cmdExt = ext;
|
|
526
|
-
break;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
const context = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext(cmdExt)));
|
|
506
|
+
createCommandContext() {
|
|
507
|
+
// Use property descriptors instead of object spread so the guarded getters from
|
|
508
|
+
// createContext() stay lazy. A spread would eagerly read them once and freeze the
|
|
509
|
+
// old values into the returned object, bypassing stale-instance checks.
|
|
510
|
+
const context = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext()));
|
|
531
511
|
context.waitForIdle = () => {
|
|
532
512
|
this.assertActive();
|
|
533
513
|
return this.waitForIdleFn();
|
|
@@ -561,12 +541,12 @@ export class ExtensionRunner {
|
|
|
561
541
|
event.type === "session_before_tree");
|
|
562
542
|
}
|
|
563
543
|
async emit(event) {
|
|
544
|
+
const ctx = this.createContext();
|
|
564
545
|
let result;
|
|
565
546
|
for (const ext of this.extensions) {
|
|
566
547
|
const handlers = ext.handlers.get(event.type);
|
|
567
548
|
if (!handlers || handlers.length === 0)
|
|
568
549
|
continue;
|
|
569
|
-
const ctx = this.createContext(ext);
|
|
570
550
|
for (const handler of handlers) {
|
|
571
551
|
try {
|
|
572
552
|
const handlerResult = await handler(event, ctx);
|
|
@@ -591,14 +571,53 @@ export class ExtensionRunner {
|
|
|
591
571
|
}
|
|
592
572
|
return result;
|
|
593
573
|
}
|
|
574
|
+
async emitMessageEnd(event) {
|
|
575
|
+
const ctx = this.createContext();
|
|
576
|
+
let currentMessage = event.message;
|
|
577
|
+
let modified = false;
|
|
578
|
+
for (const ext of this.extensions) {
|
|
579
|
+
const handlers = ext.handlers.get("message_end");
|
|
580
|
+
if (!handlers || handlers.length === 0)
|
|
581
|
+
continue;
|
|
582
|
+
for (const handler of handlers) {
|
|
583
|
+
try {
|
|
584
|
+
const currentEvent = { ...event, message: currentMessage };
|
|
585
|
+
const handlerResult = (await handler(currentEvent, ctx));
|
|
586
|
+
if (!handlerResult?.message)
|
|
587
|
+
continue;
|
|
588
|
+
if (handlerResult.message.role !== currentMessage.role) {
|
|
589
|
+
this.emitError({
|
|
590
|
+
extensionPath: ext.path,
|
|
591
|
+
event: "message_end",
|
|
592
|
+
error: "message_end handlers must return a message with the same role",
|
|
593
|
+
});
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
currentMessage = handlerResult.message;
|
|
597
|
+
modified = true;
|
|
598
|
+
}
|
|
599
|
+
catch (err) {
|
|
600
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
601
|
+
const stack = err instanceof Error ? err.stack : undefined;
|
|
602
|
+
this.emitError({
|
|
603
|
+
extensionPath: ext.path,
|
|
604
|
+
event: "message_end",
|
|
605
|
+
error: message,
|
|
606
|
+
stack,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return modified ? currentMessage : undefined;
|
|
612
|
+
}
|
|
594
613
|
async emitToolResult(event) {
|
|
614
|
+
const ctx = this.createContext();
|
|
595
615
|
const currentEvent = { ...event };
|
|
596
616
|
let modified = false;
|
|
597
617
|
for (const ext of this.extensions) {
|
|
598
618
|
const handlers = ext.handlers.get("tool_result");
|
|
599
619
|
if (!handlers || handlers.length === 0)
|
|
600
620
|
continue;
|
|
601
|
-
const ctx = this.createContext(ext);
|
|
602
621
|
for (const handler of handlers) {
|
|
603
622
|
try {
|
|
604
623
|
const handlerResult = (await handler(currentEvent, ctx));
|
|
@@ -639,12 +658,12 @@ export class ExtensionRunner {
|
|
|
639
658
|
};
|
|
640
659
|
}
|
|
641
660
|
async emitToolCall(event) {
|
|
661
|
+
const ctx = this.createContext();
|
|
642
662
|
let result;
|
|
643
663
|
for (const ext of this.extensions) {
|
|
644
664
|
const handlers = ext.handlers.get("tool_call");
|
|
645
665
|
if (!handlers || handlers.length === 0)
|
|
646
666
|
continue;
|
|
647
|
-
const ctx = this.createContext(ext);
|
|
648
667
|
for (const handler of handlers) {
|
|
649
668
|
const handlerResult = await handler(event, ctx);
|
|
650
669
|
if (handlerResult) {
|
|
@@ -658,11 +677,11 @@ export class ExtensionRunner {
|
|
|
658
677
|
return result;
|
|
659
678
|
}
|
|
660
679
|
async emitUserBash(event) {
|
|
680
|
+
const ctx = this.createContext();
|
|
661
681
|
for (const ext of this.extensions) {
|
|
662
682
|
const handlers = ext.handlers.get("user_bash");
|
|
663
683
|
if (!handlers || handlers.length === 0)
|
|
664
684
|
continue;
|
|
665
|
-
const ctx = this.createContext(ext);
|
|
666
685
|
for (const handler of handlers) {
|
|
667
686
|
try {
|
|
668
687
|
const handlerResult = await handler(event, ctx);
|
|
@@ -684,157 +703,13 @@ export class ExtensionRunner {
|
|
|
684
703
|
}
|
|
685
704
|
return undefined;
|
|
686
705
|
}
|
|
687
|
-
createAsyncUIPromise(id, extract) {
|
|
688
|
-
if (!this.hasHandlers("ui"))
|
|
689
|
-
return undefined;
|
|
690
|
-
return new Promise((resolve) => {
|
|
691
|
-
this.pendingUIResponses.set(id, (result) => {
|
|
692
|
-
this.pendingUIResponses.delete(id);
|
|
693
|
-
resolve(extract(result));
|
|
694
|
-
});
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
wrapUIForInterception(original) {
|
|
698
|
-
return {
|
|
699
|
-
...original,
|
|
700
|
-
confirm: async (title, message, opts) => {
|
|
701
|
-
if (!this.hasHandlers("ui"))
|
|
702
|
-
return original.confirm(title, message, opts);
|
|
703
|
-
const id = randomUUID();
|
|
704
|
-
const asyncPromise = this.createAsyncUIPromise(id, (r) => r?.action === "responded" && r.confirmed !== undefined ? r.confirmed : false);
|
|
705
|
-
const result = await this.emitUIEvent({
|
|
706
|
-
type: "ui",
|
|
707
|
-
id,
|
|
708
|
-
method: "confirm",
|
|
709
|
-
title,
|
|
710
|
-
message,
|
|
711
|
-
signal: opts?.signal,
|
|
712
|
-
timeout: opts?.timeout,
|
|
713
|
-
});
|
|
714
|
-
if (result?.action === "responded" && result.confirmed !== undefined) {
|
|
715
|
-
this.pendingUIResponses.delete(id);
|
|
716
|
-
return result.confirmed;
|
|
717
|
-
}
|
|
718
|
-
return Promise.race([original.confirm(title, message, opts), asyncPromise]);
|
|
719
|
-
},
|
|
720
|
-
select: async (title, options, opts) => {
|
|
721
|
-
if (!this.hasHandlers("ui"))
|
|
722
|
-
return original.select(title, options, opts);
|
|
723
|
-
const id = randomUUID();
|
|
724
|
-
const multiple = opts?.multiple;
|
|
725
|
-
const asyncPromise = this.createAsyncUIPromise(id, (r) => r?.action === "responded" ? r.value : undefined);
|
|
726
|
-
const result = await this.emitUIEvent({
|
|
727
|
-
type: "ui",
|
|
728
|
-
id,
|
|
729
|
-
method: "select",
|
|
730
|
-
title,
|
|
731
|
-
options,
|
|
732
|
-
multiple,
|
|
733
|
-
signal: opts?.signal,
|
|
734
|
-
timeout: opts?.timeout,
|
|
735
|
-
});
|
|
736
|
-
if (result?.action === "responded") {
|
|
737
|
-
this.pendingUIResponses.delete(id);
|
|
738
|
-
if (multiple && result.value !== undefined) {
|
|
739
|
-
return Array.isArray(result.value) ? result.value : [result.value];
|
|
740
|
-
}
|
|
741
|
-
return result.value;
|
|
742
|
-
}
|
|
743
|
-
return Promise.race([original.select(title, options, opts), asyncPromise]);
|
|
744
|
-
},
|
|
745
|
-
input: async (title, placeholder, opts) => {
|
|
746
|
-
if (!this.hasHandlers("ui"))
|
|
747
|
-
return original.input(title, placeholder, opts);
|
|
748
|
-
const id = randomUUID();
|
|
749
|
-
const asyncPromise = this.createAsyncUIPromise(id, (r) => r?.action === "responded" ? r.value : undefined);
|
|
750
|
-
const result = await this.emitUIEvent({
|
|
751
|
-
type: "ui",
|
|
752
|
-
id,
|
|
753
|
-
method: "input",
|
|
754
|
-
title,
|
|
755
|
-
placeholder,
|
|
756
|
-
signal: opts?.signal,
|
|
757
|
-
timeout: opts?.timeout,
|
|
758
|
-
});
|
|
759
|
-
if (result?.action === "responded") {
|
|
760
|
-
this.pendingUIResponses.delete(id);
|
|
761
|
-
return result.value;
|
|
762
|
-
}
|
|
763
|
-
return Promise.race([original.input(title, placeholder, opts), asyncPromise]);
|
|
764
|
-
},
|
|
765
|
-
editor: async (title, prefill) => {
|
|
766
|
-
if (!this.hasHandlers("ui"))
|
|
767
|
-
return original.editor(title, prefill);
|
|
768
|
-
const id = randomUUID();
|
|
769
|
-
const asyncPromise = this.createAsyncUIPromise(id, (r) => r?.action === "responded" ? r.value : undefined);
|
|
770
|
-
const result = await this.emitUIEvent({
|
|
771
|
-
type: "ui",
|
|
772
|
-
id,
|
|
773
|
-
method: "editor",
|
|
774
|
-
title,
|
|
775
|
-
prefill,
|
|
776
|
-
});
|
|
777
|
-
if (result?.action === "responded") {
|
|
778
|
-
this.pendingUIResponses.delete(id);
|
|
779
|
-
return result.value;
|
|
780
|
-
}
|
|
781
|
-
return Promise.race([original.editor(title, prefill), asyncPromise]);
|
|
782
|
-
},
|
|
783
|
-
notify: (message, notifyType) => {
|
|
784
|
-
if (this.hasHandlers("ui")) {
|
|
785
|
-
this.emitUIEvent({
|
|
786
|
-
type: "ui",
|
|
787
|
-
id: randomUUID(),
|
|
788
|
-
method: "notify",
|
|
789
|
-
title: message,
|
|
790
|
-
message,
|
|
791
|
-
notifyType,
|
|
792
|
-
}).catch(() => { });
|
|
793
|
-
}
|
|
794
|
-
return original.notify(message, notifyType);
|
|
795
|
-
},
|
|
796
|
-
};
|
|
797
|
-
}
|
|
798
|
-
async emitUIEvent(event) {
|
|
799
|
-
for (const ext of this.extensions) {
|
|
800
|
-
const ctx = this.createContext(ext);
|
|
801
|
-
for (const handler of ext.handlers.get("ui") ?? []) {
|
|
802
|
-
try {
|
|
803
|
-
const result = (await handler(event, ctx));
|
|
804
|
-
if (result?.action === "responded")
|
|
805
|
-
return result;
|
|
806
|
-
}
|
|
807
|
-
catch (err) {
|
|
808
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
809
|
-
const stack = err instanceof Error ? err.stack : undefined;
|
|
810
|
-
this.emitError({
|
|
811
|
-
extensionPath: ext.path,
|
|
812
|
-
event: "ui",
|
|
813
|
-
error: message,
|
|
814
|
-
stack,
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
return undefined;
|
|
820
|
-
}
|
|
821
|
-
async emitUI(event) {
|
|
822
|
-
return this.emitUIEvent(event);
|
|
823
|
-
}
|
|
824
|
-
respondUI(id, result) {
|
|
825
|
-
const resolve = this.pendingUIResponses.get(id);
|
|
826
|
-
if (resolve) {
|
|
827
|
-
this.pendingUIResponses.delete(id);
|
|
828
|
-
resolve(result);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
706
|
async emitContext(messages) {
|
|
707
|
+
const ctx = this.createContext();
|
|
832
708
|
let currentMessages = structuredClone(messages);
|
|
833
709
|
for (const ext of this.extensions) {
|
|
834
710
|
const handlers = ext.handlers.get("context");
|
|
835
711
|
if (!handlers || handlers.length === 0)
|
|
836
712
|
continue;
|
|
837
|
-
const ctx = this.createContext(ext);
|
|
838
713
|
for (const handler of handlers) {
|
|
839
714
|
try {
|
|
840
715
|
const event = { type: "context", messages: currentMessages };
|
|
@@ -858,12 +733,12 @@ export class ExtensionRunner {
|
|
|
858
733
|
return currentMessages;
|
|
859
734
|
}
|
|
860
735
|
async emitBeforeProviderRequest(payload) {
|
|
736
|
+
const ctx = this.createContext();
|
|
861
737
|
let currentPayload = payload;
|
|
862
738
|
for (const ext of this.extensions) {
|
|
863
739
|
const handlers = ext.handlers.get("before_provider_request");
|
|
864
740
|
if (!handlers || handlers.length === 0)
|
|
865
741
|
continue;
|
|
866
|
-
const ctx = this.createContext(ext);
|
|
867
742
|
for (const handler of handlers) {
|
|
868
743
|
try {
|
|
869
744
|
const event = {
|
|
@@ -891,17 +766,17 @@ export class ExtensionRunner {
|
|
|
891
766
|
}
|
|
892
767
|
async emitBeforeAgentStart(prompt, images, systemPrompt, systemPromptOptions) {
|
|
893
768
|
let currentSystemPrompt = systemPrompt;
|
|
769
|
+
const ctx = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext()));
|
|
770
|
+
ctx.getSystemPrompt = () => {
|
|
771
|
+
this.assertActive();
|
|
772
|
+
return currentSystemPrompt;
|
|
773
|
+
};
|
|
894
774
|
const messages = [];
|
|
895
775
|
let systemPromptModified = false;
|
|
896
776
|
for (const ext of this.extensions) {
|
|
897
777
|
const handlers = ext.handlers.get("before_agent_start");
|
|
898
778
|
if (!handlers || handlers.length === 0)
|
|
899
779
|
continue;
|
|
900
|
-
const ctx = Object.defineProperties({}, Object.getOwnPropertyDescriptors(this.createContext(ext)));
|
|
901
|
-
ctx.getSystemPrompt = () => {
|
|
902
|
-
this.assertActive();
|
|
903
|
-
return currentSystemPrompt;
|
|
904
|
-
};
|
|
905
780
|
for (const handler of handlers) {
|
|
906
781
|
try {
|
|
907
782
|
const event = {
|
|
@@ -944,6 +819,7 @@ export class ExtensionRunner {
|
|
|
944
819
|
return undefined;
|
|
945
820
|
}
|
|
946
821
|
async emitResourcesDiscover(cwd, reason) {
|
|
822
|
+
const ctx = this.createContext();
|
|
947
823
|
const skillPaths = [];
|
|
948
824
|
const promptPaths = [];
|
|
949
825
|
const themePaths = [];
|
|
@@ -951,7 +827,6 @@ export class ExtensionRunner {
|
|
|
951
827
|
const handlers = ext.handlers.get("resources_discover");
|
|
952
828
|
if (!handlers || handlers.length === 0)
|
|
953
829
|
continue;
|
|
954
|
-
const ctx = this.createContext(ext);
|
|
955
830
|
for (const handler of handlers) {
|
|
956
831
|
try {
|
|
957
832
|
const event = { type: "resources_discover", cwd, reason };
|
|
@@ -983,10 +858,10 @@ export class ExtensionRunner {
|
|
|
983
858
|
}
|
|
984
859
|
/** Emit input event. Transforms chain, "handled" short-circuits. */
|
|
985
860
|
async emitInput(text, images, source) {
|
|
861
|
+
const ctx = this.createContext();
|
|
986
862
|
let currentText = text;
|
|
987
863
|
let currentImages = images;
|
|
988
864
|
for (const ext of this.extensions) {
|
|
989
|
-
const ctx = this.createContext(ext);
|
|
990
865
|
for (const handler of ext.handlers.get("input") ?? []) {
|
|
991
866
|
try {
|
|
992
867
|
const event = { type: "input", text: currentText, images: currentImages, source };
|