@mariozechner/pi-coding-agent 0.34.2 → 0.35.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 +204 -0
- package/README.md +233 -105
- package/dist/cli/args.d.ts +3 -4
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +13 -18
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +39 -50
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +166 -197
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -3
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +6 -5
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/extensions/index.d.ts +10 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +21 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +400 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +88 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/{hooks → extensions}/runner.js +52 -141
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +461 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/{hooks → extensions}/types.js +7 -4
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +25 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/{hooks/tool-wrapper.js → extensions/wrapper.js} +39 -24
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/messages.d.ts +7 -7
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +4 -4
- package/dist/core/messages.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +40 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/{slash-commands.js → prompt-templates.js} +31 -31
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/sdk.d.ts +29 -52
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +111 -211
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -17
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +25 -10
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +4 -11
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +4 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -6
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +36 -33
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +7 -2
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +93 -4
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -2
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +4 -4
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +18 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/{hook-message.js → custom-message.js} +3 -3
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +2 -2
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +2 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/{hook-editor.d.ts → extension-editor.d.ts} +3 -3
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/{hook-editor.js → extension-editor.js} +4 -4
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/{hook-input.d.ts → extension-input.d.ts} +3 -3
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/{hook-input.js → extension-input.js} +3 -3
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/{hook-selector.d.ts → extension-selector.d.ts} +3 -3
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/{hook-selector.js → extension-selector.js} +3 -3
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +3 -3
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +3 -3
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +9 -9
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +37 -44
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +143 -189
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +10 -33
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -3
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -3
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +33 -57
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +16 -16
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/extensions.md +1053 -0
- package/docs/rpc.md +4 -4
- package/docs/sdk.md +62 -93
- package/docs/session.md +22 -19
- package/docs/skills.md +1 -1
- package/docs/tui.md +1 -1
- package/examples/README.md +9 -15
- package/examples/extensions/README.md +141 -0
- package/examples/{hooks → extensions}/auto-commit-on-exit.ts +3 -3
- package/examples/extensions/chalk-logger.ts +26 -0
- package/examples/{hooks → extensions}/confirm-destructive.ts +3 -3
- package/examples/{hooks → extensions}/custom-compaction.ts +6 -6
- package/examples/{hooks → extensions}/dirty-repo-guard.ts +8 -4
- package/examples/{hooks → extensions}/file-trigger.ts +3 -3
- package/examples/{hooks → extensions}/git-checkpoint.ts +3 -3
- package/examples/{hooks → extensions}/handoff.ts +3 -3
- package/examples/extensions/hello.ts +25 -0
- package/examples/{hooks → extensions}/permission-gate.ts +3 -3
- package/examples/{hooks → extensions}/pirate.ts +5 -5
- package/examples/{hooks → extensions}/plan-mode.ts +6 -6
- package/examples/{hooks → extensions}/protected-paths.ts +3 -3
- package/examples/{hooks → extensions}/qna.ts +3 -3
- package/examples/{custom-tools/question/index.ts → extensions/question.ts} +13 -17
- package/examples/{hooks → extensions}/snake.ts +3 -3
- package/examples/{hooks → extensions}/status-line.ts +3 -3
- package/examples/{custom-tools → extensions}/subagent/README.md +15 -15
- package/examples/{custom-tools → extensions}/subagent/index.ts +22 -43
- package/examples/{custom-tools/todo/index.ts → extensions/todo.ts} +122 -39
- package/examples/{hooks → extensions}/tools.ts +5 -5
- package/examples/extensions/with-deps/index.ts +40 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +16 -0
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/05-tools.ts +7 -41
- package/examples/sdk/06-extensions.ts +81 -0
- package/examples/sdk/08-prompt-templates.ts +42 -0
- package/examples/sdk/12-full-control.ts +10 -29
- package/examples/sdk/README.md +5 -5
- package/package.json +4 -4
- package/dist/core/custom-tools/index.d.ts +0 -7
- package/dist/core/custom-tools/index.d.ts.map +0 -1
- package/dist/core/custom-tools/index.js +0 -6
- package/dist/core/custom-tools/index.js.map +0 -1
- package/dist/core/custom-tools/loader.d.ts +0 -30
- package/dist/core/custom-tools/loader.d.ts.map +0 -1
- package/dist/core/custom-tools/loader.js +0 -276
- package/dist/core/custom-tools/loader.js.map +0 -1
- package/dist/core/custom-tools/types.d.ts +0 -144
- package/dist/core/custom-tools/types.d.ts.map +0 -1
- package/dist/core/custom-tools/types.js +0 -8
- package/dist/core/custom-tools/types.js.map +0 -1
- package/dist/core/custom-tools/wrapper.d.ts +0 -15
- package/dist/core/custom-tools/wrapper.d.ts.map +0 -1
- package/dist/core/custom-tools/wrapper.js +0 -23
- package/dist/core/custom-tools/wrapper.js.map +0 -1
- package/dist/core/hooks/index.d.ts +0 -6
- package/dist/core/hooks/index.d.ts.map +0 -1
- package/dist/core/hooks/index.js +0 -6
- package/dist/core/hooks/index.js.map +0 -1
- package/dist/core/hooks/loader.d.ts +0 -146
- package/dist/core/hooks/loader.d.ts.map +0 -1
- package/dist/core/hooks/loader.js +0 -275
- package/dist/core/hooks/loader.js.map +0 -1
- package/dist/core/hooks/runner.d.ts +0 -173
- package/dist/core/hooks/runner.d.ts.map +0 -1
- package/dist/core/hooks/runner.js.map +0 -1
- package/dist/core/hooks/tool-wrapper.d.ts +0 -17
- package/dist/core/hooks/tool-wrapper.d.ts.map +0 -1
- package/dist/core/hooks/tool-wrapper.js.map +0 -1
- package/dist/core/hooks/types.d.ts +0 -767
- package/dist/core/hooks/types.d.ts.map +0 -1
- package/dist/core/hooks/types.js.map +0 -1
- package/dist/core/slash-commands.d.ts +0 -40
- package/dist/core/slash-commands.d.ts.map +0 -1
- package/dist/core/slash-commands.js.map +0 -1
- package/dist/modes/interactive/components/hook-editor.d.ts.map +0 -1
- package/dist/modes/interactive/components/hook-editor.js.map +0 -1
- package/dist/modes/interactive/components/hook-input.d.ts.map +0 -1
- package/dist/modes/interactive/components/hook-input.js.map +0 -1
- package/dist/modes/interactive/components/hook-message.d.ts +0 -18
- package/dist/modes/interactive/components/hook-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/hook-message.js.map +0 -1
- package/dist/modes/interactive/components/hook-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/hook-selector.js.map +0 -1
- package/docs/custom-tools.md +0 -514
- package/docs/extension-loading.md +0 -1004
- package/docs/hooks.md +0 -979
- package/docs/session-tree-plan.md +0 -441
- package/examples/custom-tools/README.md +0 -114
- package/examples/custom-tools/hello/index.ts +0 -21
- package/examples/hooks/README.md +0 -60
- package/examples/hooks/todo/index.ts +0 -134
- package/examples/sdk/06-hooks.ts +0 -61
- package/examples/sdk/08-slash-commands.ts +0 -42
- /package/examples/{custom-tools → extensions}/subagent/agents/planner.md +0 -0
- /package/examples/{custom-tools → extensions}/subagent/agents/reviewer.md +0 -0
- /package/examples/{custom-tools → extensions}/subagent/agents/scout.md +0 -0
- /package/examples/{custom-tools → extensions}/subagent/agents/worker.md +0 -0
- /package/examples/{custom-tools → extensions}/subagent/agents.ts +0 -0
- /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/implement-and-review.md +0 -0
- /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/implement.md +0 -0
- /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/scout-and-plan.md +0 -0
package/dist/core/sdk.js
CHANGED
|
@@ -9,20 +9,11 @@
|
|
|
9
9
|
* // Minimal - everything auto-discovered
|
|
10
10
|
* const session = await createAgentSession();
|
|
11
11
|
*
|
|
12
|
-
* // With custom hooks
|
|
13
|
-
* const session = await createAgentSession({
|
|
14
|
-
* hooks: [
|
|
15
|
-
* ...await discoverHooks(),
|
|
16
|
-
* { factory: myHookFactory },
|
|
17
|
-
* ],
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
12
|
* // Full control
|
|
21
13
|
* const session = await createAgentSession({
|
|
22
14
|
* model: myModel,
|
|
23
15
|
* getApiKey: async () => process.env.MY_KEY,
|
|
24
16
|
* tools: [readTool, bashTool],
|
|
25
|
-
* hooks: [],
|
|
26
17
|
* skills: [],
|
|
27
18
|
* sessionFile: false,
|
|
28
19
|
* });
|
|
@@ -33,14 +24,14 @@ import { join } from "path";
|
|
|
33
24
|
import { getAgentDir } from "../config.js";
|
|
34
25
|
import { AgentSession } from "./agent-session.js";
|
|
35
26
|
import { AuthStorage } from "./auth-storage.js";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
27
|
+
import { createEventBus } from "./event-bus.js";
|
|
28
|
+
import { discoverAndLoadExtensions, ExtensionRunner, loadExtensionFromFactory, wrapRegisteredTools, wrapToolsWithExtensions, } from "./extensions/index.js";
|
|
38
29
|
import { convertToLlm } from "./messages.js";
|
|
39
30
|
import { ModelRegistry } from "./model-registry.js";
|
|
31
|
+
import { loadPromptTemplates as loadPromptTemplatesInternal } from "./prompt-templates.js";
|
|
40
32
|
import { SessionManager } from "./session-manager.js";
|
|
41
33
|
import { SettingsManager } from "./settings-manager.js";
|
|
42
34
|
import { loadSkills as loadSkillsInternal } from "./skills.js";
|
|
43
|
-
import { loadSlashCommands as loadSlashCommandsInternal } from "./slash-commands.js";
|
|
44
35
|
import { buildSystemPrompt as buildSystemPromptInternal, loadProjectContextFiles as loadContextFilesInternal, } from "./system-prompt.js";
|
|
45
36
|
import { time } from "./timings.js";
|
|
46
37
|
import { allTools, bashTool, codingTools, createAllTools, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, editTool, findTool, grepTool, lsTool, readOnlyTools, readTool, writeTool, } from "./tools/index.js";
|
|
@@ -67,36 +58,20 @@ export function discoverModels(authStorage, agentDir = getDefaultAgentDir()) {
|
|
|
67
58
|
return new ModelRegistry(authStorage, join(agentDir, "models.json"));
|
|
68
59
|
}
|
|
69
60
|
/**
|
|
70
|
-
* Discover
|
|
61
|
+
* Discover extensions from cwd and agentDir.
|
|
62
|
+
* @param eventBus - Shared event bus for extension communication. Pass to createAgentSession too.
|
|
63
|
+
* @param cwd - Current working directory
|
|
64
|
+
* @param agentDir - Agent configuration directory
|
|
71
65
|
*/
|
|
72
|
-
export async function
|
|
66
|
+
export async function discoverExtensions(eventBus, cwd, agentDir) {
|
|
73
67
|
const resolvedCwd = cwd ?? process.cwd();
|
|
74
68
|
const resolvedAgentDir = agentDir ?? getDefaultAgentDir();
|
|
75
|
-
const
|
|
69
|
+
const result = await discoverAndLoadExtensions([], resolvedCwd, resolvedAgentDir, eventBus);
|
|
76
70
|
// Log errors but don't fail
|
|
77
|
-
for (const { path, error } of errors) {
|
|
78
|
-
console.error(`Failed to load
|
|
71
|
+
for (const { path, error } of result.errors) {
|
|
72
|
+
console.error(`Failed to load extension "${path}": ${error}`);
|
|
79
73
|
}
|
|
80
|
-
return
|
|
81
|
-
path: h.path,
|
|
82
|
-
factory: createFactoryFromLoadedHook(h),
|
|
83
|
-
}));
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Discover custom tools from cwd and agentDir.
|
|
87
|
-
*/
|
|
88
|
-
export async function discoverCustomTools(cwd, agentDir) {
|
|
89
|
-
const resolvedCwd = cwd ?? process.cwd();
|
|
90
|
-
const resolvedAgentDir = agentDir ?? getDefaultAgentDir();
|
|
91
|
-
const { tools, errors } = await discoverAndLoadCustomTools([], resolvedCwd, Object.keys(allTools), resolvedAgentDir);
|
|
92
|
-
// Log errors but don't fail
|
|
93
|
-
for (const { path, error } of errors) {
|
|
94
|
-
console.error(`Failed to load custom tool "${path}": ${error}`);
|
|
95
|
-
}
|
|
96
|
-
return tools.map((t) => ({
|
|
97
|
-
path: t.path,
|
|
98
|
-
tool: t.tool,
|
|
99
|
-
}));
|
|
74
|
+
return result;
|
|
100
75
|
}
|
|
101
76
|
/**
|
|
102
77
|
* Discover skills from cwd and agentDir.
|
|
@@ -119,10 +94,10 @@ export function discoverContextFiles(cwd, agentDir) {
|
|
|
119
94
|
});
|
|
120
95
|
}
|
|
121
96
|
/**
|
|
122
|
-
* Discover
|
|
97
|
+
* Discover prompt templates from cwd and agentDir.
|
|
123
98
|
*/
|
|
124
|
-
export function
|
|
125
|
-
return
|
|
99
|
+
export function discoverPromptTemplates(cwd, agentDir) {
|
|
100
|
+
return loadPromptTemplatesInternal({
|
|
126
101
|
cwd: cwd ?? process.cwd(),
|
|
127
102
|
agentDir: agentDir ?? getDefaultAgentDir(),
|
|
128
103
|
});
|
|
@@ -156,123 +131,11 @@ export function loadSettings(cwd, agentDir) {
|
|
|
156
131
|
hideThinkingBlock: manager.getHideThinkingBlock(),
|
|
157
132
|
shellPath: manager.getShellPath(),
|
|
158
133
|
collapseChangelog: manager.getCollapseChangelog(),
|
|
159
|
-
|
|
160
|
-
customTools: manager.getCustomToolPaths(),
|
|
134
|
+
extensions: manager.getExtensionPaths(),
|
|
161
135
|
skills: manager.getSkillsSettings(),
|
|
162
136
|
terminal: { showImages: manager.getShowImages() },
|
|
163
137
|
};
|
|
164
138
|
}
|
|
165
|
-
// Internal Helpers
|
|
166
|
-
/**
|
|
167
|
-
* Create a HookFactory from a LoadedHook.
|
|
168
|
-
* This allows mixing discovered hooks with inline hooks.
|
|
169
|
-
*/
|
|
170
|
-
function createFactoryFromLoadedHook(loaded) {
|
|
171
|
-
return (api) => {
|
|
172
|
-
for (const [eventType, handlers] of loaded.handlers) {
|
|
173
|
-
for (const handler of handlers) {
|
|
174
|
-
api.on(eventType, handler);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Convert hook definitions to LoadedHooks for the HookRunner.
|
|
181
|
-
*/
|
|
182
|
-
function createLoadedHooksFromDefinitions(definitions) {
|
|
183
|
-
return definitions.map((def) => {
|
|
184
|
-
const hookPath = def.path ?? "<inline>";
|
|
185
|
-
const handlers = new Map();
|
|
186
|
-
const messageRenderers = new Map();
|
|
187
|
-
const commands = new Map();
|
|
188
|
-
const flags = new Map();
|
|
189
|
-
const flagValues = new Map();
|
|
190
|
-
const shortcuts = new Map();
|
|
191
|
-
let sendMessageHandler = () => { };
|
|
192
|
-
let appendEntryHandler = () => { };
|
|
193
|
-
let getActiveToolsHandler = () => [];
|
|
194
|
-
let getAllToolsHandler = () => [];
|
|
195
|
-
let setActiveToolsHandler = () => { };
|
|
196
|
-
let newSessionHandler = async () => ({ cancelled: false });
|
|
197
|
-
let branchHandler = async () => ({ cancelled: false });
|
|
198
|
-
let navigateTreeHandler = async () => ({
|
|
199
|
-
cancelled: false,
|
|
200
|
-
});
|
|
201
|
-
const api = {
|
|
202
|
-
on: (event, handler) => {
|
|
203
|
-
const list = handlers.get(event) ?? [];
|
|
204
|
-
list.push(handler);
|
|
205
|
-
handlers.set(event, list);
|
|
206
|
-
},
|
|
207
|
-
sendMessage: (message, options) => {
|
|
208
|
-
sendMessageHandler(message, options);
|
|
209
|
-
},
|
|
210
|
-
appendEntry: (customType, data) => {
|
|
211
|
-
appendEntryHandler(customType, data);
|
|
212
|
-
},
|
|
213
|
-
registerMessageRenderer: (customType, renderer) => {
|
|
214
|
-
messageRenderers.set(customType, renderer);
|
|
215
|
-
},
|
|
216
|
-
registerCommand: (name, options) => {
|
|
217
|
-
commands.set(name, { name, ...options });
|
|
218
|
-
},
|
|
219
|
-
registerFlag: (name, options) => {
|
|
220
|
-
flags.set(name, { name, hookPath, ...options });
|
|
221
|
-
if (options.default !== undefined) {
|
|
222
|
-
flagValues.set(name, options.default);
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
getFlag: (name) => flagValues.get(name),
|
|
226
|
-
registerShortcut: (shortcut, options) => {
|
|
227
|
-
shortcuts.set(shortcut, { shortcut, hookPath, ...options });
|
|
228
|
-
},
|
|
229
|
-
newSession: (options) => newSessionHandler(options),
|
|
230
|
-
branch: (entryId) => branchHandler(entryId),
|
|
231
|
-
navigateTree: (targetId, options) => navigateTreeHandler(targetId, options),
|
|
232
|
-
getActiveTools: () => getActiveToolsHandler(),
|
|
233
|
-
getAllTools: () => getAllToolsHandler(),
|
|
234
|
-
setActiveTools: (toolNames) => setActiveToolsHandler(toolNames),
|
|
235
|
-
};
|
|
236
|
-
def.factory(api);
|
|
237
|
-
return {
|
|
238
|
-
path: hookPath,
|
|
239
|
-
resolvedPath: hookPath,
|
|
240
|
-
handlers,
|
|
241
|
-
messageRenderers,
|
|
242
|
-
commands,
|
|
243
|
-
flags,
|
|
244
|
-
flagValues,
|
|
245
|
-
shortcuts,
|
|
246
|
-
setSendMessageHandler: (handler) => {
|
|
247
|
-
sendMessageHandler = handler;
|
|
248
|
-
},
|
|
249
|
-
setAppendEntryHandler: (handler) => {
|
|
250
|
-
appendEntryHandler = handler;
|
|
251
|
-
},
|
|
252
|
-
setNewSessionHandler: (handler) => {
|
|
253
|
-
newSessionHandler = handler;
|
|
254
|
-
},
|
|
255
|
-
setBranchHandler: (handler) => {
|
|
256
|
-
branchHandler = handler;
|
|
257
|
-
},
|
|
258
|
-
setNavigateTreeHandler: (handler) => {
|
|
259
|
-
navigateTreeHandler = handler;
|
|
260
|
-
},
|
|
261
|
-
setGetActiveToolsHandler: (handler) => {
|
|
262
|
-
getActiveToolsHandler = handler;
|
|
263
|
-
},
|
|
264
|
-
setGetAllToolsHandler: (handler) => {
|
|
265
|
-
getAllToolsHandler = handler;
|
|
266
|
-
},
|
|
267
|
-
setSetActiveToolsHandler: (handler) => {
|
|
268
|
-
setActiveToolsHandler = handler;
|
|
269
|
-
},
|
|
270
|
-
setFlagValue: (name, value) => {
|
|
271
|
-
flagValues.set(name, value);
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
139
|
// Factory
|
|
277
140
|
/**
|
|
278
141
|
* Create an AgentSession with the specified options.
|
|
@@ -300,7 +163,6 @@ function createLoadedHooksFromDefinitions(definitions) {
|
|
|
300
163
|
* getApiKey: async () => process.env.MY_KEY,
|
|
301
164
|
* systemPrompt: 'You are helpful.',
|
|
302
165
|
* tools: [readTool, bashTool],
|
|
303
|
-
* hooks: [],
|
|
304
166
|
* skills: [],
|
|
305
167
|
* sessionManager: SessionManager.inMemory(),
|
|
306
168
|
* });
|
|
@@ -309,6 +171,7 @@ function createLoadedHooksFromDefinitions(definitions) {
|
|
|
309
171
|
export async function createAgentSession(options = {}) {
|
|
310
172
|
const cwd = options.cwd ?? process.cwd();
|
|
311
173
|
const agentDir = options.agentDir ?? getDefaultAgentDir();
|
|
174
|
+
const eventBus = options.eventBus ?? createEventBus();
|
|
312
175
|
// Use provided or create AuthStorage and ModelRegistry
|
|
313
176
|
const authStorage = options.authStorage ?? discoverAuthStorage(agentDir);
|
|
314
177
|
const modelRegistry = options.modelRegistry ?? discoverModels(authStorage, agentDir);
|
|
@@ -381,7 +244,7 @@ export async function createAgentSession(options = {}) {
|
|
|
381
244
|
const contextFiles = options.contextFiles ?? discoverContextFiles(cwd, agentDir);
|
|
382
245
|
time("discoverContextFiles");
|
|
383
246
|
const autoResizeImages = settingsManager.getImageAutoResize();
|
|
384
|
-
// Create ALL built-in tools for the registry (
|
|
247
|
+
// Create ALL built-in tools for the registry (extensions can enable any of them)
|
|
385
248
|
const allBuiltInToolsMap = createAllTools(cwd, { read: { autoResizeImages } });
|
|
386
249
|
// Determine initially active built-in tools (default: read, bash, edit, write)
|
|
387
250
|
const defaultActiveToolNames = ["read", "bash", "edit", "write"];
|
|
@@ -390,56 +253,94 @@ export async function createAgentSession(options = {}) {
|
|
|
390
253
|
: defaultActiveToolNames;
|
|
391
254
|
const initialActiveBuiltInTools = initialActiveToolNames.map((name) => allBuiltInToolsMap[name]);
|
|
392
255
|
time("createAllTools");
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
tool: ct.tool,
|
|
400
|
-
}));
|
|
401
|
-
customToolsResult = {
|
|
402
|
-
tools: loadedTools,
|
|
256
|
+
// Load extensions (discovers from standard locations + configured paths)
|
|
257
|
+
let extensionsResult;
|
|
258
|
+
if (options.preloadedExtensions !== undefined && options.preloadedExtensions.length > 0) {
|
|
259
|
+
// Use pre-loaded extensions (from early CLI flag discovery)
|
|
260
|
+
extensionsResult = {
|
|
261
|
+
extensions: options.preloadedExtensions,
|
|
403
262
|
errors: [],
|
|
404
263
|
setUIContext: () => { },
|
|
405
264
|
};
|
|
406
265
|
}
|
|
407
266
|
else {
|
|
408
|
-
// Discover
|
|
409
|
-
const configuredPaths = [...settingsManager.
|
|
410
|
-
|
|
411
|
-
time("
|
|
412
|
-
for (const { path, error } of
|
|
413
|
-
console.error(`Failed to load
|
|
267
|
+
// Discover extensions, merging with additional paths
|
|
268
|
+
const configuredPaths = [...settingsManager.getExtensionPaths(), ...(options.additionalExtensionPaths ?? [])];
|
|
269
|
+
extensionsResult = await discoverAndLoadExtensions(configuredPaths, cwd, agentDir, eventBus);
|
|
270
|
+
time("discoverAndLoadExtensions");
|
|
271
|
+
for (const { path, error } of extensionsResult.errors) {
|
|
272
|
+
console.error(`Failed to load extension "${path}": ${error}`);
|
|
414
273
|
}
|
|
415
274
|
}
|
|
416
|
-
|
|
417
|
-
if (options.
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
275
|
+
// Load inline extensions from factories
|
|
276
|
+
if (options.extensions && options.extensions.length > 0) {
|
|
277
|
+
// Create shared UI context holder that will be set later
|
|
278
|
+
const uiHolder = {
|
|
279
|
+
ui: {
|
|
280
|
+
select: async () => undefined,
|
|
281
|
+
confirm: async () => false,
|
|
282
|
+
input: async () => undefined,
|
|
283
|
+
notify: () => { },
|
|
284
|
+
setStatus: () => { },
|
|
285
|
+
setWidget: () => { },
|
|
286
|
+
setTitle: () => { },
|
|
287
|
+
custom: async () => undefined,
|
|
288
|
+
setEditorText: () => { },
|
|
289
|
+
getEditorText: () => "",
|
|
290
|
+
editor: async () => undefined,
|
|
291
|
+
get theme() {
|
|
292
|
+
return {};
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
hasUI: false,
|
|
296
|
+
};
|
|
297
|
+
for (let i = 0; i < options.extensions.length; i++) {
|
|
298
|
+
const factory = options.extensions[i];
|
|
299
|
+
const loaded = loadExtensionFromFactory(factory, cwd, eventBus, uiHolder, `<inline-${i}>`);
|
|
300
|
+
extensionsResult.extensions.push(loaded);
|
|
425
301
|
}
|
|
302
|
+
// Extend setUIContext to update inline extensions too
|
|
303
|
+
const originalSetUIContext = extensionsResult.setUIContext;
|
|
304
|
+
extensionsResult.setUIContext = (uiContext, hasUI) => {
|
|
305
|
+
originalSetUIContext(uiContext, hasUI);
|
|
306
|
+
uiHolder.ui = uiContext;
|
|
307
|
+
uiHolder.hasUI = hasUI;
|
|
308
|
+
};
|
|
426
309
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
time("discoverAndLoadHooks");
|
|
432
|
-
for (const { path, error } of errors) {
|
|
433
|
-
console.error(`Failed to load hook "${path}": ${error}`);
|
|
434
|
-
}
|
|
435
|
-
if (hooks.length > 0) {
|
|
436
|
-
hookRunner = new HookRunner(hooks, cwd, sessionManager, modelRegistry);
|
|
437
|
-
}
|
|
310
|
+
// Create extension runner if we have extensions
|
|
311
|
+
let extensionRunner;
|
|
312
|
+
if (extensionsResult.extensions.length > 0) {
|
|
313
|
+
extensionRunner = new ExtensionRunner(extensionsResult.extensions, cwd, sessionManager, modelRegistry);
|
|
438
314
|
}
|
|
439
|
-
// Wrap custom tools with context getter
|
|
315
|
+
// Wrap extension-registered tools and SDK-provided custom tools with context getter
|
|
316
|
+
// (agent/session assigned below, accessed at execute time)
|
|
440
317
|
let agent;
|
|
441
318
|
let session;
|
|
442
|
-
const
|
|
319
|
+
const registeredTools = extensionRunner?.getAllRegisteredTools() ?? [];
|
|
320
|
+
// Combine extension-registered tools with SDK-provided custom tools
|
|
321
|
+
const allCustomTools = [
|
|
322
|
+
...registeredTools,
|
|
323
|
+
...(options.customTools?.map((def) => ({ definition: def, extensionPath: "<sdk>" })) ?? []),
|
|
324
|
+
];
|
|
325
|
+
const wrappedExtensionTools = wrapRegisteredTools(allCustomTools, () => ({
|
|
326
|
+
ui: extensionRunner?.getUIContext() ?? {
|
|
327
|
+
select: async () => undefined,
|
|
328
|
+
confirm: async () => false,
|
|
329
|
+
input: async () => undefined,
|
|
330
|
+
notify: () => { },
|
|
331
|
+
setStatus: () => { },
|
|
332
|
+
setWidget: () => { },
|
|
333
|
+
setTitle: () => { },
|
|
334
|
+
custom: async () => undefined,
|
|
335
|
+
setEditorText: () => { },
|
|
336
|
+
getEditorText: () => "",
|
|
337
|
+
editor: async () => undefined,
|
|
338
|
+
get theme() {
|
|
339
|
+
return {};
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
hasUI: extensionRunner?.getHasUI() ?? false,
|
|
343
|
+
cwd,
|
|
443
344
|
sessionManager,
|
|
444
345
|
modelRegistry,
|
|
445
346
|
model: agent.state.model,
|
|
@@ -449,25 +350,25 @@ export async function createAgentSession(options = {}) {
|
|
|
449
350
|
session.abort();
|
|
450
351
|
},
|
|
451
352
|
}));
|
|
452
|
-
// Create tool registry mapping name -> tool (for
|
|
453
|
-
// Registry contains ALL built-in tools so
|
|
353
|
+
// Create tool registry mapping name -> tool (for extension getTools/setTools)
|
|
354
|
+
// Registry contains ALL built-in tools so extensions can enable any of them
|
|
454
355
|
const toolRegistry = new Map();
|
|
455
356
|
for (const [name, tool] of Object.entries(allBuiltInToolsMap)) {
|
|
456
357
|
toolRegistry.set(name, tool);
|
|
457
358
|
}
|
|
458
|
-
for (const tool of
|
|
359
|
+
for (const tool of wrappedExtensionTools) {
|
|
459
360
|
toolRegistry.set(tool.name, tool);
|
|
460
361
|
}
|
|
461
|
-
// Initially active tools = active built-in +
|
|
462
|
-
let activeToolsArray = [...initialActiveBuiltInTools, ...
|
|
362
|
+
// Initially active tools = active built-in + extension tools
|
|
363
|
+
let activeToolsArray = [...initialActiveBuiltInTools, ...wrappedExtensionTools];
|
|
463
364
|
time("combineTools");
|
|
464
|
-
// Wrap tools with
|
|
365
|
+
// Wrap tools with extensions if available
|
|
465
366
|
let wrappedToolRegistry;
|
|
466
|
-
if (
|
|
467
|
-
activeToolsArray =
|
|
468
|
-
// Wrap ALL registry tools (not just active) so
|
|
367
|
+
if (extensionRunner) {
|
|
368
|
+
activeToolsArray = wrapToolsWithExtensions(activeToolsArray, extensionRunner);
|
|
369
|
+
// Wrap ALL registry tools (not just active) so extensions can enable any
|
|
469
370
|
const allRegistryTools = Array.from(toolRegistry.values());
|
|
470
|
-
const wrappedAllTools =
|
|
371
|
+
const wrappedAllTools = wrapToolsWithExtensions(allRegistryTools, extensionRunner);
|
|
471
372
|
wrappedToolRegistry = new Map();
|
|
472
373
|
for (const tool of wrappedAllTools) {
|
|
473
374
|
wrappedToolRegistry.set(tool.name, tool);
|
|
@@ -504,8 +405,8 @@ export async function createAgentSession(options = {}) {
|
|
|
504
405
|
};
|
|
505
406
|
const systemPrompt = rebuildSystemPrompt(initialActiveToolNames);
|
|
506
407
|
time("buildSystemPrompt");
|
|
507
|
-
const
|
|
508
|
-
time("
|
|
408
|
+
const promptTemplates = options.promptTemplates ?? discoverPromptTemplates(cwd, agentDir);
|
|
409
|
+
time("discoverPromptTemplates");
|
|
509
410
|
agent = new Agent({
|
|
510
411
|
initialState: {
|
|
511
412
|
systemPrompt,
|
|
@@ -514,9 +415,9 @@ export async function createAgentSession(options = {}) {
|
|
|
514
415
|
tools: activeToolsArray,
|
|
515
416
|
},
|
|
516
417
|
convertToLlm,
|
|
517
|
-
transformContext:
|
|
418
|
+
transformContext: extensionRunner
|
|
518
419
|
? async (messages) => {
|
|
519
|
-
return
|
|
420
|
+
return extensionRunner.emitContext(messages);
|
|
520
421
|
}
|
|
521
422
|
: undefined,
|
|
522
423
|
steeringMode: settingsManager.getSteeringMode(),
|
|
@@ -550,9 +451,8 @@ export async function createAgentSession(options = {}) {
|
|
|
550
451
|
sessionManager,
|
|
551
452
|
settingsManager,
|
|
552
453
|
scopedModels: options.scopedModels,
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
customTools: customToolsResult.tools,
|
|
454
|
+
promptTemplates: promptTemplates,
|
|
455
|
+
extensionRunner,
|
|
556
456
|
skillsSettings: settingsManager.getSkillsSettings(),
|
|
557
457
|
modelRegistry,
|
|
558
458
|
toolRegistry: wrappedToolRegistry ?? toolRegistry,
|
|
@@ -561,7 +461,7 @@ export async function createAgentSession(options = {}) {
|
|
|
561
461
|
time("createAgentSession");
|
|
562
462
|
return {
|
|
563
463
|
session,
|
|
564
|
-
|
|
464
|
+
extensionsResult,
|
|
565
465
|
modelFallbackMessage,
|
|
566
466
|
};
|
|
567
467
|
}
|