@posthog/agent 1.30.0 → 2.0.1
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/LICENSE +1 -1
- package/README.md +221 -219
- package/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +21 -0
- package/dist/adapters/claude/conversion/tool-use-to-acp.js +547 -0
- package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -0
- package/dist/adapters/claude/permissions/permission-options.d.ts +13 -0
- package/dist/adapters/claude/permissions/permission-options.js +117 -0
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -0
- package/dist/adapters/claude/questions/utils.d.ts +132 -0
- package/dist/adapters/claude/questions/utils.js +63 -0
- package/dist/adapters/claude/questions/utils.js.map +1 -0
- package/dist/adapters/claude/tools.d.ts +18 -0
- package/dist/adapters/claude/tools.js +95 -0
- package/dist/adapters/claude/tools.js.map +1 -0
- package/dist/agent-DBQY1BfC.d.ts +123 -0
- package/dist/agent.d.ts +5 -0
- package/dist/agent.js +3656 -0
- package/dist/agent.js.map +1 -0
- package/dist/claude-cli/cli.js +3695 -2746
- package/dist/claude-cli/vendor/ripgrep/COPYING +3 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-darwin/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-linux/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-darwin/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-linux/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-win32/ripgrep.node +0 -0
- package/dist/gateway-models.d.ts +24 -0
- package/dist/gateway-models.js +93 -0
- package/dist/gateway-models.js.map +1 -0
- package/dist/index.d.ts +172 -1203
- package/dist/index.js +3704 -6826
- package/dist/index.js.map +1 -1
- package/dist/logger-DDBiMOOD.d.ts +24 -0
- package/dist/posthog-api.d.ts +40 -0
- package/dist/posthog-api.js +175 -0
- package/dist/posthog-api.js.map +1 -0
- package/dist/server/agent-server.d.ts +41 -0
- package/dist/server/agent-server.js +4451 -0
- package/dist/server/agent-server.js.map +1 -0
- package/dist/server/bin.d.ts +1 -0
- package/dist/server/bin.js +4507 -0
- package/dist/server/bin.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -14
- package/src/acp-extensions.ts +93 -61
- package/src/adapters/acp-connection.ts +494 -0
- package/src/adapters/base-acp-agent.ts +150 -0
- package/src/adapters/claude/claude-agent.ts +596 -0
- package/src/adapters/claude/conversion/acp-to-sdk.ts +102 -0
- package/src/adapters/claude/conversion/sdk-to-acp.ts +571 -0
- package/src/adapters/claude/conversion/tool-use-to-acp.ts +618 -0
- package/src/adapters/claude/hooks.ts +64 -0
- package/src/adapters/claude/mcp/tool-metadata.ts +102 -0
- package/src/adapters/claude/permissions/permission-handlers.ts +433 -0
- package/src/adapters/claude/permissions/permission-options.ts +103 -0
- package/src/adapters/claude/plan/utils.ts +56 -0
- package/src/adapters/claude/questions/utils.ts +92 -0
- package/src/adapters/claude/session/commands.ts +38 -0
- package/src/adapters/claude/session/mcp-config.ts +37 -0
- package/src/adapters/claude/session/models.ts +12 -0
- package/src/adapters/claude/session/options.ts +236 -0
- package/src/adapters/claude/tool-meta.ts +143 -0
- package/src/adapters/claude/tools.ts +53 -611
- package/src/adapters/claude/types.ts +61 -0
- package/src/adapters/codex/spawn.ts +130 -0
- package/src/agent.ts +97 -734
- package/src/execution-mode.ts +43 -0
- package/src/gateway-models.ts +135 -0
- package/src/index.ts +79 -0
- package/src/otel-log-writer.test.ts +105 -0
- package/src/otel-log-writer.ts +94 -0
- package/src/posthog-api.ts +75 -235
- package/src/resume.ts +115 -0
- package/src/sagas/apply-snapshot-saga.test.ts +690 -0
- package/src/sagas/apply-snapshot-saga.ts +88 -0
- package/src/sagas/capture-tree-saga.test.ts +892 -0
- package/src/sagas/capture-tree-saga.ts +141 -0
- package/src/sagas/resume-saga.test.ts +558 -0
- package/src/sagas/resume-saga.ts +332 -0
- package/src/sagas/test-fixtures.ts +250 -0
- package/src/server/agent-server.test.ts +220 -0
- package/src/server/agent-server.ts +748 -0
- package/src/server/bin.ts +88 -0
- package/src/server/jwt.ts +65 -0
- package/src/server/schemas.ts +47 -0
- package/src/server/types.ts +13 -0
- package/src/server/utils/retry.test.ts +122 -0
- package/src/server/utils/retry.ts +61 -0
- package/src/server/utils/sse-parser.test.ts +93 -0
- package/src/server/utils/sse-parser.ts +46 -0
- package/src/session-log-writer.test.ts +140 -0
- package/src/session-log-writer.ts +137 -0
- package/src/test/assertions.ts +114 -0
- package/src/test/controllers/sse-controller.ts +107 -0
- package/src/test/fixtures/api.ts +111 -0
- package/src/test/fixtures/config.ts +33 -0
- package/src/test/fixtures/notifications.ts +92 -0
- package/src/test/mocks/claude-sdk.ts +251 -0
- package/src/test/mocks/msw-handlers.ts +48 -0
- package/src/test/setup.ts +114 -0
- package/src/test/wait.ts +41 -0
- package/src/tree-tracker.ts +173 -0
- package/src/types.ts +51 -154
- package/src/utils/acp-content.ts +58 -0
- package/src/utils/async-mutex.test.ts +104 -0
- package/src/utils/async-mutex.ts +31 -0
- package/src/utils/common.ts +15 -0
- package/src/utils/gateway.ts +9 -6
- package/src/utils/logger.ts +0 -30
- package/src/utils/streams.ts +220 -0
- package/CLAUDE.md +0 -331
- package/dist/templates/plan-template.md +0 -41
- package/src/adapters/claude/claude.ts +0 -1543
- package/src/adapters/claude/mcp-server.ts +0 -810
- package/src/adapters/claude/utils.ts +0 -267
- package/src/agents/execution.ts +0 -37
- package/src/agents/planning.ts +0 -60
- package/src/agents/research.ts +0 -160
- package/src/file-manager.ts +0 -306
- package/src/git-manager.ts +0 -577
- package/src/prompt-builder.ts +0 -499
- package/src/schemas.ts +0 -241
- package/src/session-store.ts +0 -259
- package/src/task-manager.ts +0 -163
- package/src/template-manager.ts +0 -236
- package/src/templates/plan-template.md +0 -41
- package/src/todo-manager.ts +0 -180
- package/src/tools/registry.ts +0 -129
- package/src/tools/types.ts +0 -127
- package/src/utils/tapped-stream.ts +0 -60
- package/src/workflow/config.ts +0 -53
- package/src/workflow/steps/build.ts +0 -135
- package/src/workflow/steps/finalize.ts +0 -241
- package/src/workflow/steps/plan.ts +0 -167
- package/src/workflow/steps/research.ts +0 -223
- package/src/workflow/types.ts +0 -62
- package/src/workflow/utils.ts +0 -53
- package/src/worktree-manager.ts +0 -928
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
// src/utils/acp-content.ts
|
|
2
|
+
function text(value) {
|
|
3
|
+
return { type: "text", text: value };
|
|
4
|
+
}
|
|
5
|
+
function image(data, mimeType, uri) {
|
|
6
|
+
return { type: "image", data, mimeType, uri };
|
|
7
|
+
}
|
|
8
|
+
function resourceLink(uri, name, options) {
|
|
9
|
+
return {
|
|
10
|
+
type: "resource_link",
|
|
11
|
+
uri,
|
|
12
|
+
name,
|
|
13
|
+
...options
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
var ToolContentBuilder = class {
|
|
17
|
+
items = [];
|
|
18
|
+
text(value) {
|
|
19
|
+
this.items.push({ type: "content", content: text(value) });
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
image(data, mimeType, uri) {
|
|
23
|
+
this.items.push({ type: "content", content: image(data, mimeType, uri) });
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
diff(path, oldText, newText) {
|
|
27
|
+
this.items.push({ type: "diff", path, oldText, newText });
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
build() {
|
|
31
|
+
return this.items;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function toolContent() {
|
|
35
|
+
return new ToolContentBuilder();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/utils/logger.ts
|
|
39
|
+
var Logger = class _Logger {
|
|
40
|
+
debugEnabled;
|
|
41
|
+
prefix;
|
|
42
|
+
scope;
|
|
43
|
+
onLog;
|
|
44
|
+
constructor(config = {}) {
|
|
45
|
+
this.debugEnabled = config.debug ?? false;
|
|
46
|
+
this.prefix = config.prefix ?? "[PostHog Agent]";
|
|
47
|
+
this.scope = config.scope ?? "agent";
|
|
48
|
+
this.onLog = config.onLog;
|
|
49
|
+
}
|
|
50
|
+
formatMessage(level, message, data) {
|
|
51
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
52
|
+
const base = `${timestamp} ${this.prefix} [${level}] ${message}`;
|
|
53
|
+
if (data !== void 0) {
|
|
54
|
+
return `${base} ${JSON.stringify(data, null, 2)}`;
|
|
55
|
+
}
|
|
56
|
+
return base;
|
|
57
|
+
}
|
|
58
|
+
emitLog(level, message, data) {
|
|
59
|
+
if (this.onLog) {
|
|
60
|
+
this.onLog(level, this.scope, message, data);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const shouldLog = this.debugEnabled || level === "error";
|
|
64
|
+
if (shouldLog) {
|
|
65
|
+
console[level](this.formatMessage(level.toLowerCase(), message, data));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
error(message, error) {
|
|
69
|
+
const data = error instanceof Error ? { message: error.message, stack: error.stack } : error;
|
|
70
|
+
this.emitLog("error", message, data);
|
|
71
|
+
}
|
|
72
|
+
warn(message, data) {
|
|
73
|
+
this.emitLog("warn", message, data);
|
|
74
|
+
}
|
|
75
|
+
info(message, data) {
|
|
76
|
+
this.emitLog("info", message, data);
|
|
77
|
+
}
|
|
78
|
+
debug(message, data) {
|
|
79
|
+
this.emitLog("debug", message, data);
|
|
80
|
+
}
|
|
81
|
+
child(childPrefix) {
|
|
82
|
+
return new _Logger({
|
|
83
|
+
debug: this.debugEnabled,
|
|
84
|
+
prefix: `${this.prefix} [${childPrefix}]`,
|
|
85
|
+
scope: `${this.scope}:${childPrefix}`,
|
|
86
|
+
onLog: this.onLog
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/adapters/claude/conversion/tool-use-to-acp.ts
|
|
92
|
+
var SYSTEM_REMINDER = `
|
|
93
|
+
|
|
94
|
+
<system-reminder>
|
|
95
|
+
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
|
|
96
|
+
</system-reminder>`;
|
|
97
|
+
function replaceAndCalculateLocation(fileContent, edits) {
|
|
98
|
+
let currentContent = fileContent;
|
|
99
|
+
const randomHex = Array.from(crypto.getRandomValues(new Uint8Array(5))).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
100
|
+
const markerPrefix = `__REPLACE_MARKER_${randomHex}_`;
|
|
101
|
+
let markerCounter = 0;
|
|
102
|
+
const markers = [];
|
|
103
|
+
for (const edit of edits) {
|
|
104
|
+
if (edit.oldText === "") {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`The provided \`old_string\` is empty.
|
|
107
|
+
|
|
108
|
+
No edits were applied.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
if (edit.replaceAll) {
|
|
112
|
+
const parts = [];
|
|
113
|
+
let lastIndex = 0;
|
|
114
|
+
let searchIndex = 0;
|
|
115
|
+
while (true) {
|
|
116
|
+
const index = currentContent.indexOf(edit.oldText, searchIndex);
|
|
117
|
+
if (index === -1) {
|
|
118
|
+
if (searchIndex === 0) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`The provided \`old_string\` does not appear in the file: "${edit.oldText}".
|
|
121
|
+
|
|
122
|
+
No edits were applied.`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
parts.push(currentContent.substring(lastIndex, index));
|
|
128
|
+
const marker = `${markerPrefix}${markerCounter++}__`;
|
|
129
|
+
markers.push(marker);
|
|
130
|
+
parts.push(marker + edit.newText);
|
|
131
|
+
lastIndex = index + edit.oldText.length;
|
|
132
|
+
searchIndex = lastIndex;
|
|
133
|
+
}
|
|
134
|
+
parts.push(currentContent.substring(lastIndex));
|
|
135
|
+
currentContent = parts.join("");
|
|
136
|
+
} else {
|
|
137
|
+
const index = currentContent.indexOf(edit.oldText);
|
|
138
|
+
if (index === -1) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`The provided \`old_string\` does not appear in the file: "${edit.oldText}".
|
|
141
|
+
|
|
142
|
+
No edits were applied.`
|
|
143
|
+
);
|
|
144
|
+
} else {
|
|
145
|
+
const marker = `${markerPrefix}${markerCounter++}__`;
|
|
146
|
+
markers.push(marker);
|
|
147
|
+
currentContent = currentContent.substring(0, index) + marker + edit.newText + currentContent.substring(index + edit.oldText.length);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const lineNumbers = [];
|
|
152
|
+
for (const marker of markers) {
|
|
153
|
+
const index = currentContent.indexOf(marker);
|
|
154
|
+
if (index !== -1) {
|
|
155
|
+
const lineNumber = Math.max(
|
|
156
|
+
0,
|
|
157
|
+
currentContent.substring(0, index).split(/\r\n|\r|\n/).length - 1
|
|
158
|
+
);
|
|
159
|
+
lineNumbers.push(lineNumber);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
let finalContent = currentContent;
|
|
163
|
+
for (const marker of markers) {
|
|
164
|
+
finalContent = finalContent.replace(marker, "");
|
|
165
|
+
}
|
|
166
|
+
const uniqueLineNumbers = [...new Set(lineNumbers)].sort();
|
|
167
|
+
return { newContent: finalContent, lineNumbers: uniqueLineNumbers };
|
|
168
|
+
}
|
|
169
|
+
function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ debug: false, prefix: "[ClaudeTools]" })) {
|
|
170
|
+
const name = toolUse.name;
|
|
171
|
+
const input = toolUse.input;
|
|
172
|
+
switch (name) {
|
|
173
|
+
case "Task":
|
|
174
|
+
return {
|
|
175
|
+
title: input?.description ? String(input.description) : "Task",
|
|
176
|
+
kind: "think",
|
|
177
|
+
content: input?.prompt ? toolContent().text(String(input.prompt)).build() : []
|
|
178
|
+
};
|
|
179
|
+
case "NotebookRead":
|
|
180
|
+
return {
|
|
181
|
+
title: input?.notebook_path ? `Read Notebook ${String(input.notebook_path)}` : "Read Notebook",
|
|
182
|
+
kind: "read",
|
|
183
|
+
content: [],
|
|
184
|
+
locations: input?.notebook_path ? [{ path: String(input.notebook_path) }] : []
|
|
185
|
+
};
|
|
186
|
+
case "NotebookEdit":
|
|
187
|
+
return {
|
|
188
|
+
title: input?.notebook_path ? `Edit Notebook ${String(input.notebook_path)}` : "Edit Notebook",
|
|
189
|
+
kind: "edit",
|
|
190
|
+
content: input?.new_source ? toolContent().text(String(input.new_source)).build() : [],
|
|
191
|
+
locations: input?.notebook_path ? [{ path: String(input.notebook_path) }] : []
|
|
192
|
+
};
|
|
193
|
+
case "Bash":
|
|
194
|
+
return {
|
|
195
|
+
title: input?.description ? String(input.description) : "Execute command",
|
|
196
|
+
kind: "execute",
|
|
197
|
+
content: input?.command ? toolContent().text(String(input.command)).build() : []
|
|
198
|
+
};
|
|
199
|
+
case "BashOutput":
|
|
200
|
+
return {
|
|
201
|
+
title: "Tail Logs",
|
|
202
|
+
kind: "execute",
|
|
203
|
+
content: []
|
|
204
|
+
};
|
|
205
|
+
case "KillShell":
|
|
206
|
+
return {
|
|
207
|
+
title: "Kill Process",
|
|
208
|
+
kind: "execute",
|
|
209
|
+
content: []
|
|
210
|
+
};
|
|
211
|
+
case "Read": {
|
|
212
|
+
let limit = "";
|
|
213
|
+
const inputLimit = input?.limit;
|
|
214
|
+
const inputOffset = input?.offset ?? 0;
|
|
215
|
+
if (inputLimit) {
|
|
216
|
+
limit = ` (${inputOffset + 1} - ${inputOffset + inputLimit})`;
|
|
217
|
+
} else if (inputOffset) {
|
|
218
|
+
limit = ` (from line ${inputOffset + 1})`;
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
title: `Read ${input?.file_path ? String(input.file_path) : "File"}${limit}`,
|
|
222
|
+
kind: "read",
|
|
223
|
+
locations: input?.file_path ? [
|
|
224
|
+
{
|
|
225
|
+
path: String(input.file_path),
|
|
226
|
+
line: inputOffset
|
|
227
|
+
}
|
|
228
|
+
] : [],
|
|
229
|
+
content: []
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
case "LS":
|
|
233
|
+
return {
|
|
234
|
+
title: `List the ${input?.path ? `\`${String(input.path)}\`` : "current"} directory's contents`,
|
|
235
|
+
kind: "search",
|
|
236
|
+
content: [],
|
|
237
|
+
locations: []
|
|
238
|
+
};
|
|
239
|
+
case "Edit": {
|
|
240
|
+
const path = input?.file_path ? String(input.file_path) : void 0;
|
|
241
|
+
let oldText = input?.old_string ? String(input.old_string) : null;
|
|
242
|
+
let newText = input?.new_string ? String(input.new_string) : "";
|
|
243
|
+
let affectedLines = [];
|
|
244
|
+
if (path && oldText) {
|
|
245
|
+
try {
|
|
246
|
+
const oldContent = cachedFileContent[path] || "";
|
|
247
|
+
const newContent = replaceAndCalculateLocation(oldContent, [
|
|
248
|
+
{
|
|
249
|
+
oldText,
|
|
250
|
+
newText,
|
|
251
|
+
replaceAll: false
|
|
252
|
+
}
|
|
253
|
+
]);
|
|
254
|
+
oldText = oldContent;
|
|
255
|
+
newText = newContent.newContent;
|
|
256
|
+
affectedLines = newContent.lineNumbers;
|
|
257
|
+
} catch (e) {
|
|
258
|
+
logger.error("Failed to edit file", e);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
title: path ? `Edit \`${path}\`` : "Edit",
|
|
263
|
+
kind: "edit",
|
|
264
|
+
content: input && path ? [
|
|
265
|
+
{
|
|
266
|
+
type: "diff",
|
|
267
|
+
path,
|
|
268
|
+
oldText,
|
|
269
|
+
newText
|
|
270
|
+
}
|
|
271
|
+
] : [],
|
|
272
|
+
locations: path ? affectedLines.length > 0 ? affectedLines.map((line) => ({ line, path })) : [{ path }] : []
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
case "Write": {
|
|
276
|
+
let contentResult = [];
|
|
277
|
+
const filePath = input?.file_path ? String(input.file_path) : void 0;
|
|
278
|
+
const contentStr = input?.content ? String(input.content) : void 0;
|
|
279
|
+
if (filePath) {
|
|
280
|
+
contentResult = toolContent().diff(filePath, null, contentStr ?? "").build();
|
|
281
|
+
} else if (contentStr) {
|
|
282
|
+
contentResult = toolContent().text(contentStr).build();
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
title: filePath ? `Write ${filePath}` : "Write",
|
|
286
|
+
kind: "edit",
|
|
287
|
+
content: contentResult,
|
|
288
|
+
locations: filePath ? [{ path: filePath }] : []
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
case "Glob": {
|
|
292
|
+
let label = "Find";
|
|
293
|
+
const pathStr = input?.path ? String(input.path) : void 0;
|
|
294
|
+
if (pathStr) {
|
|
295
|
+
label += ` "${pathStr}"`;
|
|
296
|
+
}
|
|
297
|
+
if (input?.pattern) {
|
|
298
|
+
label += ` "${String(input.pattern)}"`;
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
title: label,
|
|
302
|
+
kind: "search",
|
|
303
|
+
content: [],
|
|
304
|
+
locations: pathStr ? [{ path: pathStr }] : []
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
case "Grep": {
|
|
308
|
+
let label = "grep";
|
|
309
|
+
if (input?.["-i"]) {
|
|
310
|
+
label += " -i";
|
|
311
|
+
}
|
|
312
|
+
if (input?.["-n"]) {
|
|
313
|
+
label += " -n";
|
|
314
|
+
}
|
|
315
|
+
if (input?.["-A"] !== void 0) {
|
|
316
|
+
label += ` -A ${input["-A"]}`;
|
|
317
|
+
}
|
|
318
|
+
if (input?.["-B"] !== void 0) {
|
|
319
|
+
label += ` -B ${input["-B"]}`;
|
|
320
|
+
}
|
|
321
|
+
if (input?.["-C"] !== void 0) {
|
|
322
|
+
label += ` -C ${input["-C"]}`;
|
|
323
|
+
}
|
|
324
|
+
if (input?.output_mode) {
|
|
325
|
+
switch (input.output_mode) {
|
|
326
|
+
case "FilesWithMatches":
|
|
327
|
+
label += " -l";
|
|
328
|
+
break;
|
|
329
|
+
case "Count":
|
|
330
|
+
label += " -c";
|
|
331
|
+
break;
|
|
332
|
+
default:
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (input?.head_limit !== void 0) {
|
|
337
|
+
label += ` | head -${input.head_limit}`;
|
|
338
|
+
}
|
|
339
|
+
if (input?.glob) {
|
|
340
|
+
label += ` --include="${String(input.glob)}"`;
|
|
341
|
+
}
|
|
342
|
+
if (input?.type) {
|
|
343
|
+
label += ` --type=${String(input.type)}`;
|
|
344
|
+
}
|
|
345
|
+
if (input?.multiline) {
|
|
346
|
+
label += " -P";
|
|
347
|
+
}
|
|
348
|
+
label += ` "${input?.pattern ? String(input.pattern) : ""}"`;
|
|
349
|
+
if (input?.path) {
|
|
350
|
+
label += ` ${String(input.path)}`;
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
title: label,
|
|
354
|
+
kind: "search",
|
|
355
|
+
content: []
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
case "WebFetch":
|
|
359
|
+
return {
|
|
360
|
+
title: "Fetch",
|
|
361
|
+
kind: "fetch",
|
|
362
|
+
content: input?.url ? [
|
|
363
|
+
{
|
|
364
|
+
type: "content",
|
|
365
|
+
content: resourceLink(String(input.url), String(input.url), {
|
|
366
|
+
description: input?.prompt ? String(input.prompt) : void 0
|
|
367
|
+
})
|
|
368
|
+
}
|
|
369
|
+
] : []
|
|
370
|
+
};
|
|
371
|
+
case "WebSearch": {
|
|
372
|
+
let label = `"${input?.query ? String(input.query) : ""}"`;
|
|
373
|
+
const allowedDomains = input?.allowed_domains;
|
|
374
|
+
const blockedDomains = input?.blocked_domains;
|
|
375
|
+
if (allowedDomains && allowedDomains.length > 0) {
|
|
376
|
+
label += ` (allowed: ${allowedDomains.join(", ")})`;
|
|
377
|
+
}
|
|
378
|
+
if (blockedDomains && blockedDomains.length > 0) {
|
|
379
|
+
label += ` (blocked: ${blockedDomains.join(", ")})`;
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
title: label,
|
|
383
|
+
kind: "fetch",
|
|
384
|
+
content: []
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
case "TodoWrite":
|
|
388
|
+
return {
|
|
389
|
+
title: Array.isArray(input?.todos) ? `Update TODOs: ${input.todos.map((todo) => todo.content).join(", ")}` : "Update TODOs",
|
|
390
|
+
kind: "think",
|
|
391
|
+
content: []
|
|
392
|
+
};
|
|
393
|
+
case "ExitPlanMode":
|
|
394
|
+
return {
|
|
395
|
+
title: "Ready to code?",
|
|
396
|
+
kind: "switch_mode",
|
|
397
|
+
content: input?.plan ? toolContent().text(String(input.plan)).build() : []
|
|
398
|
+
};
|
|
399
|
+
case "AskUserQuestion": {
|
|
400
|
+
const questions = input?.questions;
|
|
401
|
+
return {
|
|
402
|
+
title: questions?.[0]?.question || "Question",
|
|
403
|
+
kind: "other",
|
|
404
|
+
content: questions ? toolContent().text(JSON.stringify(questions, null, 2)).build() : []
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
case "Other": {
|
|
408
|
+
let output;
|
|
409
|
+
try {
|
|
410
|
+
output = JSON.stringify(input, null, 2);
|
|
411
|
+
} catch {
|
|
412
|
+
output = typeof input === "string" ? input : "{}";
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
title: name || "Unknown Tool",
|
|
416
|
+
kind: "other",
|
|
417
|
+
content: toolContent().text(`\`\`\`json
|
|
418
|
+
${output}\`\`\``).build()
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
default:
|
|
422
|
+
return {
|
|
423
|
+
title: name || "Unknown Tool",
|
|
424
|
+
kind: "other",
|
|
425
|
+
content: []
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
function toolUpdateFromToolResult(toolResult, toolUse) {
|
|
430
|
+
switch (toolUse?.name) {
|
|
431
|
+
case "Read":
|
|
432
|
+
if (Array.isArray(toolResult.content) && toolResult.content.length > 0) {
|
|
433
|
+
return {
|
|
434
|
+
content: toolResult.content.map((item) => {
|
|
435
|
+
const itemObj = item;
|
|
436
|
+
if (itemObj.type === "text") {
|
|
437
|
+
return {
|
|
438
|
+
type: "content",
|
|
439
|
+
content: text(
|
|
440
|
+
markdownEscape(
|
|
441
|
+
(itemObj.text ?? "").replace(SYSTEM_REMINDER, "")
|
|
442
|
+
)
|
|
443
|
+
)
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
type: "content",
|
|
448
|
+
content: item
|
|
449
|
+
};
|
|
450
|
+
})
|
|
451
|
+
};
|
|
452
|
+
} else if (typeof toolResult.content === "string" && toolResult.content.length > 0) {
|
|
453
|
+
return {
|
|
454
|
+
content: toolContent().text(
|
|
455
|
+
markdownEscape(toolResult.content.replace(SYSTEM_REMINDER, ""))
|
|
456
|
+
).build()
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
return {};
|
|
460
|
+
case "Bash": {
|
|
461
|
+
return toAcpContentUpdate(
|
|
462
|
+
toolResult.content,
|
|
463
|
+
"is_error" in toolResult ? toolResult.is_error : false
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
case "Edit":
|
|
467
|
+
case "Write": {
|
|
468
|
+
if ("is_error" in toolResult && toolResult.is_error && toolResult.content && toolResult.content.length > 0) {
|
|
469
|
+
return toAcpContentUpdate(toolResult.content, true);
|
|
470
|
+
}
|
|
471
|
+
return {};
|
|
472
|
+
}
|
|
473
|
+
case "ExitPlanMode": {
|
|
474
|
+
return { title: "Exited Plan Mode" };
|
|
475
|
+
}
|
|
476
|
+
case "AskUserQuestion": {
|
|
477
|
+
const content = toolResult.content;
|
|
478
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
479
|
+
const firstItem = content[0];
|
|
480
|
+
if (typeof firstItem === "object" && firstItem !== null && "text" in firstItem) {
|
|
481
|
+
return {
|
|
482
|
+
title: "Answer received",
|
|
483
|
+
content: toolContent().text(String(firstItem.text)).build()
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return { title: "Question answered" };
|
|
488
|
+
}
|
|
489
|
+
default: {
|
|
490
|
+
return toAcpContentUpdate(
|
|
491
|
+
toolResult.content,
|
|
492
|
+
"is_error" in toolResult ? toolResult.is_error : false
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function toAcpContentUpdate(content, isError = false) {
|
|
498
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
499
|
+
return {
|
|
500
|
+
content: content.map((item) => {
|
|
501
|
+
const itemObj = item;
|
|
502
|
+
if (isError && itemObj.type === "text") {
|
|
503
|
+
return {
|
|
504
|
+
type: "content",
|
|
505
|
+
content: text(`\`\`\`
|
|
506
|
+
${itemObj.text ?? ""}
|
|
507
|
+
\`\`\``)
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
return {
|
|
511
|
+
type: "content",
|
|
512
|
+
content: item
|
|
513
|
+
};
|
|
514
|
+
})
|
|
515
|
+
};
|
|
516
|
+
} else if (typeof content === "string" && content.length > 0) {
|
|
517
|
+
return {
|
|
518
|
+
content: toolContent().text(isError ? `\`\`\`
|
|
519
|
+
${content}
|
|
520
|
+
\`\`\`` : content).build()
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return {};
|
|
524
|
+
}
|
|
525
|
+
function planEntries(input) {
|
|
526
|
+
return input.todos.map((input2) => ({
|
|
527
|
+
content: input2.content,
|
|
528
|
+
status: input2.status,
|
|
529
|
+
priority: "medium"
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
function markdownEscape(text2) {
|
|
533
|
+
let escapedText = "```";
|
|
534
|
+
for (const [m] of text2.matchAll(/^```+/gm)) {
|
|
535
|
+
while (m.length >= escapedText.length) {
|
|
536
|
+
escapedText += "`";
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return `${escapedText}
|
|
540
|
+
${text2}${text2.endsWith("\n") ? "" : "\n"}${escapedText}`;
|
|
541
|
+
}
|
|
542
|
+
export {
|
|
543
|
+
planEntries,
|
|
544
|
+
toolInfoFromToolUse,
|
|
545
|
+
toolUpdateFromToolResult
|
|
546
|
+
};
|
|
547
|
+
//# sourceMappingURL=tool-use-to-acp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/utils/acp-content.ts","../../../../src/utils/logger.ts","../../../../src/adapters/claude/conversion/tool-use-to-acp.ts"],"sourcesContent":["import type { ContentBlock, ToolCallContent } from \"@agentclientprotocol/sdk\";\n\nexport function text(value: string): ContentBlock {\n return { type: \"text\", text: value };\n}\n\nexport function image(\n data: string,\n mimeType: string,\n uri?: string,\n): ContentBlock {\n return { type: \"image\", data, mimeType, uri };\n}\n\nexport function resourceLink(\n uri: string,\n name: string,\n options?: {\n mimeType?: string;\n title?: string;\n description?: string;\n size?: bigint;\n },\n): ContentBlock {\n return {\n type: \"resource_link\",\n uri,\n name,\n ...options,\n };\n}\n\nclass ToolContentBuilder {\n private items: ToolCallContent[] = [];\n\n text(value: string): this {\n this.items.push({ type: \"content\", content: text(value) });\n return this;\n }\n\n image(data: string, mimeType: string, uri?: string): this {\n this.items.push({ type: \"content\", content: image(data, mimeType, uri) });\n return this;\n }\n\n diff(path: string, oldText: string | null, newText: string): this {\n this.items.push({ type: \"diff\", path, oldText, newText });\n return this;\n }\n\n build(): ToolCallContent[] {\n return this.items;\n }\n}\n\nexport function toolContent(): ToolContentBuilder {\n return new ToolContentBuilder();\n}\n","import type { LogLevel as LogLevelType, OnLogCallback } from \"../types.js\";\n\nexport interface LoggerConfig {\n debug?: boolean;\n prefix?: string;\n scope?: string;\n onLog?: OnLogCallback;\n}\n\nexport class Logger {\n private debugEnabled: boolean;\n private prefix: string;\n private scope: string;\n private onLog?: OnLogCallback;\n\n constructor(config: LoggerConfig = {}) {\n this.debugEnabled = config.debug ?? false;\n this.prefix = config.prefix ?? \"[PostHog Agent]\";\n this.scope = config.scope ?? \"agent\";\n this.onLog = config.onLog;\n }\n\n private formatMessage(\n level: string,\n message: string,\n data?: unknown,\n ): string {\n const timestamp = new Date().toISOString();\n const base = `${timestamp} ${this.prefix} [${level}] ${message}`;\n\n if (data !== undefined) {\n return `${base} ${JSON.stringify(data, null, 2)}`;\n }\n\n return base;\n }\n\n private emitLog(level: LogLevelType, message: string, data?: unknown) {\n if (this.onLog) {\n this.onLog(level, this.scope, message, data);\n return;\n }\n\n const shouldLog = this.debugEnabled || level === \"error\";\n\n if (shouldLog) {\n console[level](this.formatMessage(level.toLowerCase(), message, data));\n }\n }\n\n error(message: string, error?: Error | unknown) {\n const data =\n error instanceof Error\n ? { message: error.message, stack: error.stack }\n : error;\n\n this.emitLog(\"error\", message, data);\n }\n\n warn(message: string, data?: unknown) {\n this.emitLog(\"warn\", message, data);\n }\n\n info(message: string, data?: unknown) {\n this.emitLog(\"info\", message, data);\n }\n\n debug(message: string, data?: unknown) {\n this.emitLog(\"debug\", message, data);\n }\n\n child(childPrefix: string): Logger {\n return new Logger({\n debug: this.debugEnabled,\n prefix: `${this.prefix} [${childPrefix}]`,\n scope: `${this.scope}:${childPrefix}`,\n onLog: this.onLog,\n });\n }\n}\n","import type {\n PlanEntry,\n ToolCall,\n ToolCallContent,\n ToolCallUpdate,\n ToolKind,\n} from \"@agentclientprotocol/sdk\";\nimport type {\n ToolResultBlockParam,\n ToolUseBlock,\n WebSearchToolResultBlockParam,\n} from \"@anthropic-ai/sdk/resources\";\nimport type {\n BetaBashCodeExecutionToolResultBlockParam,\n BetaCodeExecutionToolResultBlockParam,\n BetaRequestMCPToolResultBlockParam,\n BetaTextEditorCodeExecutionToolResultBlockParam,\n BetaToolSearchToolResultBlockParam,\n BetaWebFetchToolResultBlockParam,\n BetaWebSearchToolResultBlockParam,\n} from \"@anthropic-ai/sdk/resources/beta.mjs\";\n\nconst SYSTEM_REMINDER = `\n\n<system-reminder>\nWhenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.\n</system-reminder>`;\n\nimport { resourceLink, text, toolContent } from \"../../../utils/acp-content.js\";\nimport { Logger } from \"../../../utils/logger.js\";\n\ninterface EditOperation {\n oldText: string;\n newText: string;\n replaceAll?: boolean;\n}\n\ninterface EditResult {\n newContent: string;\n lineNumbers: number[];\n}\n\nfunction replaceAndCalculateLocation(\n fileContent: string,\n edits: EditOperation[],\n): EditResult {\n let currentContent = fileContent;\n\n const randomHex = Array.from(crypto.getRandomValues(new Uint8Array(5)))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const markerPrefix = `__REPLACE_MARKER_${randomHex}_`;\n let markerCounter = 0;\n const markers: string[] = [];\n\n for (const edit of edits) {\n if (edit.oldText === \"\") {\n throw new Error(\n `The provided \\`old_string\\` is empty.\\n\\nNo edits were applied.`,\n );\n }\n\n if (edit.replaceAll) {\n const parts: string[] = [];\n let lastIndex = 0;\n let searchIndex = 0;\n\n while (true) {\n const index = currentContent.indexOf(edit.oldText, searchIndex);\n if (index === -1) {\n if (searchIndex === 0) {\n throw new Error(\n `The provided \\`old_string\\` does not appear in the file: \"${edit.oldText}\".\\n\\nNo edits were applied.`,\n );\n }\n break;\n }\n\n parts.push(currentContent.substring(lastIndex, index));\n\n const marker = `${markerPrefix}${markerCounter++}__`;\n markers.push(marker);\n parts.push(marker + edit.newText);\n\n lastIndex = index + edit.oldText.length;\n searchIndex = lastIndex;\n }\n\n parts.push(currentContent.substring(lastIndex));\n currentContent = parts.join(\"\");\n } else {\n const index = currentContent.indexOf(edit.oldText);\n if (index === -1) {\n throw new Error(\n `The provided \\`old_string\\` does not appear in the file: \"${edit.oldText}\".\\n\\nNo edits were applied.`,\n );\n } else {\n const marker = `${markerPrefix}${markerCounter++}__`;\n markers.push(marker);\n currentContent =\n currentContent.substring(0, index) +\n marker +\n edit.newText +\n currentContent.substring(index + edit.oldText.length);\n }\n }\n }\n\n const lineNumbers: number[] = [];\n for (const marker of markers) {\n const index = currentContent.indexOf(marker);\n if (index !== -1) {\n const lineNumber = Math.max(\n 0,\n currentContent.substring(0, index).split(/\\r\\n|\\r|\\n/).length - 1,\n );\n lineNumbers.push(lineNumber);\n }\n }\n\n let finalContent = currentContent;\n for (const marker of markers) {\n finalContent = finalContent.replace(marker, \"\");\n }\n\n const uniqueLineNumbers = [...new Set(lineNumbers)].sort();\n\n return { newContent: finalContent, lineNumbers: uniqueLineNumbers };\n}\n\ntype ToolInfo = Pick<ToolCall, \"title\" | \"kind\" | \"content\" | \"locations\">;\n\nexport function toolInfoFromToolUse(\n toolUse: Pick<ToolUseBlock, \"name\" | \"input\">,\n cachedFileContent: { [key: string]: string },\n logger: Logger = new Logger({ debug: false, prefix: \"[ClaudeTools]\" }),\n): ToolInfo {\n const name = toolUse.name;\n const input = toolUse.input as Record<string, unknown> | undefined;\n\n switch (name) {\n case \"Task\":\n return {\n title: input?.description ? String(input.description) : \"Task\",\n kind: \"think\",\n content: input?.prompt\n ? toolContent().text(String(input.prompt)).build()\n : [],\n };\n\n case \"NotebookRead\":\n return {\n title: input?.notebook_path\n ? `Read Notebook ${String(input.notebook_path)}`\n : \"Read Notebook\",\n kind: \"read\",\n content: [],\n locations: input?.notebook_path\n ? [{ path: String(input.notebook_path) }]\n : [],\n };\n\n case \"NotebookEdit\":\n return {\n title: input?.notebook_path\n ? `Edit Notebook ${String(input.notebook_path)}`\n : \"Edit Notebook\",\n kind: \"edit\",\n content: input?.new_source\n ? toolContent().text(String(input.new_source)).build()\n : [],\n locations: input?.notebook_path\n ? [{ path: String(input.notebook_path) }]\n : [],\n };\n\n case \"Bash\":\n return {\n title: input?.description\n ? String(input.description)\n : \"Execute command\",\n kind: \"execute\",\n content: input?.command\n ? toolContent().text(String(input.command)).build()\n : [],\n };\n\n case \"BashOutput\":\n return {\n title: \"Tail Logs\",\n kind: \"execute\",\n content: [],\n };\n\n case \"KillShell\":\n return {\n title: \"Kill Process\",\n kind: \"execute\",\n content: [],\n };\n\n case \"Read\": {\n let limit = \"\";\n const inputLimit = input?.limit as number | undefined;\n const inputOffset = (input?.offset as number | undefined) ?? 0;\n if (inputLimit) {\n limit = ` (${inputOffset + 1} - ${inputOffset + inputLimit})`;\n } else if (inputOffset) {\n limit = ` (from line ${inputOffset + 1})`;\n }\n return {\n title: `Read ${input?.file_path ? String(input.file_path) : \"File\"}${limit}`,\n kind: \"read\",\n locations: input?.file_path\n ? [\n {\n path: String(input.file_path),\n line: inputOffset,\n },\n ]\n : [],\n content: [],\n };\n }\n\n case \"LS\":\n return {\n title: `List the ${input?.path ? `\\`${String(input.path)}\\`` : \"current\"} directory's contents`,\n kind: \"search\",\n content: [],\n locations: [],\n };\n\n case \"Edit\": {\n const path = input?.file_path ? String(input.file_path) : undefined;\n let oldText = input?.old_string ? String(input.old_string) : null;\n let newText = input?.new_string ? String(input.new_string) : \"\";\n let affectedLines: number[] = [];\n\n if (path && oldText) {\n try {\n const oldContent = cachedFileContent[path] || \"\";\n const newContent = replaceAndCalculateLocation(oldContent, [\n {\n oldText,\n newText,\n replaceAll: false,\n },\n ]);\n oldText = oldContent;\n newText = newContent.newContent;\n affectedLines = newContent.lineNumbers;\n } catch (e) {\n logger.error(\"Failed to edit file\", e);\n }\n }\n return {\n title: path ? `Edit \\`${path}\\`` : \"Edit\",\n kind: \"edit\",\n content:\n input && path\n ? [\n {\n type: \"diff\",\n path,\n oldText,\n newText,\n },\n ]\n : [],\n locations: path\n ? affectedLines.length > 0\n ? affectedLines.map((line) => ({ line, path }))\n : [{ path }]\n : [],\n };\n }\n\n case \"Write\": {\n let contentResult: ToolCallContent[] = [];\n const filePath = input?.file_path ? String(input.file_path) : undefined;\n const contentStr = input?.content ? String(input.content) : undefined;\n if (filePath) {\n contentResult = toolContent()\n .diff(filePath, null, contentStr ?? \"\")\n .build();\n } else if (contentStr) {\n contentResult = toolContent().text(contentStr).build();\n }\n return {\n title: filePath ? `Write ${filePath}` : \"Write\",\n kind: \"edit\",\n content: contentResult,\n locations: filePath ? [{ path: filePath }] : [],\n };\n }\n\n case \"Glob\": {\n let label = \"Find\";\n const pathStr = input?.path ? String(input.path) : undefined;\n if (pathStr) {\n label += ` \"${pathStr}\"`;\n }\n if (input?.pattern) {\n label += ` \"${String(input.pattern)}\"`;\n }\n return {\n title: label,\n kind: \"search\",\n content: [],\n locations: pathStr ? [{ path: pathStr }] : [],\n };\n }\n\n case \"Grep\": {\n let label = \"grep\";\n\n if (input?.[\"-i\"]) {\n label += \" -i\";\n }\n if (input?.[\"-n\"]) {\n label += \" -n\";\n }\n\n if (input?.[\"-A\"] !== undefined) {\n label += ` -A ${input[\"-A\"]}`;\n }\n if (input?.[\"-B\"] !== undefined) {\n label += ` -B ${input[\"-B\"]}`;\n }\n if (input?.[\"-C\"] !== undefined) {\n label += ` -C ${input[\"-C\"]}`;\n }\n\n if (input?.output_mode) {\n switch (input.output_mode) {\n case \"FilesWithMatches\":\n label += \" -l\";\n break;\n case \"Count\":\n label += \" -c\";\n break;\n default:\n break;\n }\n }\n\n if (input?.head_limit !== undefined) {\n label += ` | head -${input.head_limit}`;\n }\n\n if (input?.glob) {\n label += ` --include=\"${String(input.glob)}\"`;\n }\n\n if (input?.type) {\n label += ` --type=${String(input.type)}`;\n }\n\n if (input?.multiline) {\n label += \" -P\";\n }\n\n label += ` \"${input?.pattern ? String(input.pattern) : \"\"}\"`;\n\n if (input?.path) {\n label += ` ${String(input.path)}`;\n }\n\n return {\n title: label,\n kind: \"search\",\n content: [],\n };\n }\n\n case \"WebFetch\":\n return {\n title: \"Fetch\",\n kind: \"fetch\",\n content: input?.url\n ? [\n {\n type: \"content\",\n content: resourceLink(String(input.url), String(input.url), {\n description: input?.prompt ? String(input.prompt) : undefined,\n }),\n },\n ]\n : [],\n };\n\n case \"WebSearch\": {\n let label = `\"${input?.query ? String(input.query) : \"\"}\"`;\n const allowedDomains = input?.allowed_domains as string[] | undefined;\n const blockedDomains = input?.blocked_domains as string[] | undefined;\n\n if (allowedDomains && allowedDomains.length > 0) {\n label += ` (allowed: ${allowedDomains.join(\", \")})`;\n }\n\n if (blockedDomains && blockedDomains.length > 0) {\n label += ` (blocked: ${blockedDomains.join(\", \")})`;\n }\n\n return {\n title: label,\n kind: \"fetch\",\n content: [],\n };\n }\n\n case \"TodoWrite\":\n return {\n title: Array.isArray(input?.todos)\n ? `Update TODOs: ${input.todos.map((todo: { content?: string }) => todo.content).join(\", \")}`\n : \"Update TODOs\",\n kind: \"think\",\n content: [],\n };\n\n case \"ExitPlanMode\":\n return {\n title: \"Ready to code?\",\n kind: \"switch_mode\",\n content: input?.plan\n ? toolContent().text(String(input.plan)).build()\n : [],\n };\n\n case \"AskUserQuestion\": {\n const questions = input?.questions as\n | Array<{ question?: string }>\n | undefined;\n return {\n title: questions?.[0]?.question || \"Question\",\n kind: \"other\" as ToolKind,\n content: questions\n ? toolContent()\n .text(JSON.stringify(questions, null, 2))\n .build()\n : [],\n };\n }\n\n case \"Other\": {\n let output: string;\n try {\n output = JSON.stringify(input, null, 2);\n } catch {\n output = typeof input === \"string\" ? input : \"{}\";\n }\n return {\n title: name || \"Unknown Tool\",\n kind: \"other\",\n content: toolContent().text(`\\`\\`\\`json\\n${output}\\`\\`\\``).build(),\n };\n }\n\n default:\n return {\n title: name || \"Unknown Tool\",\n kind: \"other\",\n content: [],\n };\n }\n}\n\nexport function toolUpdateFromToolResult(\n toolResult:\n | ToolResultBlockParam\n | BetaWebSearchToolResultBlockParam\n | BetaWebFetchToolResultBlockParam\n | WebSearchToolResultBlockParam\n | BetaCodeExecutionToolResultBlockParam\n | BetaBashCodeExecutionToolResultBlockParam\n | BetaTextEditorCodeExecutionToolResultBlockParam\n | BetaRequestMCPToolResultBlockParam\n | BetaToolSearchToolResultBlockParam,\n toolUse: Pick<ToolUseBlock, \"name\" | \"input\"> | undefined,\n): Pick<ToolCallUpdate, \"title\" | \"content\" | \"locations\"> {\n switch (toolUse?.name) {\n case \"Read\":\n if (Array.isArray(toolResult.content) && toolResult.content.length > 0) {\n return {\n content: toolResult.content.map((item) => {\n const itemObj = item as { type?: string; text?: string };\n if (itemObj.type === \"text\") {\n return {\n type: \"content\" as const,\n content: text(\n markdownEscape(\n (itemObj.text ?? \"\").replace(SYSTEM_REMINDER, \"\"),\n ),\n ),\n };\n }\n return {\n type: \"content\" as const,\n content: item as { type: \"text\"; text: string },\n };\n }),\n };\n } else if (\n typeof toolResult.content === \"string\" &&\n toolResult.content.length > 0\n ) {\n return {\n content: toolContent()\n .text(\n markdownEscape(toolResult.content.replace(SYSTEM_REMINDER, \"\")),\n )\n .build(),\n };\n }\n return {};\n\n case \"Bash\": {\n return toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n }\n case \"Edit\":\n case \"Write\": {\n if (\n \"is_error\" in toolResult &&\n toolResult.is_error &&\n toolResult.content &&\n toolResult.content.length > 0\n ) {\n return toAcpContentUpdate(toolResult.content, true);\n }\n return {};\n }\n\n case \"ExitPlanMode\": {\n return { title: \"Exited Plan Mode\" };\n }\n case \"AskUserQuestion\": {\n const content = toolResult.content;\n if (Array.isArray(content) && content.length > 0) {\n const firstItem = content[0];\n if (\n typeof firstItem === \"object\" &&\n firstItem !== null &&\n \"text\" in firstItem\n ) {\n return {\n title: \"Answer received\",\n content: toolContent().text(String(firstItem.text)).build(),\n };\n }\n }\n return { title: \"Question answered\" };\n }\n default: {\n return toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n }\n }\n}\n\nfunction toAcpContentUpdate(\n content: unknown,\n isError: boolean = false,\n): Pick<ToolCallUpdate, \"content\"> {\n if (Array.isArray(content) && content.length > 0) {\n return {\n content: content.map((item) => {\n const itemObj = item as { type?: string; text?: string };\n if (isError && itemObj.type === \"text\") {\n return {\n type: \"content\" as const,\n content: text(`\\`\\`\\`\\n${itemObj.text ?? \"\"}\\n\\`\\`\\``),\n };\n }\n return {\n type: \"content\" as const,\n content: item as { type: \"text\"; text: string },\n };\n }),\n };\n } else if (typeof content === \"string\" && content.length > 0) {\n return {\n content: toolContent()\n .text(isError ? `\\`\\`\\`\\n${content}\\n\\`\\`\\`` : content)\n .build(),\n };\n }\n return {};\n}\n\nexport type ClaudePlanEntry = {\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n activeForm: string;\n};\n\nexport function planEntries(input: { todos: ClaudePlanEntry[] }): PlanEntry[] {\n return input.todos.map((input) => ({\n content: input.content,\n status: input.status,\n priority: \"medium\",\n }));\n}\n\nfunction markdownEscape(text: string): string {\n let escapedText = \"```\";\n for (const [m] of text.matchAll(/^```+/gm)) {\n while (m.length >= escapedText.length) {\n escapedText += \"`\";\n }\n }\n return `${escapedText}\\n${text}${text.endsWith(\"\\n\") ? \"\" : \"\\n\"}${escapedText}`;\n}\n"],"mappings":"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","names":["input","text"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface PermissionOption {
|
|
2
|
+
kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
|
|
3
|
+
name: string;
|
|
4
|
+
optionId: string;
|
|
5
|
+
_meta?: {
|
|
6
|
+
description?: string;
|
|
7
|
+
customInput?: boolean;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
declare function buildPermissionOptions(toolName: string, toolInput: Record<string, unknown>, cwd?: string): PermissionOption[];
|
|
11
|
+
declare function buildExitPlanModePermissionOptions(): PermissionOption[];
|
|
12
|
+
|
|
13
|
+
export { type PermissionOption, buildExitPlanModePermissionOptions, buildPermissionOptions };
|