@posthog/agent 2.1.131 → 2.1.137

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.
Files changed (32) hide show
  1. package/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +14 -28
  2. package/dist/adapters/claude/conversion/tool-use-to-acp.js +116 -164
  3. package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -1
  4. package/dist/adapters/claude/permissions/permission-options.js +33 -0
  5. package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
  6. package/dist/adapters/claude/tools.js +21 -11
  7. package/dist/adapters/claude/tools.js.map +1 -1
  8. package/dist/agent.js +1251 -606
  9. package/dist/agent.js.map +1 -1
  10. package/dist/posthog-api.js +2 -2
  11. package/dist/posthog-api.js.map +1 -1
  12. package/dist/server/agent-server.js +1300 -655
  13. package/dist/server/agent-server.js.map +1 -1
  14. package/dist/server/bin.cjs +1278 -635
  15. package/dist/server/bin.cjs.map +1 -1
  16. package/package.json +2 -2
  17. package/src/adapters/base-acp-agent.ts +6 -3
  18. package/src/adapters/claude/UPSTREAM.md +63 -0
  19. package/src/adapters/claude/claude-agent.ts +682 -421
  20. package/src/adapters/claude/conversion/sdk-to-acp.ts +249 -85
  21. package/src/adapters/claude/conversion/tool-use-to-acp.ts +174 -149
  22. package/src/adapters/claude/hooks.ts +53 -1
  23. package/src/adapters/claude/permissions/permission-handlers.ts +39 -21
  24. package/src/adapters/claude/session/commands.ts +13 -9
  25. package/src/adapters/claude/session/mcp-config.ts +2 -5
  26. package/src/adapters/claude/session/options.ts +58 -6
  27. package/src/adapters/claude/session/settings.ts +326 -0
  28. package/src/adapters/claude/tools.ts +1 -0
  29. package/src/adapters/claude/types.ts +38 -0
  30. package/src/execution-mode.ts +26 -10
  31. package/src/server/agent-server.test.ts +41 -1
  32. package/src/utils/common.ts +1 -1
@@ -1,34 +1,20 @@
1
- import { PlanEntry, ToolCall, ToolCallUpdate } from '@agentclientprotocol/sdk';
1
+ import { PlanEntry, ToolCall, ToolCallContent, ToolCallLocation, ToolCallUpdate } from '@agentclientprotocol/sdk';
2
2
  import { ToolUseBlock, ToolResultBlockParam, WebSearchToolResultBlockParam } from '@anthropic-ai/sdk/resources';
3
3
  import { BetaWebSearchToolResultBlockParam, BetaWebFetchToolResultBlockParam, BetaCodeExecutionToolResultBlockParam, BetaBashCodeExecutionToolResultBlockParam, BetaTextEditorCodeExecutionToolResultBlockParam, BetaRequestMCPToolResultBlockParam, BetaToolSearchToolResultBlockParam } from '@anthropic-ai/sdk/resources/beta.mjs';
4
- import { OnLogCallback } from '../../../types.js';
5
-
6
- interface LoggerConfig {
7
- debug?: boolean;
8
- prefix?: string;
9
- scope?: string;
10
- onLog?: OnLogCallback;
11
- }
12
- declare class Logger {
13
- private debugEnabled;
14
- private prefix;
15
- private scope;
16
- private onLog?;
17
- constructor(config?: LoggerConfig);
18
- private formatMessage;
19
- private emitLog;
20
- error(message: string, error?: Error | unknown): void;
21
- warn(message: string, data?: unknown): void;
22
- info(message: string, data?: unknown): void;
23
- debug(message: string, data?: unknown): void;
24
- child(childPrefix: string): Logger;
25
- }
26
4
 
27
5
  type ToolInfo = Pick<ToolCall, "title" | "kind" | "content" | "locations">;
28
- declare function toolInfoFromToolUse(toolUse: Pick<ToolUseBlock, "name" | "input">, cachedFileContent: {
29
- [key: string]: string;
30
- }, logger?: Logger): ToolInfo;
31
- declare function toolUpdateFromToolResult(toolResult: ToolResultBlockParam | BetaWebSearchToolResultBlockParam | BetaWebFetchToolResultBlockParam | WebSearchToolResultBlockParam | BetaCodeExecutionToolResultBlockParam | BetaBashCodeExecutionToolResultBlockParam | BetaTextEditorCodeExecutionToolResultBlockParam | BetaRequestMCPToolResultBlockParam | BetaToolSearchToolResultBlockParam, toolUse: Pick<ToolUseBlock, "name" | "input"> | undefined): Pick<ToolCallUpdate, "title" | "content" | "locations">;
6
+ declare function toolInfoFromToolUse(toolUse: Pick<ToolUseBlock, "name" | "input">, options?: {
7
+ supportsTerminalOutput?: boolean;
8
+ toolUseId?: string;
9
+ }): ToolInfo;
10
+ declare function toolUpdateFromEditToolResponse(toolResponse: unknown): {
11
+ content: ToolCallContent[];
12
+ locations: ToolCallLocation[];
13
+ } | null;
14
+ declare function toolUpdateFromToolResult(toolResult: ToolResultBlockParam | BetaWebSearchToolResultBlockParam | BetaWebFetchToolResultBlockParam | WebSearchToolResultBlockParam | BetaCodeExecutionToolResultBlockParam | BetaBashCodeExecutionToolResultBlockParam | BetaTextEditorCodeExecutionToolResultBlockParam | BetaRequestMCPToolResultBlockParam | BetaToolSearchToolResultBlockParam, toolUse: Pick<ToolUseBlock, "name" | "input"> | undefined, options?: {
15
+ supportsTerminalOutput?: boolean;
16
+ toolUseId?: string;
17
+ }): Pick<ToolCallUpdate, "title" | "content" | "locations" | "_meta">;
32
18
  type ClaudePlanEntry = {
33
19
  content: string;
34
20
  status: "pending" | "in_progress" | "completed";
@@ -38,4 +24,4 @@ declare function planEntries(input: {
38
24
  todos: ClaudePlanEntry[];
39
25
  }): PlanEntry[];
40
26
 
41
- export { type ClaudePlanEntry, planEntries, toolInfoFromToolUse, toolUpdateFromToolResult };
27
+ export { type ClaudePlanEntry, planEntries, toolInfoFromToolUse, toolUpdateFromEditToolResponse, toolUpdateFromToolResult };
@@ -35,59 +35,6 @@ function toolContent() {
35
35
  return new ToolContentBuilder();
36
36
  }
37
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
38
  // src/adapters/claude/mcp/tool-metadata.ts
92
39
  var mcpToolMetadataCache = /* @__PURE__ */ new Map();
93
40
  function getMcpToolMetadata(toolName) {
@@ -100,79 +47,7 @@ var SYSTEM_REMINDER = `
100
47
  <system-reminder>
101
48
  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.
102
49
  </system-reminder>`;
103
- function replaceAndCalculateLocation(fileContent, edits) {
104
- let currentContent = fileContent;
105
- const randomHex = Array.from(crypto.getRandomValues(new Uint8Array(5))).map((b) => b.toString(16).padStart(2, "0")).join("");
106
- const markerPrefix = `__REPLACE_MARKER_${randomHex}_`;
107
- let markerCounter = 0;
108
- const markers = [];
109
- for (const edit of edits) {
110
- if (edit.oldText === "") {
111
- throw new Error(
112
- `The provided \`old_string\` is empty.
113
-
114
- No edits were applied.`
115
- );
116
- }
117
- if (edit.replaceAll) {
118
- const parts = [];
119
- let lastIndex = 0;
120
- let searchIndex = 0;
121
- while (true) {
122
- const index = currentContent.indexOf(edit.oldText, searchIndex);
123
- if (index === -1) {
124
- if (searchIndex === 0) {
125
- throw new Error(
126
- `The provided \`old_string\` does not appear in the file: "${edit.oldText}".
127
-
128
- No edits were applied.`
129
- );
130
- }
131
- break;
132
- }
133
- parts.push(currentContent.substring(lastIndex, index));
134
- const marker = `${markerPrefix}${markerCounter++}__`;
135
- markers.push(marker);
136
- parts.push(marker + edit.newText);
137
- lastIndex = index + edit.oldText.length;
138
- searchIndex = lastIndex;
139
- }
140
- parts.push(currentContent.substring(lastIndex));
141
- currentContent = parts.join("");
142
- } else {
143
- const index = currentContent.indexOf(edit.oldText);
144
- if (index === -1) {
145
- throw new Error(
146
- `The provided \`old_string\` does not appear in the file: "${edit.oldText}".
147
-
148
- No edits were applied.`
149
- );
150
- } else {
151
- const marker = `${markerPrefix}${markerCounter++}__`;
152
- markers.push(marker);
153
- currentContent = currentContent.substring(0, index) + marker + edit.newText + currentContent.substring(index + edit.oldText.length);
154
- }
155
- }
156
- }
157
- const lineNumbers = [];
158
- for (const marker of markers) {
159
- const index = currentContent.indexOf(marker);
160
- if (index !== -1) {
161
- const lineNumber = Math.max(
162
- 0,
163
- currentContent.substring(0, index).split(/\r\n|\r|\n/).length - 1
164
- );
165
- lineNumbers.push(lineNumber);
166
- }
167
- }
168
- let finalContent = currentContent;
169
- for (const marker of markers) {
170
- finalContent = finalContent.replace(marker, "");
171
- }
172
- const uniqueLineNumbers = [...new Set(lineNumbers)].sort();
173
- return { newContent: finalContent, lineNumbers: uniqueLineNumbers };
174
- }
175
- function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ debug: false, prefix: "[ClaudeTools]" })) {
50
+ function toolInfoFromToolUse(toolUse, options) {
176
51
  const name = toolUse.name;
177
52
  const input = toolUse.input;
178
53
  switch (name) {
@@ -197,6 +72,13 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
197
72
  locations: input?.notebook_path ? [{ path: String(input.notebook_path) }] : []
198
73
  };
199
74
  case "Bash":
75
+ if (options?.supportsTerminalOutput && options?.toolUseId) {
76
+ return {
77
+ title: input?.description ? String(input.description) : "Execute command",
78
+ kind: "execute",
79
+ content: [{ type: "terminal", terminalId: options.toolUseId }]
80
+ };
81
+ }
200
82
  return {
201
83
  title: input?.description ? String(input.description) : "Execute command",
202
84
  kind: "execute",
@@ -217,11 +99,11 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
217
99
  case "Read": {
218
100
  let limit = "";
219
101
  const inputLimit = input?.limit;
220
- const inputOffset = input?.offset ?? 0;
102
+ const inputOffset = input?.offset ?? 1;
221
103
  if (inputLimit) {
222
- limit = ` (${inputOffset + 1} - ${inputOffset + inputLimit})`;
223
- } else if (inputOffset) {
224
- limit = ` (from line ${inputOffset + 1})`;
104
+ limit = ` (${inputOffset} - ${inputOffset + inputLimit - 1})`;
105
+ } else if (inputOffset > 1) {
106
+ limit = ` (from line ${inputOffset})`;
225
107
  }
226
108
  return {
227
109
  title: `Read ${input?.file_path ? String(input.file_path) : "File"}${limit}`,
@@ -244,26 +126,8 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
244
126
  };
245
127
  case "Edit": {
246
128
  const path = input?.file_path ? String(input.file_path) : void 0;
247
- let oldText = input?.old_string ? String(input.old_string) : null;
248
- let newText = input?.new_string ? String(input.new_string) : "";
249
- let affectedLines = [];
250
- if (path && oldText) {
251
- try {
252
- const oldContent = cachedFileContent[path] || "";
253
- const newContent = replaceAndCalculateLocation(oldContent, [
254
- {
255
- oldText,
256
- newText,
257
- replaceAll: false
258
- }
259
- ]);
260
- oldText = oldContent;
261
- newText = newContent.newContent;
262
- affectedLines = newContent.lineNumbers;
263
- } catch (e) {
264
- logger.error("Failed to edit file", e);
265
- }
266
- }
129
+ const oldText = input?.old_string ? String(input.old_string) : null;
130
+ const newText = input?.new_string ? String(input.new_string) : "";
267
131
  return {
268
132
  title: path ? `Edit \`${path}\`` : "Edit",
269
133
  kind: "edit",
@@ -275,7 +139,7 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
275
139
  newText
276
140
  }
277
141
  ] : [],
278
- locations: path ? affectedLines.length > 0 ? affectedLines.map((line) => ({ line, path })) : [{ path }] : []
142
+ locations: path ? [{ path }] : []
279
143
  };
280
144
  }
281
145
  case "Write": {
@@ -329,10 +193,10 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
329
193
  }
330
194
  if (input?.output_mode) {
331
195
  switch (input.output_mode) {
332
- case "FilesWithMatches":
196
+ case "files_with_matches":
333
197
  label += " -l";
334
198
  break;
335
- case "Count":
199
+ case "count":
336
200
  label += " -c";
337
201
  break;
338
202
  default:
@@ -351,7 +215,9 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
351
215
  if (input?.multiline) {
352
216
  label += " -P";
353
217
  }
354
- label += ` "${input?.pattern ? String(input.pattern) : ""}"`;
218
+ if (input?.pattern) {
219
+ label += ` "${String(input.pattern)}"`;
220
+ }
355
221
  if (input?.path) {
356
222
  label += ` ${String(input.path)}`;
357
223
  }
@@ -445,7 +311,49 @@ function mcpToolInfo(name, _input) {
445
311
  content: []
446
312
  };
447
313
  }
448
- function toolUpdateFromToolResult(toolResult, toolUse) {
314
+ function toolUpdateFromEditToolResponse(toolResponse) {
315
+ if (!toolResponse || typeof toolResponse !== "object") return null;
316
+ const response = toolResponse;
317
+ const patches = response.structuredPatch;
318
+ if (!Array.isArray(patches) || patches.length === 0) return null;
319
+ const content = [];
320
+ const locations = [];
321
+ for (const patch of patches) {
322
+ if (!patch.hunks || patch.hunks.length === 0) continue;
323
+ const filePath = patch.newFileName || patch.oldFileName;
324
+ const oldLines = [];
325
+ const newLines = [];
326
+ for (const hunk of patch.hunks) {
327
+ for (const line of hunk.lines) {
328
+ if (line.startsWith("-")) {
329
+ oldLines.push(line.slice(1));
330
+ } else if (line.startsWith("+")) {
331
+ newLines.push(line.slice(1));
332
+ } else if (line.startsWith(" ")) {
333
+ oldLines.push(line.slice(1));
334
+ newLines.push(line.slice(1));
335
+ }
336
+ }
337
+ }
338
+ content.push({
339
+ type: "diff",
340
+ path: filePath,
341
+ oldText: oldLines.join("\n"),
342
+ newText: newLines.join("\n")
343
+ });
344
+ const firstHunk = patch.hunks[0];
345
+ locations.push({
346
+ path: filePath,
347
+ line: firstHunk.newStart
348
+ });
349
+ }
350
+ if (content.length === 0) return null;
351
+ return { content, locations };
352
+ }
353
+ function toolUpdateFromToolResult(toolResult, toolUse, options) {
354
+ if ("is_error" in toolResult && toolResult.is_error && toolResult.content && toolResult.content.length > 0) {
355
+ return toAcpContentUpdate(toolResult.content, true);
356
+ }
449
357
  switch (toolUse?.name) {
450
358
  case "Read":
451
359
  if (Array.isArray(toolResult.content) && toolResult.content.length > 0) {
@@ -462,6 +370,16 @@ function toolUpdateFromToolResult(toolResult, toolUse) {
462
370
  )
463
371
  };
464
372
  }
373
+ if (itemObj.type === "image" && itemObj.source) {
374
+ return {
375
+ type: "content",
376
+ content: {
377
+ type: "image",
378
+ data: itemObj.source.data ?? "",
379
+ mimeType: itemObj.source.media_type ?? "image/png"
380
+ }
381
+ };
382
+ }
465
383
  return {
466
384
  type: "content",
467
385
  content: item
@@ -477,18 +395,51 @@ function toolUpdateFromToolResult(toolResult, toolUse) {
477
395
  }
478
396
  return {};
479
397
  case "Bash": {
480
- return toAcpContentUpdate(
481
- toolResult.content,
482
- "is_error" in toolResult ? toolResult.is_error : false
483
- );
484
- }
485
- case "Edit":
486
- case "Write": {
487
- if ("is_error" in toolResult && toolResult.is_error && toolResult.content && toolResult.content.length > 0) {
488
- return toAcpContentUpdate(toolResult.content, true);
398
+ const result = toolResult.content;
399
+ const terminalId = "tool_use_id" in toolResult ? String(toolResult.tool_use_id) : "";
400
+ const isError = "is_error" in toolResult && toolResult.is_error;
401
+ let output = "";
402
+ let exitCode = isError ? 1 : 0;
403
+ if (result && typeof result === "object" && "type" in result && result.type === "bash_code_execution_result") {
404
+ const bashResult = result;
405
+ output = [bashResult.stdout, bashResult.stderr].filter(Boolean).join("\n");
406
+ exitCode = bashResult.return_code;
407
+ } else if (typeof result === "string") {
408
+ output = result;
409
+ } else if (Array.isArray(result) && result.length > 0 && "text" in result[0] && typeof result[0].text === "string") {
410
+ output = result.map((c) => c.text ?? "").join("\n");
411
+ }
412
+ if (options?.supportsTerminalOutput) {
413
+ return {
414
+ content: [{ type: "terminal", terminalId }],
415
+ _meta: {
416
+ terminal_info: {
417
+ terminal_id: terminalId
418
+ },
419
+ terminal_output: {
420
+ terminal_id: terminalId,
421
+ data: output
422
+ },
423
+ terminal_exit: {
424
+ terminal_id: terminalId,
425
+ exit_code: exitCode,
426
+ signal: null
427
+ }
428
+ }
429
+ };
430
+ }
431
+ if (output.trim()) {
432
+ return {
433
+ content: toolContent().text(`\`\`\`console
434
+ ${output.trimEnd()}
435
+ \`\`\``).build()
436
+ };
489
437
  }
490
438
  return {};
491
439
  }
440
+ case "Edit":
441
+ case "Write":
442
+ return {};
492
443
  case "ExitPlanMode": {
493
444
  return { title: "Exited Plan Mode" };
494
445
  }
@@ -601,6 +552,7 @@ ${text2}${text2.endsWith("\n") ? "" : "\n"}${escapedText}`;
601
552
  export {
602
553
  planEntries,
603
554
  toolInfoFromToolUse,
555
+ toolUpdateFromEditToolResponse,
604
556
  toolUpdateFromToolResult
605
557
  };
606
558
  //# sourceMappingURL=tool-use-to-acp.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/acp-content.ts","../../../../src/utils/logger.ts","../../../../src/adapters/claude/mcp/tool-metadata.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 { McpServerStatus, Query } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Logger } from \"../../../utils/logger.js\";\n\nexport interface McpToolMetadata {\n readOnly: boolean;\n name: string;\n description?: string;\n}\n\nconst mcpToolMetadataCache: Map<string, McpToolMetadata> = new Map();\n\nconst PENDING_RETRY_INTERVAL_MS = 1_000;\nconst PENDING_MAX_RETRIES = 10;\n\nfunction buildToolKey(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function fetchMcpToolMetadata(\n q: Query,\n logger: Logger = new Logger({ debug: false, prefix: \"[McpToolMetadata]\" }),\n): Promise<void> {\n let retries = 0;\n\n while (retries <= PENDING_MAX_RETRIES) {\n let statuses: McpServerStatus[];\n try {\n statuses = await q.mcpServerStatus();\n } catch (error) {\n logger.error(\"Failed to fetch MCP server status\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return;\n }\n\n const pendingServers = statuses.filter((s) => s.status === \"pending\");\n\n for (const server of statuses) {\n if (server.status !== \"connected\" || !server.tools) {\n continue;\n }\n\n let readOnlyCount = 0;\n for (const tool of server.tools) {\n const toolKey = buildToolKey(server.name, tool.name);\n const readOnly = tool.annotations?.readOnly === true;\n mcpToolMetadataCache.set(toolKey, {\n readOnly,\n name: tool.name,\n description: tool.description,\n });\n if (readOnly) readOnlyCount++;\n }\n\n logger.info(\"Fetched MCP tool metadata\", {\n serverName: server.name,\n toolCount: server.tools.length,\n readOnlyCount,\n });\n }\n\n if (pendingServers.length === 0) {\n return;\n }\n\n retries++;\n if (retries > PENDING_MAX_RETRIES) {\n logger.warn(\"Gave up waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n });\n return;\n }\n\n logger.info(\"Waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n retry: retries,\n });\n await delay(PENDING_RETRY_INTERVAL_MS);\n }\n}\n\nexport function getMcpToolMetadata(\n toolName: string,\n): McpToolMetadata | undefined {\n return mcpToolMetadataCache.get(toolName);\n}\n\nexport function isMcpToolReadOnly(toolName: string): boolean {\n const metadata = mcpToolMetadataCache.get(toolName);\n return metadata?.readOnly === true;\n}\n\nexport function clearMcpToolMetadataCache(): void {\n mcpToolMetadataCache.clear();\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\";\nimport { getMcpToolMetadata } from \"../mcp/tool-metadata.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 if (name?.startsWith(\"mcp__\")) {\n return mcpToolInfo(name, input);\n }\n return {\n title: name || \"Unknown Tool\",\n kind: \"other\",\n content: [],\n };\n }\n }\n}\n\nfunction mcpToolInfo(\n name: string,\n _input: Record<string, unknown> | undefined,\n): ToolInfo {\n const metadata = getMcpToolMetadata(name);\n // Fallback: parse tool name from mcp__<server>__<tool> prefix\n const title =\n metadata?.name ?? (name.split(\"__\").slice(2).join(\"__\") || name);\n\n return {\n title,\n kind: \"other\",\n content: [],\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 case \"WebFetch\": {\n const input = toolUse?.input as Record<string, unknown> | undefined;\n const url = input?.url ? String(input.url) : \"\";\n const prompt = input?.prompt ? String(input.prompt) : undefined;\n\n const resultContent = toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n\n const content: ToolCallContent[] = [];\n if (url) {\n content.push({\n type: \"content\",\n content: resourceLink(url, url, {\n description: prompt,\n }),\n });\n }\n if (resultContent.content) {\n content.push(...resultContent.content);\n }\n\n return { content };\n }\n default: {\n return toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n }\n }\n}\n\nfunction itemToText(item: unknown): string | null {\n if (!item || typeof item !== \"object\") return null;\n const obj = item as Record<string, unknown>;\n // Standard text block\n if (obj.type === \"text\" && typeof obj.text === \"string\") {\n return obj.text;\n }\n // Any other structured object — serialize it\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return null;\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 const texts: string[] = [];\n for (const item of content) {\n const t = itemToText(item);\n if (t) texts.push(t);\n }\n if (texts.length > 0) {\n const combined = texts.join(\"\\n\");\n return {\n content: toolContent()\n .text(isError ? `\\`\\`\\`\\n${combined}\\n\\`\\`\\`` : combined)\n .build(),\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 } else if (content && typeof content === \"object\") {\n try {\n const json = JSON.stringify(content, null, 2);\n if (json && json !== \"{}\") {\n return {\n content: toolContent().text(json).build(),\n };\n }\n } catch {\n // ignore serialization errors\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"]}
1
+ {"version":3,"sources":["../../../../src/utils/acp-content.ts","../../../../src/adapters/claude/mcp/tool-metadata.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 { McpServerStatus, Query } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Logger } from \"../../../utils/logger.js\";\n\nexport interface McpToolMetadata {\n readOnly: boolean;\n name: string;\n description?: string;\n}\n\nconst mcpToolMetadataCache: Map<string, McpToolMetadata> = new Map();\n\nconst PENDING_RETRY_INTERVAL_MS = 1_000;\nconst PENDING_MAX_RETRIES = 10;\n\nfunction buildToolKey(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function fetchMcpToolMetadata(\n q: Query,\n logger: Logger = new Logger({ debug: false, prefix: \"[McpToolMetadata]\" }),\n): Promise<void> {\n let retries = 0;\n\n while (retries <= PENDING_MAX_RETRIES) {\n let statuses: McpServerStatus[];\n try {\n statuses = await q.mcpServerStatus();\n } catch (error) {\n logger.error(\"Failed to fetch MCP server status\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return;\n }\n\n const pendingServers = statuses.filter((s) => s.status === \"pending\");\n\n for (const server of statuses) {\n if (server.status !== \"connected\" || !server.tools) {\n continue;\n }\n\n let readOnlyCount = 0;\n for (const tool of server.tools) {\n const toolKey = buildToolKey(server.name, tool.name);\n const readOnly = tool.annotations?.readOnly === true;\n mcpToolMetadataCache.set(toolKey, {\n readOnly,\n name: tool.name,\n description: tool.description,\n });\n if (readOnly) readOnlyCount++;\n }\n\n logger.info(\"Fetched MCP tool metadata\", {\n serverName: server.name,\n toolCount: server.tools.length,\n readOnlyCount,\n });\n }\n\n if (pendingServers.length === 0) {\n return;\n }\n\n retries++;\n if (retries > PENDING_MAX_RETRIES) {\n logger.warn(\"Gave up waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n });\n return;\n }\n\n logger.info(\"Waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n retry: retries,\n });\n await delay(PENDING_RETRY_INTERVAL_MS);\n }\n}\n\nexport function getMcpToolMetadata(\n toolName: string,\n): McpToolMetadata | undefined {\n return mcpToolMetadataCache.get(toolName);\n}\n\nexport function isMcpToolReadOnly(toolName: string): boolean {\n const metadata = mcpToolMetadataCache.get(toolName);\n return metadata?.readOnly === true;\n}\n\nexport function clearMcpToolMetadataCache(): void {\n mcpToolMetadataCache.clear();\n}\n","import type {\n PlanEntry,\n ToolCall,\n ToolCallContent,\n ToolCallLocation,\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 { getMcpToolMetadata } from \"../mcp/tool-metadata.js\";\n\ntype ToolInfo = Pick<ToolCall, \"title\" | \"kind\" | \"content\" | \"locations\">;\n\nexport function toolInfoFromToolUse(\n toolUse: Pick<ToolUseBlock, \"name\" | \"input\">,\n options?: { supportsTerminalOutput?: boolean; toolUseId?: string },\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 if (options?.supportsTerminalOutput && options?.toolUseId) {\n return {\n title: input?.description\n ? String(input.description)\n : \"Execute command\",\n kind: \"execute\",\n content: [{ type: \"terminal\", terminalId: options.toolUseId }],\n };\n }\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) ?? 1;\n if (inputLimit) {\n limit = ` (${inputOffset} - ${inputOffset + inputLimit - 1})`;\n } else if (inputOffset > 1) {\n limit = ` (from line ${inputOffset})`;\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 const oldText = input?.old_string ? String(input.old_string) : null;\n const newText = input?.new_string ? String(input.new_string) : \"\";\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 ? [{ path }] : [],\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 \"files_with_matches\":\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 if (input?.pattern) {\n label += ` \"${String(input.pattern)}\"`;\n }\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 if (name?.startsWith(\"mcp__\")) {\n return mcpToolInfo(name, input);\n }\n return {\n title: name || \"Unknown Tool\",\n kind: \"other\",\n content: [],\n };\n }\n }\n}\n\nfunction mcpToolInfo(\n name: string,\n _input: Record<string, unknown> | undefined,\n): ToolInfo {\n const metadata = getMcpToolMetadata(name);\n // Fallback: parse tool name from mcp__<server>__<tool> prefix\n const title =\n metadata?.name ?? (name.split(\"__\").slice(2).join(\"__\") || name);\n\n return {\n title,\n kind: \"other\",\n content: [],\n };\n}\n\ninterface StructuredPatchHunk {\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n lines: string[];\n}\n\ninterface StructuredPatch {\n oldFileName: string;\n newFileName: string;\n hunks: StructuredPatchHunk[];\n}\n\nexport function toolUpdateFromEditToolResponse(\n toolResponse: unknown,\n): { content: ToolCallContent[]; locations: ToolCallLocation[] } | null {\n if (!toolResponse || typeof toolResponse !== \"object\") return null;\n const response = toolResponse as Record<string, unknown>;\n\n const patches = response.structuredPatch as StructuredPatch[] | undefined;\n if (!Array.isArray(patches) || patches.length === 0) return null;\n\n const content: ToolCallContent[] = [];\n const locations: ToolCallLocation[] = [];\n\n for (const patch of patches) {\n if (!patch.hunks || patch.hunks.length === 0) continue;\n\n const filePath = patch.newFileName || patch.oldFileName;\n\n const oldLines: string[] = [];\n const newLines: string[] = [];\n for (const hunk of patch.hunks) {\n for (const line of hunk.lines) {\n if (line.startsWith(\"-\")) {\n oldLines.push(line.slice(1));\n } else if (line.startsWith(\"+\")) {\n newLines.push(line.slice(1));\n } else if (line.startsWith(\" \")) {\n oldLines.push(line.slice(1));\n newLines.push(line.slice(1));\n }\n }\n }\n\n content.push({\n type: \"diff\",\n path: filePath,\n oldText: oldLines.join(\"\\n\"),\n newText: newLines.join(\"\\n\"),\n });\n\n const firstHunk = patch.hunks[0];\n locations.push({\n path: filePath,\n line: firstHunk.newStart,\n });\n }\n\n if (content.length === 0) return null;\n return { content, locations };\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 options?: { supportsTerminalOutput?: boolean; toolUseId?: string },\n): Pick<ToolCallUpdate, \"title\" | \"content\" | \"locations\" | \"_meta\"> {\n if (\n \"is_error\" in toolResult &&\n toolResult.is_error &&\n toolResult.content &&\n (toolResult.content as unknown[]).length > 0\n ) {\n return toAcpContentUpdate(toolResult.content, true);\n }\n\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 {\n type?: string;\n text?: string;\n source?: { data?: string; media_type?: string };\n };\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 if (itemObj.type === \"image\" && itemObj.source) {\n return {\n type: \"content\" as const,\n content: {\n type: \"image\" as const,\n data: itemObj.source.data ?? \"\",\n mimeType: itemObj.source.media_type ?? \"image/png\",\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 const result = toolResult.content;\n const terminalId =\n \"tool_use_id\" in toolResult ? String(toolResult.tool_use_id) : \"\";\n const isError = \"is_error\" in toolResult && toolResult.is_error;\n\n let output = \"\";\n let exitCode = isError ? 1 : 0;\n\n if (\n result &&\n typeof result === \"object\" &&\n \"type\" in result &&\n (result as { type: string }).type === \"bash_code_execution_result\"\n ) {\n const bashResult = result as {\n stdout?: string;\n stderr?: string;\n return_code: number;\n };\n output = [bashResult.stdout, bashResult.stderr]\n .filter(Boolean)\n .join(\"\\n\");\n exitCode = bashResult.return_code;\n } else if (typeof result === \"string\") {\n output = result;\n } else if (\n Array.isArray(result) &&\n result.length > 0 &&\n \"text\" in result[0] &&\n typeof result[0].text === \"string\"\n ) {\n output = result.map((c: { text?: string }) => c.text ?? \"\").join(\"\\n\");\n }\n\n if (options?.supportsTerminalOutput) {\n return {\n content: [{ type: \"terminal\" as const, terminalId }],\n _meta: {\n terminal_info: {\n terminal_id: terminalId,\n },\n terminal_output: {\n terminal_id: terminalId,\n data: output,\n },\n terminal_exit: {\n terminal_id: terminalId,\n exit_code: exitCode,\n signal: null,\n },\n },\n };\n }\n if (output.trim()) {\n return {\n content: toolContent()\n .text(`\\`\\`\\`console\\n${output.trimEnd()}\\n\\`\\`\\``)\n .build(),\n };\n }\n return {};\n }\n case \"Edit\":\n case \"Write\":\n return {};\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 case \"WebFetch\": {\n const input = toolUse?.input as Record<string, unknown> | undefined;\n const url = input?.url ? String(input.url) : \"\";\n const prompt = input?.prompt ? String(input.prompt) : undefined;\n\n const resultContent = toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n\n const content: ToolCallContent[] = [];\n if (url) {\n content.push({\n type: \"content\",\n content: resourceLink(url, url, {\n description: prompt,\n }),\n });\n }\n if (resultContent.content) {\n content.push(...resultContent.content);\n }\n\n return { content };\n }\n default: {\n return toAcpContentUpdate(\n toolResult.content,\n \"is_error\" in toolResult ? toolResult.is_error : false,\n );\n }\n }\n}\n\nfunction itemToText(item: unknown): string | null {\n if (!item || typeof item !== \"object\") return null;\n const obj = item as Record<string, unknown>;\n // Standard text block\n if (obj.type === \"text\" && typeof obj.text === \"string\") {\n return obj.text;\n }\n // Any other structured object — serialize it\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return null;\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 const texts: string[] = [];\n for (const item of content) {\n const t = itemToText(item);\n if (t) texts.push(t);\n }\n if (texts.length > 0) {\n const combined = texts.join(\"\\n\");\n return {\n content: toolContent()\n .text(isError ? `\\`\\`\\`\\n${combined}\\n\\`\\`\\`` : combined)\n .build(),\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 } else if (content && typeof content === \"object\") {\n try {\n const json = JSON.stringify(content, null, 2);\n if (json && json !== \"{}\") {\n return {\n content: toolContent().text(json).build(),\n };\n }\n } catch {\n // ignore serialization errors\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"]}
@@ -1,6 +1,38 @@
1
1
  // src/utils/common.ts
2
2
  var IS_ROOT = typeof process !== "undefined" && (process.geteuid?.() ?? process.getuid?.()) === 0;
3
3
 
4
+ // src/execution-mode.ts
5
+ var ALLOW_BYPASS = !IS_ROOT;
6
+ var availableModes = [
7
+ {
8
+ id: "default",
9
+ name: "Default",
10
+ description: "Standard behavior, prompts for dangerous operations"
11
+ },
12
+ {
13
+ id: "acceptEdits",
14
+ name: "Accept Edits",
15
+ description: "Auto-accept file edit operations"
16
+ },
17
+ {
18
+ id: "plan",
19
+ name: "Plan Mode",
20
+ description: "Planning mode, no actual tool execution"
21
+ }
22
+ // {
23
+ // id: "dontAsk",
24
+ // name: "Don't Ask",
25
+ // description: "Don't prompt for permissions, deny if not pre-approved",
26
+ // },
27
+ ];
28
+ if (ALLOW_BYPASS) {
29
+ availableModes.push({
30
+ id: "bypassPermissions",
31
+ name: "Bypass Permissions",
32
+ description: "Bypass all permission checks"
33
+ });
34
+ }
35
+
4
36
  // src/adapters/claude/tools.ts
5
37
  var READ_TOOLS = /* @__PURE__ */ new Set(["Read", "NotebookRead"]);
6
38
  var WRITE_TOOLS = /* @__PURE__ */ new Set([
@@ -26,6 +58,7 @@ var AUTO_ALLOWED_TOOLS = {
26
58
  default: new Set(BASE_ALLOWED_TOOLS),
27
59
  acceptEdits: /* @__PURE__ */ new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),
28
60
  plan: new Set(BASE_ALLOWED_TOOLS)
61
+ // dontAsk: new Set(BASE_ALLOWED_TOOLS),
29
62
  };
30
63
 
31
64
  // src/adapters/claude/permissions/permission-options.ts