@posthog/agent 2.3.735 → 2.3.736
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/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +2 -10
- package/dist/adapters/claude/conversion/tool-use-to-acp.js +24 -10
- package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -1
- package/dist/adapters/claude/permissions/permission-options.js +6 -4
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/session/jsonl-hydration.js +1 -0
- package/dist/adapters/claude/session/jsonl-hydration.js.map +1 -1
- package/dist/adapters/claude/session/models.js +20 -1
- package/dist/adapters/claude/session/models.js.map +1 -1
- package/dist/adapters/claude/tools.js +4 -2
- package/dist/adapters/claude/tools.js.map +1 -1
- package/dist/adapters/reasoning-effort.js +3 -1
- package/dist/adapters/reasoning-effort.js.map +1 -1
- package/dist/agent.js +524 -72
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +4 -4
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +524 -72
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +524 -72
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +6 -6
- package/src/adapters/claude/UPSTREAM.md +80 -3
- package/src/adapters/claude/claude-agent.ts +201 -18
- package/src/adapters/claude/conversion/sdk-to-acp.ts +182 -16
- package/src/adapters/claude/conversion/task-state.test.ts +338 -0
- package/src/adapters/claude/conversion/task-state.ts +178 -0
- package/src/adapters/claude/conversion/tool-use-to-acp.ts +29 -19
- package/src/adapters/claude/hooks.test.ts +162 -0
- package/src/adapters/claude/hooks.ts +44 -3
- package/src/adapters/claude/permissions/permission-options.ts +7 -2
- package/src/adapters/claude/session/commands.ts +1 -0
- package/src/adapters/claude/session/mcp-config.ts +23 -7
- package/src/adapters/claude/session/model-config.test.ts +60 -0
- package/src/adapters/claude/session/model-config.ts +56 -0
- package/src/adapters/claude/session/models.test.ts +119 -0
- package/src/adapters/claude/session/models.ts +31 -0
- package/src/adapters/claude/session/options.test.ts +1 -0
- package/src/adapters/claude/session/options.ts +29 -1
- package/src/adapters/claude/session/settings.test.ts +102 -1
- package/src/adapters/claude/session/settings.ts +33 -6
- package/src/adapters/claude/tools.ts +4 -2
- package/src/adapters/claude/types.ts +8 -0
- package/src/adapters/codex/codex-agent.ts +2 -2
- package/src/server/agent-server.test.ts +173 -0
- package/src/test/mocks/claude-sdk.ts +4 -0
- package/src/test/native-binary.test.ts +27 -0
- package/dist/claude-cli/cli.js +0 -18412
- package/dist/claude-cli/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/COPYING +0 -3
- package/dist/claude-cli/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-win32/rg.exe +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/dist/claude-cli/yoga.wasm +0 -0
|
@@ -9315,7 +9315,7 @@ import { z as z5 } from "zod";
|
|
|
9315
9315
|
// package.json
|
|
9316
9316
|
var package_default = {
|
|
9317
9317
|
name: "@posthog/agent",
|
|
9318
|
-
version: "2.3.
|
|
9318
|
+
version: "2.3.736",
|
|
9319
9319
|
repository: "https://github.com/PostHog/code",
|
|
9320
9320
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
9321
9321
|
exports: {
|
|
@@ -9435,9 +9435,9 @@ var package_default = {
|
|
|
9435
9435
|
vitest: "^2.1.8"
|
|
9436
9436
|
},
|
|
9437
9437
|
dependencies: {
|
|
9438
|
-
"@agentclientprotocol/sdk": "0.
|
|
9439
|
-
"@anthropic-ai/claude-agent-sdk": "0.
|
|
9440
|
-
"@anthropic-ai/sdk": "0.
|
|
9438
|
+
"@agentclientprotocol/sdk": "0.22.1",
|
|
9439
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.154",
|
|
9440
|
+
"@anthropic-ai/sdk": "0.100.0",
|
|
9441
9441
|
"@hono/node-server": "^1.19.9",
|
|
9442
9442
|
"@opentelemetry/api-logs": "^0.208.0",
|
|
9443
9443
|
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
|
|
@@ -15157,6 +15157,30 @@ var registerHookCallback = (toolUseID, {
|
|
|
15157
15157
|
onPostToolUseHook
|
|
15158
15158
|
};
|
|
15159
15159
|
};
|
|
15160
|
+
var createTaskHook = (taskState, onChange) => async (input) => {
|
|
15161
|
+
const taskId = "task_id" in input && typeof input.task_id === "string" ? input.task_id : void 0;
|
|
15162
|
+
if (!taskId) return { continue: true };
|
|
15163
|
+
let mutated = false;
|
|
15164
|
+
if (input.hook_event_name === "TaskCreated") {
|
|
15165
|
+
if (!input.task_subject) return { continue: true };
|
|
15166
|
+
if (taskState.has(taskId)) return { continue: true };
|
|
15167
|
+
taskState.set(taskId, {
|
|
15168
|
+
subject: input.task_subject,
|
|
15169
|
+
status: "pending",
|
|
15170
|
+
description: input.task_description
|
|
15171
|
+
});
|
|
15172
|
+
mutated = true;
|
|
15173
|
+
} else if (input.hook_event_name === "TaskCompleted") {
|
|
15174
|
+
const existing = taskState.get(taskId);
|
|
15175
|
+
if (!existing || existing.status === "completed") {
|
|
15176
|
+
return { continue: true };
|
|
15177
|
+
}
|
|
15178
|
+
taskState.set(taskId, { ...existing, status: "completed" });
|
|
15179
|
+
mutated = true;
|
|
15180
|
+
}
|
|
15181
|
+
if (mutated && onChange) await onChange();
|
|
15182
|
+
return { continue: true };
|
|
15183
|
+
};
|
|
15160
15184
|
var createPostToolUseHook = ({ onModeChange }) => async (input, toolUseID) => {
|
|
15161
15185
|
if (input.hook_event_name === "PostToolUse") {
|
|
15162
15186
|
const toolName = input.tool_name;
|
|
@@ -15171,10 +15195,8 @@ var createPostToolUseHook = ({ onModeChange }) => async (input, toolUseID) => {
|
|
|
15171
15195
|
input.tool_input,
|
|
15172
15196
|
input.tool_response
|
|
15173
15197
|
);
|
|
15174
|
-
delete toolUseCallbacks[toolUseID];
|
|
15175
|
-
} else {
|
|
15176
|
-
delete toolUseCallbacks[toolUseID];
|
|
15177
15198
|
}
|
|
15199
|
+
delete toolUseCallbacks[toolUseID];
|
|
15178
15200
|
}
|
|
15179
15201
|
}
|
|
15180
15202
|
return { continue: true };
|
|
@@ -15321,6 +15343,104 @@ var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID
|
|
|
15321
15343
|
}
|
|
15322
15344
|
};
|
|
15323
15345
|
|
|
15346
|
+
// src/adapters/claude/conversion/task-state.ts
|
|
15347
|
+
function parseTaskCreateOutput(content) {
|
|
15348
|
+
const tryParse = (text2) => {
|
|
15349
|
+
try {
|
|
15350
|
+
const parsed = JSON.parse(text2);
|
|
15351
|
+
if (parsed && typeof parsed === "object" && parsed.task && typeof parsed.task.id === "string") {
|
|
15352
|
+
return parsed;
|
|
15353
|
+
}
|
|
15354
|
+
} catch {
|
|
15355
|
+
}
|
|
15356
|
+
return void 0;
|
|
15357
|
+
};
|
|
15358
|
+
if (typeof content === "string") {
|
|
15359
|
+
return tryParse(content);
|
|
15360
|
+
}
|
|
15361
|
+
if (Array.isArray(content)) {
|
|
15362
|
+
for (const block of content) {
|
|
15363
|
+
if (block && typeof block === "object" && "type" in block && block.type === "text") {
|
|
15364
|
+
const text2 = block.text;
|
|
15365
|
+
if (typeof text2 === "string") {
|
|
15366
|
+
const parsed = tryParse(text2);
|
|
15367
|
+
if (parsed) return parsed;
|
|
15368
|
+
}
|
|
15369
|
+
}
|
|
15370
|
+
}
|
|
15371
|
+
}
|
|
15372
|
+
return void 0;
|
|
15373
|
+
}
|
|
15374
|
+
function applyTaskCreate(state, input, output) {
|
|
15375
|
+
const taskId = output?.task?.id;
|
|
15376
|
+
if (!taskId || !input) return;
|
|
15377
|
+
state.set(taskId, {
|
|
15378
|
+
subject: input.subject,
|
|
15379
|
+
status: "pending",
|
|
15380
|
+
activeForm: input.activeForm,
|
|
15381
|
+
description: input.description
|
|
15382
|
+
});
|
|
15383
|
+
}
|
|
15384
|
+
function applyTaskUpdate(state, input) {
|
|
15385
|
+
if (!input?.taskId) return;
|
|
15386
|
+
if (input.status === "deleted") {
|
|
15387
|
+
state.delete(input.taskId);
|
|
15388
|
+
return;
|
|
15389
|
+
}
|
|
15390
|
+
const existing = state.get(input.taskId);
|
|
15391
|
+
const subject = input.subject ?? existing?.subject;
|
|
15392
|
+
if (!subject) return;
|
|
15393
|
+
state.set(input.taskId, {
|
|
15394
|
+
subject,
|
|
15395
|
+
status: input.status ?? existing?.status ?? "pending",
|
|
15396
|
+
activeForm: input.activeForm ?? existing?.activeForm,
|
|
15397
|
+
description: input.description ?? existing?.description
|
|
15398
|
+
});
|
|
15399
|
+
}
|
|
15400
|
+
function taskStateToPlanEntries(state) {
|
|
15401
|
+
return Array.from(state.values()).map((task) => ({
|
|
15402
|
+
content: task.subject,
|
|
15403
|
+
status: task.status,
|
|
15404
|
+
priority: "medium"
|
|
15405
|
+
}));
|
|
15406
|
+
}
|
|
15407
|
+
function isToolUseBlock(block) {
|
|
15408
|
+
return !!block && typeof block === "object" && block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string";
|
|
15409
|
+
}
|
|
15410
|
+
function isToolResultBlock(block) {
|
|
15411
|
+
return !!block && typeof block === "object" && block.type === "tool_result" && typeof block.tool_use_id === "string";
|
|
15412
|
+
}
|
|
15413
|
+
function rehydrateTaskState(messages, state) {
|
|
15414
|
+
const pendingInputs = /* @__PURE__ */ new Map();
|
|
15415
|
+
for (const msg of messages) {
|
|
15416
|
+
const content = msg.message?.content;
|
|
15417
|
+
if (!Array.isArray(content)) continue;
|
|
15418
|
+
if (msg.type === "assistant") {
|
|
15419
|
+
for (const block of content) {
|
|
15420
|
+
if (isToolUseBlock(block) && (block.name === "TaskCreate" || block.name === "TaskUpdate")) {
|
|
15421
|
+
pendingInputs.set(block.id, { name: block.name, input: block.input });
|
|
15422
|
+
}
|
|
15423
|
+
}
|
|
15424
|
+
} else if (msg.type === "user") {
|
|
15425
|
+
for (const block of content) {
|
|
15426
|
+
if (!isToolResultBlock(block) || block.is_error) continue;
|
|
15427
|
+
const cached = pendingInputs.get(block.tool_use_id);
|
|
15428
|
+
if (!cached) continue;
|
|
15429
|
+
if (cached.name === "TaskCreate") {
|
|
15430
|
+
applyTaskCreate(
|
|
15431
|
+
state,
|
|
15432
|
+
cached.input,
|
|
15433
|
+
parseTaskCreateOutput(block.content)
|
|
15434
|
+
);
|
|
15435
|
+
} else if (cached.name === "TaskUpdate") {
|
|
15436
|
+
applyTaskUpdate(state, cached.input);
|
|
15437
|
+
}
|
|
15438
|
+
pendingInputs.delete(block.tool_use_id);
|
|
15439
|
+
}
|
|
15440
|
+
}
|
|
15441
|
+
}
|
|
15442
|
+
}
|
|
15443
|
+
|
|
15324
15444
|
// src/adapters/claude/conversion/tool-use-to-acp.ts
|
|
15325
15445
|
import fs6 from "fs";
|
|
15326
15446
|
import path7 from "path";
|
|
@@ -15672,9 +15792,31 @@ function toolInfoFromToolUse(toolUse, options) {
|
|
|
15672
15792
|
content: []
|
|
15673
15793
|
};
|
|
15674
15794
|
}
|
|
15675
|
-
case "
|
|
15795
|
+
case "TaskCreate": {
|
|
15796
|
+
const subject = typeof input?.subject === "string" ? input.subject : void 0;
|
|
15676
15797
|
return {
|
|
15677
|
-
title:
|
|
15798
|
+
title: subject ? `Create task: ${subject}` : "Create task",
|
|
15799
|
+
kind: "think",
|
|
15800
|
+
content: []
|
|
15801
|
+
};
|
|
15802
|
+
}
|
|
15803
|
+
case "TaskUpdate": {
|
|
15804
|
+
const subject = typeof input?.subject === "string" ? input.subject : void 0;
|
|
15805
|
+
return {
|
|
15806
|
+
title: subject ? `Update task: ${subject}` : "Update task",
|
|
15807
|
+
kind: "think",
|
|
15808
|
+
content: []
|
|
15809
|
+
};
|
|
15810
|
+
}
|
|
15811
|
+
case "TaskList":
|
|
15812
|
+
return {
|
|
15813
|
+
title: "List tasks",
|
|
15814
|
+
kind: "think",
|
|
15815
|
+
content: []
|
|
15816
|
+
};
|
|
15817
|
+
case "TaskGet":
|
|
15818
|
+
return {
|
|
15819
|
+
title: "Get task",
|
|
15678
15820
|
kind: "think",
|
|
15679
15821
|
content: []
|
|
15680
15822
|
};
|
|
@@ -15958,13 +16100,6 @@ ${content}
|
|
|
15958
16100
|
}
|
|
15959
16101
|
return {};
|
|
15960
16102
|
}
|
|
15961
|
-
function planEntries(input) {
|
|
15962
|
-
return input.todos.map((input2) => ({
|
|
15963
|
-
content: input2.content,
|
|
15964
|
-
status: input2.status,
|
|
15965
|
-
priority: "medium"
|
|
15966
|
-
}));
|
|
15967
|
-
}
|
|
15968
16103
|
function resolveFileContent(filePath, oldText, cachedFileContent) {
|
|
15969
16104
|
if (cachedFileContent && filePath in cachedFileContent) {
|
|
15970
16105
|
const cached = cachedFileContent[filePath];
|
|
@@ -16050,14 +16185,7 @@ function handleThinkingChunk(chunk, parentToolCallId) {
|
|
|
16050
16185
|
function handleToolUseChunk(chunk, ctx) {
|
|
16051
16186
|
const alreadyCached = chunk.id in ctx.toolUseCache;
|
|
16052
16187
|
ctx.toolUseCache[chunk.id] = chunk;
|
|
16053
|
-
if (chunk.name === "
|
|
16054
|
-
const input = chunk.input;
|
|
16055
|
-
if (Array.isArray(input.todos)) {
|
|
16056
|
-
return {
|
|
16057
|
-
sessionUpdate: "plan",
|
|
16058
|
-
entries: planEntries(chunk.input)
|
|
16059
|
-
};
|
|
16060
|
-
}
|
|
16188
|
+
if (chunk.name === "TaskCreate" || chunk.name === "TaskUpdate" || chunk.name === "TaskList" || chunk.name === "TaskGet") {
|
|
16061
16189
|
return null;
|
|
16062
16190
|
}
|
|
16063
16191
|
if (!alreadyCached && ctx.registerHooks !== false) {
|
|
@@ -16065,7 +16193,7 @@ function handleToolUseChunk(chunk, ctx) {
|
|
|
16065
16193
|
onPostToolUseHook: async (toolUseId, _toolInput, toolResponse) => {
|
|
16066
16194
|
const toolUse = ctx.toolUseCache[toolUseId];
|
|
16067
16195
|
if (toolUse) {
|
|
16068
|
-
const editUpdate = toolUse.name === "Edit" ? toolUpdateFromEditToolResponse(toolResponse) : null;
|
|
16196
|
+
const editUpdate = toolUse.name === "Edit" || toolUse.name === "Write" ? toolUpdateFromEditToolResponse(toolResponse) : null;
|
|
16069
16197
|
await ctx.client.sessionUpdate({
|
|
16070
16198
|
sessionId: ctx.sessionId,
|
|
16071
16199
|
update: {
|
|
@@ -16177,7 +16305,28 @@ function handleToolResultChunk(chunk, ctx) {
|
|
|
16177
16305
|
);
|
|
16178
16306
|
return [];
|
|
16179
16307
|
}
|
|
16180
|
-
if (toolUse.name === "
|
|
16308
|
+
if (toolUse.name === "TaskCreate" || toolUse.name === "TaskUpdate" || toolUse.name === "TaskList" || toolUse.name === "TaskGet") {
|
|
16309
|
+
if (chunk.is_error || !ctx.taskState) return [];
|
|
16310
|
+
if (toolUse.name === "TaskCreate") {
|
|
16311
|
+
applyTaskCreate(
|
|
16312
|
+
ctx.taskState,
|
|
16313
|
+
toolUse.input,
|
|
16314
|
+
parseTaskCreateOutput(chunk.content)
|
|
16315
|
+
);
|
|
16316
|
+
} else if (toolUse.name === "TaskUpdate") {
|
|
16317
|
+
applyTaskUpdate(
|
|
16318
|
+
ctx.taskState,
|
|
16319
|
+
toolUse.input
|
|
16320
|
+
);
|
|
16321
|
+
}
|
|
16322
|
+
if (toolUse.name === "TaskCreate" || toolUse.name === "TaskUpdate") {
|
|
16323
|
+
return [
|
|
16324
|
+
{
|
|
16325
|
+
sessionUpdate: "plan",
|
|
16326
|
+
entries: taskStateToPlanEntries(ctx.taskState)
|
|
16327
|
+
}
|
|
16328
|
+
];
|
|
16329
|
+
}
|
|
16181
16330
|
return [];
|
|
16182
16331
|
}
|
|
16183
16332
|
if (!chunk.is_error) {
|
|
@@ -16274,13 +16423,15 @@ function processContentChunk(chunk, role, ctx) {
|
|
|
16274
16423
|
case "container_upload":
|
|
16275
16424
|
case "compaction":
|
|
16276
16425
|
case "compaction_delta":
|
|
16426
|
+
case "advisor_tool_result":
|
|
16427
|
+
case "mid_conv_system":
|
|
16277
16428
|
return [];
|
|
16278
16429
|
default:
|
|
16279
16430
|
unreachable(chunk, ctx.logger);
|
|
16280
16431
|
return [];
|
|
16281
16432
|
}
|
|
16282
16433
|
}
|
|
16283
|
-
function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, mcpToolUseResult, enrichedReadCache) {
|
|
16434
|
+
function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, mcpToolUseResult, enrichedReadCache, taskState) {
|
|
16284
16435
|
if (typeof content === "string") {
|
|
16285
16436
|
const update = {
|
|
16286
16437
|
sessionUpdate: messageUpdateType(role),
|
|
@@ -16306,7 +16457,8 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
|
|
|
16306
16457
|
registerHooks,
|
|
16307
16458
|
supportsTerminalOutput,
|
|
16308
16459
|
cwd,
|
|
16309
|
-
mcpToolUseResult
|
|
16460
|
+
mcpToolUseResult,
|
|
16461
|
+
taskState
|
|
16310
16462
|
};
|
|
16311
16463
|
const output = [];
|
|
16312
16464
|
for (const chunk of content) {
|
|
@@ -16316,7 +16468,7 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
|
|
|
16316
16468
|
}
|
|
16317
16469
|
return output;
|
|
16318
16470
|
}
|
|
16319
|
-
function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
|
|
16471
|
+
function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache, taskState) {
|
|
16320
16472
|
const event = message.event;
|
|
16321
16473
|
switch (event.type) {
|
|
16322
16474
|
case "content_block_start": {
|
|
@@ -16340,7 +16492,8 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUse
|
|
|
16340
16492
|
supportsTerminalOutput,
|
|
16341
16493
|
cwd,
|
|
16342
16494
|
void 0,
|
|
16343
|
-
enrichedReadCache
|
|
16495
|
+
enrichedReadCache,
|
|
16496
|
+
taskState
|
|
16344
16497
|
);
|
|
16345
16498
|
}
|
|
16346
16499
|
case "content_block_delta": {
|
|
@@ -16365,12 +16518,18 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUse
|
|
|
16365
16518
|
supportsTerminalOutput,
|
|
16366
16519
|
cwd,
|
|
16367
16520
|
void 0,
|
|
16368
|
-
enrichedReadCache
|
|
16521
|
+
enrichedReadCache,
|
|
16522
|
+
taskState
|
|
16369
16523
|
);
|
|
16370
16524
|
}
|
|
16371
16525
|
case "content_block_stop":
|
|
16372
16526
|
toolUseStreamCache.delete(event.index);
|
|
16373
16527
|
return [];
|
|
16528
|
+
// `ping` is a Messages-API keep-alive event that the SDK's
|
|
16529
|
+
// `BetaRawMessageStreamEvent` union doesn't include even though the
|
|
16530
|
+
// wire format emits it; the `as never` cast lets us no-op it here
|
|
16531
|
+
// instead of falling through to `unreachable`.
|
|
16532
|
+
case "ping":
|
|
16374
16533
|
case "message_start":
|
|
16375
16534
|
case "message_delta":
|
|
16376
16535
|
case "message_stop":
|
|
@@ -16441,6 +16600,38 @@ async function handleSystemMessage(message, context) {
|
|
|
16441
16600
|
});
|
|
16442
16601
|
break;
|
|
16443
16602
|
}
|
|
16603
|
+
case "memory_recall": {
|
|
16604
|
+
const isSynthesis = message.mode === "synthesize";
|
|
16605
|
+
if (!isSynthesis && message.memories.length === 0) break;
|
|
16606
|
+
const locations = isSynthesis ? [] : message.memories.map((m) => ({ path: m.path }));
|
|
16607
|
+
const content = isSynthesis ? message.memories.filter(
|
|
16608
|
+
(m) => typeof m.content === "string"
|
|
16609
|
+
).map((m) => ({
|
|
16610
|
+
type: "content",
|
|
16611
|
+
content: { type: "text", text: m.content }
|
|
16612
|
+
})) : [];
|
|
16613
|
+
const count = message.memories.length;
|
|
16614
|
+
const title = isSynthesis ? "Recalled synthesized memory" : `Recalled ${count} ${count === 1 ? "memory" : "memories"}`;
|
|
16615
|
+
await client.sessionUpdate({
|
|
16616
|
+
sessionId: message.session_id,
|
|
16617
|
+
update: {
|
|
16618
|
+
sessionUpdate: "tool_call",
|
|
16619
|
+
toolCallId: message.uuid,
|
|
16620
|
+
title,
|
|
16621
|
+
kind: "read",
|
|
16622
|
+
status: "completed",
|
|
16623
|
+
...locations.length > 0 && { locations },
|
|
16624
|
+
...content.length > 0 && { content },
|
|
16625
|
+
_meta: {
|
|
16626
|
+
claudeCode: {
|
|
16627
|
+
toolName: "memory_recall",
|
|
16628
|
+
toolResponse: { mode: message.mode }
|
|
16629
|
+
}
|
|
16630
|
+
}
|
|
16631
|
+
}
|
|
16632
|
+
});
|
|
16633
|
+
break;
|
|
16634
|
+
}
|
|
16444
16635
|
default:
|
|
16445
16636
|
break;
|
|
16446
16637
|
}
|
|
@@ -16550,7 +16741,8 @@ async function handleStreamEvent(message, context) {
|
|
|
16550
16741
|
context.registerHooks,
|
|
16551
16742
|
context.supportsTerminalOutput,
|
|
16552
16743
|
context.session.cwd,
|
|
16553
|
-
context.enrichedReadCache
|
|
16744
|
+
context.enrichedReadCache,
|
|
16745
|
+
context.session.taskState
|
|
16554
16746
|
)) {
|
|
16555
16747
|
await client.sessionUpdate(notification);
|
|
16556
16748
|
context.session.notificationHistory.push(notification);
|
|
@@ -16562,6 +16754,17 @@ function hasLocalCommandStdout(content) {
|
|
|
16562
16754
|
function hasLocalCommandStderr(content) {
|
|
16563
16755
|
return typeof content === "string" && content.includes("<local-command-stderr>");
|
|
16564
16756
|
}
|
|
16757
|
+
function isSdkLocalCommandMessage(content) {
|
|
16758
|
+
return typeof content === "string" && content.includes("<command-name>") && (content.includes("<local-command-stdout>") || content.includes("<local-command-stderr>"));
|
|
16759
|
+
}
|
|
16760
|
+
var LOCAL_COMMAND_TAG_PATTERN = /<(command-name|command-message|command-args|local-command-stdout|local-command-stderr)>[\s\S]*?<\/\1>/g;
|
|
16761
|
+
function stripMarkerTags(text2) {
|
|
16762
|
+
return text2.replace(LOCAL_COMMAND_TAG_PATTERN, "");
|
|
16763
|
+
}
|
|
16764
|
+
function stripLocalCommandMetadata(content) {
|
|
16765
|
+
const stripped = stripMarkerTags(content);
|
|
16766
|
+
return stripped.trim() === "" ? null : stripped;
|
|
16767
|
+
}
|
|
16565
16768
|
function isLoginRequiredMessage(message) {
|
|
16566
16769
|
return message.type === "assistant" && message.message.model === "<synthetic>" && Array.isArray(message.message.content) && message.message.content.length === 1 && message.message.content[0].type === "text" && message.message.content[0].text?.includes("Please run /login") === true;
|
|
16567
16770
|
}
|
|
@@ -16570,7 +16773,7 @@ function isPlainTextUserMessage(message) {
|
|
|
16570
16773
|
return message.type === "user" && (typeof content === "string" || Array.isArray(content) && content.length === 1 && content[0].type === "text");
|
|
16571
16774
|
}
|
|
16572
16775
|
function shouldSkipUserAssistantMessage(message) {
|
|
16573
|
-
return
|
|
16776
|
+
return isSdkLocalCommandMessage(message.message.content) || isLoginRequiredMessage(message);
|
|
16574
16777
|
}
|
|
16575
16778
|
function logSpecialMessages(message, logger) {
|
|
16576
16779
|
const content = message.message.content;
|
|
@@ -16591,11 +16794,39 @@ function filterMessageContent(content) {
|
|
|
16591
16794
|
}
|
|
16592
16795
|
async function handleUserAssistantMessage(message, context) {
|
|
16593
16796
|
const { session, sessionId, client, toolUseCache, fileContentCache, logger } = context;
|
|
16797
|
+
if (message.message.role === "system") {
|
|
16798
|
+
return {};
|
|
16799
|
+
}
|
|
16594
16800
|
if (shouldSkipUserAssistantMessage(message)) {
|
|
16595
16801
|
logSpecialMessages(message, logger);
|
|
16596
16802
|
if (isLoginRequiredMessage(message)) {
|
|
16597
16803
|
return { shouldStop: true, error: RequestError.authRequired() };
|
|
16598
16804
|
}
|
|
16805
|
+
const rawContent = message.message.content;
|
|
16806
|
+
if (typeof rawContent === "string") {
|
|
16807
|
+
const stripped = stripLocalCommandMetadata(rawContent);
|
|
16808
|
+
if (stripped !== null) {
|
|
16809
|
+
for (const notification of toAcpNotifications(
|
|
16810
|
+
stripped,
|
|
16811
|
+
message.message.role,
|
|
16812
|
+
sessionId,
|
|
16813
|
+
toolUseCache,
|
|
16814
|
+
fileContentCache,
|
|
16815
|
+
client,
|
|
16816
|
+
logger,
|
|
16817
|
+
void 0,
|
|
16818
|
+
context.registerHooks,
|
|
16819
|
+
context.supportsTerminalOutput,
|
|
16820
|
+
session.cwd,
|
|
16821
|
+
void 0,
|
|
16822
|
+
context.enrichedReadCache,
|
|
16823
|
+
session.taskState
|
|
16824
|
+
)) {
|
|
16825
|
+
await client.sessionUpdate(notification);
|
|
16826
|
+
session.notificationHistory.push(notification);
|
|
16827
|
+
}
|
|
16828
|
+
}
|
|
16829
|
+
}
|
|
16599
16830
|
return {};
|
|
16600
16831
|
}
|
|
16601
16832
|
if (isPlainTextUserMessage(message)) {
|
|
@@ -16618,7 +16849,8 @@ async function handleUserAssistantMessage(message, context) {
|
|
|
16618
16849
|
context.supportsTerminalOutput,
|
|
16619
16850
|
session.cwd,
|
|
16620
16851
|
mcpToolUseResult,
|
|
16621
|
-
context.enrichedReadCache
|
|
16852
|
+
context.enrichedReadCache,
|
|
16853
|
+
session.taskState
|
|
16622
16854
|
)) {
|
|
16623
16855
|
await client.sessionUpdate(notification);
|
|
16624
16856
|
session.notificationHistory.push(notification);
|
|
@@ -16814,8 +17046,10 @@ var WEB_TOOLS = /* @__PURE__ */ new Set(["WebSearch", "WebFetch"]);
|
|
|
16814
17046
|
var AGENT_TOOLS = /* @__PURE__ */ new Set([
|
|
16815
17047
|
"Task",
|
|
16816
17048
|
"Agent",
|
|
16817
|
-
"
|
|
16818
|
-
"
|
|
17049
|
+
"TaskCreate",
|
|
17050
|
+
"TaskUpdate",
|
|
17051
|
+
"TaskGet",
|
|
17052
|
+
"TaskList"
|
|
16819
17053
|
]);
|
|
16820
17054
|
var BASE_ALLOWED_TOOLS = [
|
|
16821
17055
|
...READ_TOOLS,
|
|
@@ -16899,8 +17133,8 @@ function buildPermissionOptions(toolName, toolInput, repoRoot, suggestions) {
|
|
|
16899
17133
|
if (toolName === "Task") {
|
|
16900
17134
|
return permissionOptions("Yes, allow all sub-tasks");
|
|
16901
17135
|
}
|
|
16902
|
-
if (toolName === "
|
|
16903
|
-
return permissionOptions("Yes, allow all
|
|
17136
|
+
if (toolName === "TaskCreate" || toolName === "TaskUpdate" || toolName === "TaskGet" || toolName === "TaskList") {
|
|
17137
|
+
return permissionOptions("Yes, allow all task updates");
|
|
16904
17138
|
}
|
|
16905
17139
|
return permissionOptions("Yes, always allow");
|
|
16906
17140
|
}
|
|
@@ -17452,6 +17686,7 @@ async function canUseTool(context) {
|
|
|
17452
17686
|
|
|
17453
17687
|
// src/adapters/claude/session/commands.ts
|
|
17454
17688
|
var UNSUPPORTED_COMMANDS = [
|
|
17689
|
+
"clear",
|
|
17455
17690
|
"context",
|
|
17456
17691
|
"cost",
|
|
17457
17692
|
"keybindings-help",
|
|
@@ -17506,18 +17741,30 @@ function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os3.homedir()) {
|
|
|
17506
17741
|
const projectScoped = project?.mcpServers && typeof project.mcpServers === "object" ? project.mcpServers : {};
|
|
17507
17742
|
return { ...topLevel, ...projectScoped };
|
|
17508
17743
|
}
|
|
17509
|
-
function parseMcpServers(params) {
|
|
17744
|
+
function parseMcpServers(params, logger) {
|
|
17510
17745
|
const mcpServers = {};
|
|
17511
17746
|
if (!Array.isArray(params.mcpServers)) {
|
|
17512
17747
|
return mcpServers;
|
|
17513
17748
|
}
|
|
17514
17749
|
for (const server of params.mcpServers) {
|
|
17515
17750
|
if ("type" in server) {
|
|
17516
|
-
|
|
17517
|
-
|
|
17518
|
-
|
|
17519
|
-
|
|
17520
|
-
|
|
17751
|
+
if (server.type === "http" || server.type === "sse") {
|
|
17752
|
+
mcpServers[server.name] = {
|
|
17753
|
+
type: server.type,
|
|
17754
|
+
url: server.url,
|
|
17755
|
+
headers: server.headers ? Object.fromEntries(
|
|
17756
|
+
server.headers.map((e) => [
|
|
17757
|
+
e.name,
|
|
17758
|
+
e.value
|
|
17759
|
+
])
|
|
17760
|
+
) : void 0
|
|
17761
|
+
};
|
|
17762
|
+
} else {
|
|
17763
|
+
logger?.warn("parseMcpServers: dropping unsupported MCP server type", {
|
|
17764
|
+
name: server.name,
|
|
17765
|
+
type: server.type
|
|
17766
|
+
});
|
|
17767
|
+
}
|
|
17521
17768
|
} else {
|
|
17522
17769
|
mcpServers[server.name] = {
|
|
17523
17770
|
type: "stdio",
|
|
@@ -17530,12 +17777,43 @@ function parseMcpServers(params) {
|
|
|
17530
17777
|
return mcpServers;
|
|
17531
17778
|
}
|
|
17532
17779
|
|
|
17780
|
+
// src/adapters/claude/session/model-config.ts
|
|
17781
|
+
function applyAvailableModelsAllowlist(modelOptions, allowlist) {
|
|
17782
|
+
const filtered = [];
|
|
17783
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17784
|
+
for (const entry of allowlist) {
|
|
17785
|
+
const trimmed2 = entry.trim();
|
|
17786
|
+
if (!trimmed2 || seen.has(trimmed2)) continue;
|
|
17787
|
+
const match = modelOptions.options.find((o) => o.value === trimmed2);
|
|
17788
|
+
if (match) {
|
|
17789
|
+
filtered.push(match);
|
|
17790
|
+
seen.add(trimmed2);
|
|
17791
|
+
}
|
|
17792
|
+
}
|
|
17793
|
+
if (filtered.length === 0) return modelOptions;
|
|
17794
|
+
const currentModelId = filtered.some(
|
|
17795
|
+
(o) => o.value === modelOptions.currentModelId
|
|
17796
|
+
) ? modelOptions.currentModelId : filtered[0].value;
|
|
17797
|
+
return { currentModelId, options: filtered };
|
|
17798
|
+
}
|
|
17799
|
+
function resolveInitialModelId(modelOptions, preferredModelIds) {
|
|
17800
|
+
const allowedModelIds = new Set(modelOptions.options.map((opt) => opt.value));
|
|
17801
|
+
for (const candidate of preferredModelIds) {
|
|
17802
|
+
const trimmed2 = candidate?.trim();
|
|
17803
|
+
if (trimmed2 && allowedModelIds.has(trimmed2)) {
|
|
17804
|
+
return trimmed2;
|
|
17805
|
+
}
|
|
17806
|
+
}
|
|
17807
|
+
return modelOptions.currentModelId;
|
|
17808
|
+
}
|
|
17809
|
+
|
|
17533
17810
|
// src/adapters/claude/session/models.ts
|
|
17534
17811
|
var DEFAULT_MODEL = "opus";
|
|
17535
17812
|
var GATEWAY_TO_SDK_MODEL = {
|
|
17536
17813
|
"claude-opus-4-5": "opus",
|
|
17537
17814
|
"claude-opus-4-6": "opus",
|
|
17538
17815
|
"claude-opus-4-7": "opus",
|
|
17816
|
+
"claude-opus-4-8": "opus",
|
|
17539
17817
|
"claude-sonnet-4-5": "sonnet",
|
|
17540
17818
|
"claude-sonnet-4-6": "sonnet",
|
|
17541
17819
|
"claude-haiku-4-5": "haiku"
|
|
@@ -17546,6 +17824,7 @@ function toSdkModelId(modelId) {
|
|
|
17546
17824
|
var MODELS_WITH_1M_CONTEXT = /* @__PURE__ */ new Set([
|
|
17547
17825
|
"claude-opus-4-6",
|
|
17548
17826
|
"claude-opus-4-7",
|
|
17827
|
+
"claude-opus-4-8",
|
|
17549
17828
|
"claude-sonnet-4-6"
|
|
17550
17829
|
]);
|
|
17551
17830
|
function supports1MContext(modelId) {
|
|
@@ -17555,11 +17834,13 @@ var MODELS_WITH_EFFORT = /* @__PURE__ */ new Set([
|
|
|
17555
17834
|
"claude-opus-4-5",
|
|
17556
17835
|
"claude-opus-4-6",
|
|
17557
17836
|
"claude-opus-4-7",
|
|
17837
|
+
"claude-opus-4-8",
|
|
17558
17838
|
"claude-sonnet-4-6"
|
|
17559
17839
|
]);
|
|
17560
17840
|
var MODELS_WITH_XHIGH_EFFORT = /* @__PURE__ */ new Set([
|
|
17561
17841
|
"claude-opus-4-6",
|
|
17562
|
-
"claude-opus-4-7"
|
|
17842
|
+
"claude-opus-4-7",
|
|
17843
|
+
"claude-opus-4-8"
|
|
17563
17844
|
]);
|
|
17564
17845
|
function supportsEffort(modelId) {
|
|
17565
17846
|
return MODELS_WITH_EFFORT.has(modelId);
|
|
@@ -17599,6 +17880,19 @@ function tokenizeModelPreference(model) {
|
|
|
17599
17880
|
}).filter((token) => token && token !== "claude").filter((token) => /[a-z]/.test(token) || token.endsWith("m"));
|
|
17600
17881
|
return { tokens, contextHint };
|
|
17601
17882
|
}
|
|
17883
|
+
var MODEL_FAMILY_VERSION_PATTERN = /\b(\d+)[-.](\d+)\b/;
|
|
17884
|
+
function extractModelFamilyVersion(s) {
|
|
17885
|
+
if (!s) return null;
|
|
17886
|
+
const match = s.match(MODEL_FAMILY_VERSION_PATTERN);
|
|
17887
|
+
return match ? `${match[1]}.${match[2]}` : null;
|
|
17888
|
+
}
|
|
17889
|
+
function modelVersionsCompatible(preference, candidate) {
|
|
17890
|
+
const preferred = extractModelFamilyVersion(preference);
|
|
17891
|
+
if (!preferred) return true;
|
|
17892
|
+
const candidateVersion = extractModelFamilyVersion(candidate.value) ?? extractModelFamilyVersion(candidate.name) ?? extractModelFamilyVersion(candidate.description);
|
|
17893
|
+
if (!candidateVersion) return true;
|
|
17894
|
+
return preferred === candidateVersion;
|
|
17895
|
+
}
|
|
17602
17896
|
function scoreModelMatch(model, tokens, contextHint) {
|
|
17603
17897
|
const haystack = `${model.value} ${model.name ?? ""}`.toLowerCase();
|
|
17604
17898
|
let score = 0;
|
|
@@ -17618,6 +17912,7 @@ function resolveModelPreference(preference, options) {
|
|
|
17618
17912
|
);
|
|
17619
17913
|
if (directMatch) return directMatch.value;
|
|
17620
17914
|
const includesMatch = options.find((o) => {
|
|
17915
|
+
if (!modelVersionsCompatible(trimmed2, o)) return false;
|
|
17621
17916
|
const value = o.value.toLowerCase();
|
|
17622
17917
|
const display = (o.name ?? "").toLowerCase();
|
|
17623
17918
|
return value.includes(lower) || display.includes(lower) || lower.includes(value);
|
|
@@ -17628,6 +17923,7 @@ function resolveModelPreference(preference, options) {
|
|
|
17628
17923
|
let bestMatch = null;
|
|
17629
17924
|
let bestScore = 0;
|
|
17630
17925
|
for (const model of options) {
|
|
17926
|
+
if (!modelVersionsCompatible(trimmed2, model)) continue;
|
|
17631
17927
|
const score = scoreModelMatch(model, tokens, contextHint);
|
|
17632
17928
|
if (0 < score && (!bestMatch || bestScore < score)) {
|
|
17633
17929
|
bestMatch = model;
|
|
@@ -17704,6 +18000,7 @@ function buildEnvironment() {
|
|
|
17704
18000
|
const existingCustomHeaders = process.env.ANTHROPIC_CUSTOM_HEADERS;
|
|
17705
18001
|
const customHeaders = existingCustomHeaders ? `${existingCustomHeaders}
|
|
17706
18002
|
${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
18003
|
+
const mcpNonblocking = process.env.MCP_CONNECTION_NONBLOCKING;
|
|
17707
18004
|
return {
|
|
17708
18005
|
...process.env,
|
|
17709
18006
|
ELECTRON_RUN_AS_NODE: "1",
|
|
@@ -17712,11 +18009,14 @@ ${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
|
17712
18009
|
ENABLE_TOOL_SEARCH: "auto:0",
|
|
17713
18010
|
// Enable idle state as end-of-turn signal (required for SDK 0.2.114+)
|
|
17714
18011
|
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1",
|
|
18012
|
+
...mcpNonblocking !== void 0 && {
|
|
18013
|
+
MCP_CONNECTION_NONBLOCKING: mcpNonblocking
|
|
18014
|
+
},
|
|
17715
18015
|
// Route to AWS Bedrock as a fallback when Anthropic returns 5xx
|
|
17716
18016
|
ANTHROPIC_CUSTOM_HEADERS: customHeaders
|
|
17717
18017
|
};
|
|
17718
18018
|
}
|
|
17719
|
-
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode) {
|
|
18019
|
+
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode, taskState, onTaskStateChange) {
|
|
17720
18020
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange })];
|
|
17721
18021
|
if (enrichmentDeps && enrichedReadCache) {
|
|
17722
18022
|
postToolUseHooks.push(
|
|
@@ -17730,13 +18030,16 @@ function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichment
|
|
|
17730
18030
|
if (cloudMode) {
|
|
17731
18031
|
preToolUseHooks.push(createSignedCommitGuardHook(logger));
|
|
17732
18032
|
}
|
|
18033
|
+
const taskHook = createTaskHook(taskState, onTaskStateChange);
|
|
17733
18034
|
return {
|
|
17734
18035
|
...userHooks,
|
|
17735
18036
|
PostToolUse: [
|
|
17736
18037
|
...userHooks?.PostToolUse || [],
|
|
17737
18038
|
{ hooks: postToolUseHooks }
|
|
17738
18039
|
],
|
|
17739
|
-
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }]
|
|
18040
|
+
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }],
|
|
18041
|
+
TaskCreated: [...userHooks?.TaskCreated || [], { hooks: [taskHook] }],
|
|
18042
|
+
TaskCompleted: [...userHooks?.TaskCompleted || [], { hooks: [taskHook] }]
|
|
17740
18043
|
};
|
|
17741
18044
|
}
|
|
17742
18045
|
var PH_EXPLORE_AGENT = {
|
|
@@ -17767,7 +18070,10 @@ Rules:
|
|
|
17767
18070
|
"WebFetch",
|
|
17768
18071
|
"WebSearch",
|
|
17769
18072
|
"NotebookRead",
|
|
17770
|
-
"
|
|
18073
|
+
"TaskCreate",
|
|
18074
|
+
"TaskUpdate",
|
|
18075
|
+
"TaskGet",
|
|
18076
|
+
"TaskList"
|
|
17771
18077
|
]
|
|
17772
18078
|
};
|
|
17773
18079
|
function buildAgents(userAgents) {
|
|
@@ -17895,7 +18201,9 @@ function buildSessionOptions(params) {
|
|
|
17895
18201
|
params.enrichmentDeps,
|
|
17896
18202
|
params.enrichedReadCache,
|
|
17897
18203
|
registeredAgentNames,
|
|
17898
|
-
params.cloudMode ?? false
|
|
18204
|
+
params.cloudMode ?? false,
|
|
18205
|
+
params.taskState,
|
|
18206
|
+
params.onTaskStateChange
|
|
17899
18207
|
),
|
|
17900
18208
|
outputFormat: params.outputFormat,
|
|
17901
18209
|
abortController: getAbortController(
|
|
@@ -18124,6 +18432,15 @@ function getManagedSettingsPath() {
|
|
|
18124
18432
|
return "/etc/claude-code/managed-settings.json";
|
|
18125
18433
|
}
|
|
18126
18434
|
}
|
|
18435
|
+
function mergeAvailableModels(existing, incoming, layer) {
|
|
18436
|
+
if (incoming === void 0) {
|
|
18437
|
+
return existing;
|
|
18438
|
+
}
|
|
18439
|
+
if (layer === "enterprise") {
|
|
18440
|
+
return Array.from(new Set(incoming));
|
|
18441
|
+
}
|
|
18442
|
+
return Array.from(/* @__PURE__ */ new Set([...existing ?? [], ...incoming]));
|
|
18443
|
+
}
|
|
18127
18444
|
var SettingsManager = class {
|
|
18128
18445
|
cwd;
|
|
18129
18446
|
repoRoot;
|
|
@@ -18179,10 +18496,10 @@ var SettingsManager = class {
|
|
|
18179
18496
|
}
|
|
18180
18497
|
mergeAllSettings() {
|
|
18181
18498
|
const allSettings = [
|
|
18182
|
-
this.userSettings,
|
|
18183
|
-
this.projectSettings,
|
|
18184
|
-
this.localSettings,
|
|
18185
|
-
this.enterpriseSettings
|
|
18499
|
+
{ layer: "user", settings: this.userSettings },
|
|
18500
|
+
{ layer: "project", settings: this.projectSettings },
|
|
18501
|
+
{ layer: "local", settings: this.localSettings },
|
|
18502
|
+
{ layer: "enterprise", settings: this.enterpriseSettings }
|
|
18186
18503
|
];
|
|
18187
18504
|
const permissions = {
|
|
18188
18505
|
allow: [],
|
|
@@ -18191,7 +18508,7 @@ var SettingsManager = class {
|
|
|
18191
18508
|
};
|
|
18192
18509
|
const merged = { permissions };
|
|
18193
18510
|
const posthogApprovedExecTools = /* @__PURE__ */ new Set();
|
|
18194
|
-
for (const settings of allSettings) {
|
|
18511
|
+
for (const { layer, settings } of allSettings) {
|
|
18195
18512
|
if (settings.permissions) {
|
|
18196
18513
|
if (settings.permissions.allow) {
|
|
18197
18514
|
permissions.allow?.push(...settings.permissions.allow);
|
|
@@ -18218,6 +18535,11 @@ var SettingsManager = class {
|
|
|
18218
18535
|
if (settings.model) {
|
|
18219
18536
|
merged.model = settings.model;
|
|
18220
18537
|
}
|
|
18538
|
+
merged.availableModels = mergeAvailableModels(
|
|
18539
|
+
merged.availableModels,
|
|
18540
|
+
settings.availableModels,
|
|
18541
|
+
layer
|
|
18542
|
+
);
|
|
18221
18543
|
if (settings.posthogApprovedExecTools) {
|
|
18222
18544
|
for (const tool2 of settings.posthogApprovedExecTools) {
|
|
18223
18545
|
posthogApprovedExecTools.add(tool2);
|
|
@@ -18426,6 +18748,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18426
18748
|
},
|
|
18427
18749
|
loadSession: true,
|
|
18428
18750
|
sessionCapabilities: {
|
|
18751
|
+
additionalDirectories: {},
|
|
18429
18752
|
list: {},
|
|
18430
18753
|
fork: {},
|
|
18431
18754
|
resume: {}
|
|
@@ -18451,10 +18774,18 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18451
18774
|
if (fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json.backup")) && !fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json"))) {
|
|
18452
18775
|
throw RequestError2.authRequired();
|
|
18453
18776
|
}
|
|
18454
|
-
const response = await this.createSession(
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
18777
|
+
const response = await this.createSession(
|
|
18778
|
+
{
|
|
18779
|
+
cwd: params.cwd,
|
|
18780
|
+
mcpServers: params.mcpServers ?? [],
|
|
18781
|
+
additionalDirectories: params.additionalDirectories,
|
|
18782
|
+
_meta: params._meta
|
|
18783
|
+
},
|
|
18784
|
+
{
|
|
18785
|
+
// Revisit these meta values once we support resume
|
|
18786
|
+
resume: params._meta?.claudeCode?.options?.resume
|
|
18787
|
+
}
|
|
18788
|
+
);
|
|
18458
18789
|
return response;
|
|
18459
18790
|
}
|
|
18460
18791
|
async unstable_forkSession(params) {
|
|
@@ -18462,24 +18793,27 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18462
18793
|
{
|
|
18463
18794
|
cwd: params.cwd,
|
|
18464
18795
|
mcpServers: params.mcpServers ?? [],
|
|
18796
|
+
additionalDirectories: params.additionalDirectories,
|
|
18465
18797
|
_meta: params._meta
|
|
18466
18798
|
},
|
|
18467
18799
|
{ resume: params.sessionId, forkSession: true }
|
|
18468
18800
|
);
|
|
18469
18801
|
}
|
|
18470
|
-
async
|
|
18802
|
+
async resumeSession(params) {
|
|
18471
18803
|
const existing = this.getExistingSessionState(params.sessionId);
|
|
18472
18804
|
if (existing) return existing;
|
|
18473
18805
|
const response = await this.createSession(
|
|
18474
18806
|
{
|
|
18475
18807
|
cwd: params.cwd,
|
|
18476
18808
|
mcpServers: params.mcpServers ?? [],
|
|
18809
|
+
additionalDirectories: params.additionalDirectories,
|
|
18477
18810
|
_meta: params._meta
|
|
18478
18811
|
},
|
|
18479
18812
|
{
|
|
18480
18813
|
resume: params.sessionId
|
|
18481
18814
|
}
|
|
18482
18815
|
);
|
|
18816
|
+
await this.rehydrateTaskStateFromJsonl(params.sessionId);
|
|
18483
18817
|
return response;
|
|
18484
18818
|
}
|
|
18485
18819
|
async loadSession(params) {
|
|
@@ -18489,6 +18823,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18489
18823
|
{
|
|
18490
18824
|
cwd: params.cwd,
|
|
18491
18825
|
mcpServers: params.mcpServers ?? [],
|
|
18826
|
+
additionalDirectories: params.additionalDirectories,
|
|
18492
18827
|
_meta: params._meta
|
|
18493
18828
|
},
|
|
18494
18829
|
{ resume: params.sessionId, skipBackgroundFetches: true }
|
|
@@ -18567,6 +18902,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18567
18902
|
await this.broadcastUserMessage(params);
|
|
18568
18903
|
this.session.promptRunning = true;
|
|
18569
18904
|
let handedOff = false;
|
|
18905
|
+
let errored = false;
|
|
18570
18906
|
let lastAssistantTotalUsage = null;
|
|
18571
18907
|
let lastStreamUsage = {
|
|
18572
18908
|
input_tokens: 0,
|
|
@@ -18574,6 +18910,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18574
18910
|
cache_read_input_tokens: 0,
|
|
18575
18911
|
cache_creation_input_tokens: 0
|
|
18576
18912
|
};
|
|
18913
|
+
let compactionInProgress = false;
|
|
18577
18914
|
if (this.session.lastContextWindowSize == null) {
|
|
18578
18915
|
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
18579
18916
|
this.session.modelId ?? ""
|
|
@@ -18631,6 +18968,40 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18631
18968
|
if (message.subtype === "local_command_output") {
|
|
18632
18969
|
promptReplayed = true;
|
|
18633
18970
|
}
|
|
18971
|
+
if (message.subtype === "status") {
|
|
18972
|
+
if (message.status === "compacting") {
|
|
18973
|
+
compactionInProgress = true;
|
|
18974
|
+
} else if (message.compact_result === "success" && compactionInProgress) {
|
|
18975
|
+
compactionInProgress = false;
|
|
18976
|
+
await this.client.sessionUpdate({
|
|
18977
|
+
sessionId: params.sessionId,
|
|
18978
|
+
update: {
|
|
18979
|
+
sessionUpdate: "agent_message_chunk",
|
|
18980
|
+
content: {
|
|
18981
|
+
type: "text",
|
|
18982
|
+
text: "\n\nCompacting completed."
|
|
18983
|
+
}
|
|
18984
|
+
}
|
|
18985
|
+
});
|
|
18986
|
+
break;
|
|
18987
|
+
} else if (message.compact_result === "failed" && compactionInProgress) {
|
|
18988
|
+
compactionInProgress = false;
|
|
18989
|
+
const reason = message.compact_error ? `: ${message.compact_error}` : ".";
|
|
18990
|
+
await this.client.sessionUpdate({
|
|
18991
|
+
sessionId: params.sessionId,
|
|
18992
|
+
update: {
|
|
18993
|
+
sessionUpdate: "agent_message_chunk",
|
|
18994
|
+
content: {
|
|
18995
|
+
type: "text",
|
|
18996
|
+
text: `
|
|
18997
|
+
|
|
18998
|
+
Compacting failed${reason}`
|
|
18999
|
+
}
|
|
19000
|
+
}
|
|
19001
|
+
});
|
|
19002
|
+
break;
|
|
19003
|
+
}
|
|
19004
|
+
}
|
|
18634
19005
|
if (message.subtype === "session_state_changed" && message.state === "idle") {
|
|
18635
19006
|
if (!promptReplayed) {
|
|
18636
19007
|
const cmdName = commandMatch?.[1].slice(1);
|
|
@@ -18670,7 +19041,9 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18670
19041
|
size: lastContextWindowSize
|
|
18671
19042
|
}
|
|
18672
19043
|
});
|
|
18673
|
-
return {
|
|
19044
|
+
return {
|
|
19045
|
+
stopReason: this.session.cancelled ? "cancelled" : "end_turn"
|
|
19046
|
+
};
|
|
18674
19047
|
}
|
|
18675
19048
|
await handleSystemMessage(message, context);
|
|
18676
19049
|
break;
|
|
@@ -18853,6 +19226,28 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18853
19226
|
}
|
|
18854
19227
|
throw new Error("Session did not end in result");
|
|
18855
19228
|
} catch (error) {
|
|
19229
|
+
errored = true;
|
|
19230
|
+
try {
|
|
19231
|
+
await this.session.query.interrupt();
|
|
19232
|
+
const MAX_DRAIN = 100;
|
|
19233
|
+
for (let i2 = 0; i2 < MAX_DRAIN; i2++) {
|
|
19234
|
+
const { value: m, done } = await this.session.query.next();
|
|
19235
|
+
if (done || !m) break;
|
|
19236
|
+
if (m.type === "system" && m.subtype === "session_state_changed" && m.state === "idle") {
|
|
19237
|
+
break;
|
|
19238
|
+
}
|
|
19239
|
+
if (i2 === MAX_DRAIN - 1) {
|
|
19240
|
+
this.logger.error(
|
|
19241
|
+
`Session ${params.sessionId}: drained ${MAX_DRAIN} messages after error without observing idle`
|
|
19242
|
+
);
|
|
19243
|
+
}
|
|
19244
|
+
}
|
|
19245
|
+
} catch (drainErr) {
|
|
19246
|
+
this.logger.error(
|
|
19247
|
+
`Session ${params.sessionId}: failed to drain query after prompt error`,
|
|
19248
|
+
{ error: drainErr }
|
|
19249
|
+
);
|
|
19250
|
+
}
|
|
18856
19251
|
if (error instanceof RequestError2 || !(error instanceof Error)) {
|
|
18857
19252
|
throw error;
|
|
18858
19253
|
}
|
|
@@ -18873,9 +19268,19 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18873
19268
|
this.toolUseStreamCache.clear();
|
|
18874
19269
|
if (!handedOff) {
|
|
18875
19270
|
this.session.promptRunning = false;
|
|
18876
|
-
|
|
18877
|
-
pending.
|
|
18878
|
-
|
|
19271
|
+
if (errored) {
|
|
19272
|
+
for (const pending of this.session.pendingMessages.values()) {
|
|
19273
|
+
pending.resolve(true);
|
|
19274
|
+
}
|
|
19275
|
+
this.session.pendingMessages.clear();
|
|
19276
|
+
} else if (this.session.pendingMessages.size > 0) {
|
|
19277
|
+
const next = [...this.session.pendingMessages.entries()].sort(
|
|
19278
|
+
(a, b) => a[1].order - b[1].order
|
|
19279
|
+
)[0];
|
|
19280
|
+
if (next) {
|
|
19281
|
+
next[1].resolve(false);
|
|
19282
|
+
this.session.pendingMessages.delete(next[0]);
|
|
19283
|
+
}
|
|
18879
19284
|
}
|
|
18880
19285
|
}
|
|
18881
19286
|
}
|
|
@@ -18926,7 +19331,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18926
19331
|
);
|
|
18927
19332
|
}
|
|
18928
19333
|
const mcpServers = parseMcpServers(
|
|
18929
|
-
params
|
|
19334
|
+
params,
|
|
19335
|
+
this.logger
|
|
18930
19336
|
);
|
|
18931
19337
|
await this.refreshSession(mcpServers);
|
|
18932
19338
|
return { refreshed: true };
|
|
@@ -19111,7 +19517,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19111
19517
|
const settingsManager = new SettingsManager(cwd);
|
|
19112
19518
|
await settingsManager.initialize();
|
|
19113
19519
|
const earlyModelId = settingsManager.getSettings().model || meta?.model || "";
|
|
19114
|
-
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params) : {};
|
|
19520
|
+
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params, this.logger) : {};
|
|
19115
19521
|
const localToolsServer = createLocalToolsMcpServer(
|
|
19116
19522
|
{ cwd, token: resolveGithubToken(), taskId },
|
|
19117
19523
|
meta
|
|
@@ -19135,6 +19541,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19135
19541
|
cwd
|
|
19136
19542
|
});
|
|
19137
19543
|
const permissionMode = meta?.permissionMode && CODE_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
|
|
19544
|
+
const taskState = /* @__PURE__ */ new Map();
|
|
19138
19545
|
const options = buildSessionOptions({
|
|
19139
19546
|
cwd,
|
|
19140
19547
|
mcpServers,
|
|
@@ -19148,7 +19555,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19148
19555
|
forkSession,
|
|
19149
19556
|
additionalDirectories: [
|
|
19150
19557
|
...meta?.claudeCode?.options?.additionalDirectories ?? [],
|
|
19151
|
-
|
|
19558
|
+
// Prefer the official ACP `additionalDirectories` field. Fall back
|
|
19559
|
+
// to the legacy `_meta.additionalRoots` extension for clients that
|
|
19560
|
+
// haven't been updated yet.
|
|
19561
|
+
...params.additionalDirectories ?? meta?.additionalRoots ?? []
|
|
19152
19562
|
],
|
|
19153
19563
|
disableBuiltInTools: meta?.disableBuiltInTools,
|
|
19154
19564
|
outputFormat,
|
|
@@ -19159,7 +19569,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19159
19569
|
effort,
|
|
19160
19570
|
enrichmentDeps: this.enrichment?.deps,
|
|
19161
19571
|
enrichedReadCache: this.enrichedReadCache,
|
|
19162
|
-
cloudMode: cloudRun
|
|
19572
|
+
cloudMode: cloudRun,
|
|
19573
|
+
taskState,
|
|
19574
|
+
onTaskStateChange: async () => {
|
|
19575
|
+
await this.client.sessionUpdate({
|
|
19576
|
+
sessionId,
|
|
19577
|
+
update: {
|
|
19578
|
+
sessionUpdate: "plan",
|
|
19579
|
+
entries: taskStateToPlanEntries(taskState)
|
|
19580
|
+
}
|
|
19581
|
+
});
|
|
19582
|
+
}
|
|
19163
19583
|
});
|
|
19164
19584
|
const abortController = options.abortController;
|
|
19165
19585
|
const q = query({ prompt: input, options });
|
|
@@ -19188,6 +19608,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19188
19608
|
systemPrompt: estimateSystemPrompt(systemPrompt),
|
|
19189
19609
|
rules: estimateRulesTokens(readClaudeMdQuietly(cwd, this.logger))
|
|
19190
19610
|
},
|
|
19611
|
+
taskState,
|
|
19191
19612
|
// Custom properties
|
|
19192
19613
|
cwd,
|
|
19193
19614
|
notificationHistory: [],
|
|
@@ -19227,7 +19648,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19227
19648
|
}
|
|
19228
19649
|
}
|
|
19229
19650
|
const initPromise2 = !isResume ? withTimeout(q.initializationResult(), SESSION_VALIDATION_TIMEOUT_MS) : void 0;
|
|
19230
|
-
const [
|
|
19651
|
+
const [rawModelOptions] = await Promise.all([
|
|
19231
19652
|
this.getModelConfigOptions(
|
|
19232
19653
|
settingsManager.getSettings().model || meta?.model || void 0
|
|
19233
19654
|
),
|
|
@@ -19239,6 +19660,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19239
19660
|
})
|
|
19240
19661
|
] : []
|
|
19241
19662
|
]);
|
|
19663
|
+
const settingsAvailableModels = settingsManager.getSettings().availableModels;
|
|
19664
|
+
const modelOptions = Array.isArray(settingsAvailableModels) ? applyAvailableModelsAllowlist(rawModelOptions, settingsAvailableModels) : rawModelOptions;
|
|
19242
19665
|
if (initPromise2) {
|
|
19243
19666
|
try {
|
|
19244
19667
|
const initResult = await initPromise2;
|
|
@@ -19262,9 +19685,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19262
19685
|
throw err2;
|
|
19263
19686
|
}
|
|
19264
19687
|
}
|
|
19265
|
-
const
|
|
19266
|
-
|
|
19267
|
-
|
|
19688
|
+
const resolvedModelId = resolveInitialModelId(modelOptions, [
|
|
19689
|
+
settingsManager.getSettings().model,
|
|
19690
|
+
meta?.model
|
|
19691
|
+
]);
|
|
19268
19692
|
session.modelId = resolvedModelId;
|
|
19269
19693
|
session.lastContextWindowSize = this.getContextWindowForModel(resolvedModelId);
|
|
19270
19694
|
const resolvedSdkModel = toSdkModelId(resolvedModelId);
|
|
@@ -19472,6 +19896,34 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19472
19896
|
[key]: tokens
|
|
19473
19897
|
};
|
|
19474
19898
|
}
|
|
19899
|
+
/**
|
|
19900
|
+
* Rebuild the in-memory taskState from JSONL and push a plan update so the
|
|
19901
|
+
* client's plan panel reflects pre-resume tasks. `loadSession` already covers
|
|
19902
|
+
* this via the full `replaySessionHistory` notification stream; resume
|
|
19903
|
+
* deliberately stays quiet (the client keeps its own message history) so we
|
|
19904
|
+
* walk the transcript here for state only.
|
|
19905
|
+
*/
|
|
19906
|
+
async rehydrateTaskStateFromJsonl(sessionId) {
|
|
19907
|
+
try {
|
|
19908
|
+
const messages = await getSessionMessages(sessionId, {
|
|
19909
|
+
dir: this.session.cwd
|
|
19910
|
+
});
|
|
19911
|
+
rehydrateTaskState(messages, this.session.taskState);
|
|
19912
|
+
if (this.session.taskState.size === 0) return;
|
|
19913
|
+
await this.client.sessionUpdate({
|
|
19914
|
+
sessionId,
|
|
19915
|
+
update: {
|
|
19916
|
+
sessionUpdate: "plan",
|
|
19917
|
+
entries: taskStateToPlanEntries(this.session.taskState)
|
|
19918
|
+
}
|
|
19919
|
+
});
|
|
19920
|
+
} catch (err2) {
|
|
19921
|
+
this.logger.warn("Failed to rehydrate task state", {
|
|
19922
|
+
sessionId,
|
|
19923
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
19924
|
+
});
|
|
19925
|
+
}
|
|
19926
|
+
}
|
|
19475
19927
|
async replaySessionHistory(sessionId) {
|
|
19476
19928
|
try {
|
|
19477
19929
|
const messages = await getSessionMessages(sessionId, {
|
|
@@ -20262,7 +20714,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
20262
20714
|
}
|
|
20263
20715
|
return response;
|
|
20264
20716
|
}
|
|
20265
|
-
async
|
|
20717
|
+
async resumeSession(params) {
|
|
20266
20718
|
const meta = params._meta;
|
|
20267
20719
|
const injectedParams = this.applyLocalTools(
|
|
20268
20720
|
this.applyStructuredOutput(
|