@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
package/dist/server/bin.cjs
CHANGED
|
@@ -4433,6 +4433,7 @@ var GATEWAY_TO_SDK_MODEL = {
|
|
|
4433
4433
|
"claude-opus-4-5": "opus",
|
|
4434
4434
|
"claude-opus-4-6": "opus",
|
|
4435
4435
|
"claude-opus-4-7": "opus",
|
|
4436
|
+
"claude-opus-4-8": "opus",
|
|
4436
4437
|
"claude-sonnet-4-5": "sonnet",
|
|
4437
4438
|
"claude-sonnet-4-6": "sonnet",
|
|
4438
4439
|
"claude-haiku-4-5": "haiku"
|
|
@@ -4443,6 +4444,7 @@ function toSdkModelId(modelId) {
|
|
|
4443
4444
|
var MODELS_WITH_1M_CONTEXT = /* @__PURE__ */ new Set([
|
|
4444
4445
|
"claude-opus-4-6",
|
|
4445
4446
|
"claude-opus-4-7",
|
|
4447
|
+
"claude-opus-4-8",
|
|
4446
4448
|
"claude-sonnet-4-6"
|
|
4447
4449
|
]);
|
|
4448
4450
|
function supports1MContext(modelId) {
|
|
@@ -4452,11 +4454,13 @@ var MODELS_WITH_EFFORT = /* @__PURE__ */ new Set([
|
|
|
4452
4454
|
"claude-opus-4-5",
|
|
4453
4455
|
"claude-opus-4-6",
|
|
4454
4456
|
"claude-opus-4-7",
|
|
4457
|
+
"claude-opus-4-8",
|
|
4455
4458
|
"claude-sonnet-4-6"
|
|
4456
4459
|
]);
|
|
4457
4460
|
var MODELS_WITH_XHIGH_EFFORT = /* @__PURE__ */ new Set([
|
|
4458
4461
|
"claude-opus-4-6",
|
|
4459
|
-
"claude-opus-4-7"
|
|
4462
|
+
"claude-opus-4-7",
|
|
4463
|
+
"claude-opus-4-8"
|
|
4460
4464
|
]);
|
|
4461
4465
|
function supportsEffort(modelId) {
|
|
4462
4466
|
return MODELS_WITH_EFFORT.has(modelId);
|
|
@@ -4496,6 +4500,19 @@ function tokenizeModelPreference(model) {
|
|
|
4496
4500
|
}).filter((token) => token && token !== "claude").filter((token) => /[a-z]/.test(token) || token.endsWith("m"));
|
|
4497
4501
|
return { tokens, contextHint };
|
|
4498
4502
|
}
|
|
4503
|
+
var MODEL_FAMILY_VERSION_PATTERN = /\b(\d+)[-.](\d+)\b/;
|
|
4504
|
+
function extractModelFamilyVersion(s) {
|
|
4505
|
+
if (!s) return null;
|
|
4506
|
+
const match = s.match(MODEL_FAMILY_VERSION_PATTERN);
|
|
4507
|
+
return match ? `${match[1]}.${match[2]}` : null;
|
|
4508
|
+
}
|
|
4509
|
+
function modelVersionsCompatible(preference, candidate) {
|
|
4510
|
+
const preferred = extractModelFamilyVersion(preference);
|
|
4511
|
+
if (!preferred) return true;
|
|
4512
|
+
const candidateVersion = extractModelFamilyVersion(candidate.value) ?? extractModelFamilyVersion(candidate.name) ?? extractModelFamilyVersion(candidate.description);
|
|
4513
|
+
if (!candidateVersion) return true;
|
|
4514
|
+
return preferred === candidateVersion;
|
|
4515
|
+
}
|
|
4499
4516
|
function scoreModelMatch(model, tokens, contextHint) {
|
|
4500
4517
|
const haystack = `${model.value} ${model.name ?? ""}`.toLowerCase();
|
|
4501
4518
|
let score = 0;
|
|
@@ -4515,6 +4532,7 @@ function resolveModelPreference(preference, options) {
|
|
|
4515
4532
|
);
|
|
4516
4533
|
if (directMatch) return directMatch.value;
|
|
4517
4534
|
const includesMatch = options.find((o) => {
|
|
4535
|
+
if (!modelVersionsCompatible(trimmed2, o)) return false;
|
|
4518
4536
|
const value = o.value.toLowerCase();
|
|
4519
4537
|
const display = (o.name ?? "").toLowerCase();
|
|
4520
4538
|
return value.includes(lower) || display.includes(lower) || lower.includes(value);
|
|
@@ -4525,6 +4543,7 @@ function resolveModelPreference(preference, options) {
|
|
|
4525
4543
|
let bestMatch = null;
|
|
4526
4544
|
let bestScore = 0;
|
|
4527
4545
|
for (const model of options) {
|
|
4546
|
+
if (!modelVersionsCompatible(trimmed2, model)) continue;
|
|
4528
4547
|
const score = scoreModelMatch(model, tokens, contextHint);
|
|
4529
4548
|
if (0 < score && (!bestMatch || bestScore < score)) {
|
|
4530
4549
|
bestMatch = model;
|
|
@@ -9471,7 +9490,7 @@ var import_zod4 = require("zod");
|
|
|
9471
9490
|
// package.json
|
|
9472
9491
|
var package_default = {
|
|
9473
9492
|
name: "@posthog/agent",
|
|
9474
|
-
version: "2.3.
|
|
9493
|
+
version: "2.3.736",
|
|
9475
9494
|
repository: "https://github.com/PostHog/code",
|
|
9476
9495
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
9477
9496
|
exports: {
|
|
@@ -9591,9 +9610,9 @@ var package_default = {
|
|
|
9591
9610
|
vitest: "^2.1.8"
|
|
9592
9611
|
},
|
|
9593
9612
|
dependencies: {
|
|
9594
|
-
"@agentclientprotocol/sdk": "0.
|
|
9595
|
-
"@anthropic-ai/claude-agent-sdk": "0.
|
|
9596
|
-
"@anthropic-ai/sdk": "0.
|
|
9613
|
+
"@agentclientprotocol/sdk": "0.22.1",
|
|
9614
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.154",
|
|
9615
|
+
"@anthropic-ai/sdk": "0.100.0",
|
|
9597
9616
|
"@hono/node-server": "^1.19.9",
|
|
9598
9617
|
"@opentelemetry/api-logs": "^0.208.0",
|
|
9599
9618
|
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
|
|
@@ -15308,6 +15327,30 @@ var registerHookCallback = (toolUseID, {
|
|
|
15308
15327
|
onPostToolUseHook
|
|
15309
15328
|
};
|
|
15310
15329
|
};
|
|
15330
|
+
var createTaskHook = (taskState, onChange) => async (input) => {
|
|
15331
|
+
const taskId = "task_id" in input && typeof input.task_id === "string" ? input.task_id : void 0;
|
|
15332
|
+
if (!taskId) return { continue: true };
|
|
15333
|
+
let mutated = false;
|
|
15334
|
+
if (input.hook_event_name === "TaskCreated") {
|
|
15335
|
+
if (!input.task_subject) return { continue: true };
|
|
15336
|
+
if (taskState.has(taskId)) return { continue: true };
|
|
15337
|
+
taskState.set(taskId, {
|
|
15338
|
+
subject: input.task_subject,
|
|
15339
|
+
status: "pending",
|
|
15340
|
+
description: input.task_description
|
|
15341
|
+
});
|
|
15342
|
+
mutated = true;
|
|
15343
|
+
} else if (input.hook_event_name === "TaskCompleted") {
|
|
15344
|
+
const existing = taskState.get(taskId);
|
|
15345
|
+
if (!existing || existing.status === "completed") {
|
|
15346
|
+
return { continue: true };
|
|
15347
|
+
}
|
|
15348
|
+
taskState.set(taskId, { ...existing, status: "completed" });
|
|
15349
|
+
mutated = true;
|
|
15350
|
+
}
|
|
15351
|
+
if (mutated && onChange) await onChange();
|
|
15352
|
+
return { continue: true };
|
|
15353
|
+
};
|
|
15311
15354
|
var createPostToolUseHook = ({ onModeChange }) => async (input, toolUseID) => {
|
|
15312
15355
|
if (input.hook_event_name === "PostToolUse") {
|
|
15313
15356
|
const toolName = input.tool_name;
|
|
@@ -15322,10 +15365,8 @@ var createPostToolUseHook = ({ onModeChange }) => async (input, toolUseID) => {
|
|
|
15322
15365
|
input.tool_input,
|
|
15323
15366
|
input.tool_response
|
|
15324
15367
|
);
|
|
15325
|
-
delete toolUseCallbacks[toolUseID];
|
|
15326
|
-
} else {
|
|
15327
|
-
delete toolUseCallbacks[toolUseID];
|
|
15328
15368
|
}
|
|
15369
|
+
delete toolUseCallbacks[toolUseID];
|
|
15329
15370
|
}
|
|
15330
15371
|
}
|
|
15331
15372
|
return { continue: true };
|
|
@@ -15472,6 +15513,104 @@ var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID
|
|
|
15472
15513
|
}
|
|
15473
15514
|
};
|
|
15474
15515
|
|
|
15516
|
+
// src/adapters/claude/conversion/task-state.ts
|
|
15517
|
+
function parseTaskCreateOutput(content) {
|
|
15518
|
+
const tryParse = (text2) => {
|
|
15519
|
+
try {
|
|
15520
|
+
const parsed = JSON.parse(text2);
|
|
15521
|
+
if (parsed && typeof parsed === "object" && parsed.task && typeof parsed.task.id === "string") {
|
|
15522
|
+
return parsed;
|
|
15523
|
+
}
|
|
15524
|
+
} catch {
|
|
15525
|
+
}
|
|
15526
|
+
return void 0;
|
|
15527
|
+
};
|
|
15528
|
+
if (typeof content === "string") {
|
|
15529
|
+
return tryParse(content);
|
|
15530
|
+
}
|
|
15531
|
+
if (Array.isArray(content)) {
|
|
15532
|
+
for (const block of content) {
|
|
15533
|
+
if (block && typeof block === "object" && "type" in block && block.type === "text") {
|
|
15534
|
+
const text2 = block.text;
|
|
15535
|
+
if (typeof text2 === "string") {
|
|
15536
|
+
const parsed = tryParse(text2);
|
|
15537
|
+
if (parsed) return parsed;
|
|
15538
|
+
}
|
|
15539
|
+
}
|
|
15540
|
+
}
|
|
15541
|
+
}
|
|
15542
|
+
return void 0;
|
|
15543
|
+
}
|
|
15544
|
+
function applyTaskCreate(state, input, output) {
|
|
15545
|
+
const taskId = output?.task?.id;
|
|
15546
|
+
if (!taskId || !input) return;
|
|
15547
|
+
state.set(taskId, {
|
|
15548
|
+
subject: input.subject,
|
|
15549
|
+
status: "pending",
|
|
15550
|
+
activeForm: input.activeForm,
|
|
15551
|
+
description: input.description
|
|
15552
|
+
});
|
|
15553
|
+
}
|
|
15554
|
+
function applyTaskUpdate(state, input) {
|
|
15555
|
+
if (!input?.taskId) return;
|
|
15556
|
+
if (input.status === "deleted") {
|
|
15557
|
+
state.delete(input.taskId);
|
|
15558
|
+
return;
|
|
15559
|
+
}
|
|
15560
|
+
const existing = state.get(input.taskId);
|
|
15561
|
+
const subject = input.subject ?? existing?.subject;
|
|
15562
|
+
if (!subject) return;
|
|
15563
|
+
state.set(input.taskId, {
|
|
15564
|
+
subject,
|
|
15565
|
+
status: input.status ?? existing?.status ?? "pending",
|
|
15566
|
+
activeForm: input.activeForm ?? existing?.activeForm,
|
|
15567
|
+
description: input.description ?? existing?.description
|
|
15568
|
+
});
|
|
15569
|
+
}
|
|
15570
|
+
function taskStateToPlanEntries(state) {
|
|
15571
|
+
return Array.from(state.values()).map((task) => ({
|
|
15572
|
+
content: task.subject,
|
|
15573
|
+
status: task.status,
|
|
15574
|
+
priority: "medium"
|
|
15575
|
+
}));
|
|
15576
|
+
}
|
|
15577
|
+
function isToolUseBlock(block) {
|
|
15578
|
+
return !!block && typeof block === "object" && block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string";
|
|
15579
|
+
}
|
|
15580
|
+
function isToolResultBlock(block) {
|
|
15581
|
+
return !!block && typeof block === "object" && block.type === "tool_result" && typeof block.tool_use_id === "string";
|
|
15582
|
+
}
|
|
15583
|
+
function rehydrateTaskState(messages, state) {
|
|
15584
|
+
const pendingInputs = /* @__PURE__ */ new Map();
|
|
15585
|
+
for (const msg of messages) {
|
|
15586
|
+
const content = msg.message?.content;
|
|
15587
|
+
if (!Array.isArray(content)) continue;
|
|
15588
|
+
if (msg.type === "assistant") {
|
|
15589
|
+
for (const block of content) {
|
|
15590
|
+
if (isToolUseBlock(block) && (block.name === "TaskCreate" || block.name === "TaskUpdate")) {
|
|
15591
|
+
pendingInputs.set(block.id, { name: block.name, input: block.input });
|
|
15592
|
+
}
|
|
15593
|
+
}
|
|
15594
|
+
} else if (msg.type === "user") {
|
|
15595
|
+
for (const block of content) {
|
|
15596
|
+
if (!isToolResultBlock(block) || block.is_error) continue;
|
|
15597
|
+
const cached = pendingInputs.get(block.tool_use_id);
|
|
15598
|
+
if (!cached) continue;
|
|
15599
|
+
if (cached.name === "TaskCreate") {
|
|
15600
|
+
applyTaskCreate(
|
|
15601
|
+
state,
|
|
15602
|
+
cached.input,
|
|
15603
|
+
parseTaskCreateOutput(block.content)
|
|
15604
|
+
);
|
|
15605
|
+
} else if (cached.name === "TaskUpdate") {
|
|
15606
|
+
applyTaskUpdate(state, cached.input);
|
|
15607
|
+
}
|
|
15608
|
+
pendingInputs.delete(block.tool_use_id);
|
|
15609
|
+
}
|
|
15610
|
+
}
|
|
15611
|
+
}
|
|
15612
|
+
}
|
|
15613
|
+
|
|
15475
15614
|
// src/adapters/claude/conversion/tool-use-to-acp.ts
|
|
15476
15615
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
15477
15616
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
@@ -15823,9 +15962,31 @@ function toolInfoFromToolUse(toolUse, options) {
|
|
|
15823
15962
|
content: []
|
|
15824
15963
|
};
|
|
15825
15964
|
}
|
|
15826
|
-
case "
|
|
15965
|
+
case "TaskCreate": {
|
|
15966
|
+
const subject = typeof input?.subject === "string" ? input.subject : void 0;
|
|
15827
15967
|
return {
|
|
15828
|
-
title:
|
|
15968
|
+
title: subject ? `Create task: ${subject}` : "Create task",
|
|
15969
|
+
kind: "think",
|
|
15970
|
+
content: []
|
|
15971
|
+
};
|
|
15972
|
+
}
|
|
15973
|
+
case "TaskUpdate": {
|
|
15974
|
+
const subject = typeof input?.subject === "string" ? input.subject : void 0;
|
|
15975
|
+
return {
|
|
15976
|
+
title: subject ? `Update task: ${subject}` : "Update task",
|
|
15977
|
+
kind: "think",
|
|
15978
|
+
content: []
|
|
15979
|
+
};
|
|
15980
|
+
}
|
|
15981
|
+
case "TaskList":
|
|
15982
|
+
return {
|
|
15983
|
+
title: "List tasks",
|
|
15984
|
+
kind: "think",
|
|
15985
|
+
content: []
|
|
15986
|
+
};
|
|
15987
|
+
case "TaskGet":
|
|
15988
|
+
return {
|
|
15989
|
+
title: "Get task",
|
|
15829
15990
|
kind: "think",
|
|
15830
15991
|
content: []
|
|
15831
15992
|
};
|
|
@@ -16109,13 +16270,6 @@ ${content}
|
|
|
16109
16270
|
}
|
|
16110
16271
|
return {};
|
|
16111
16272
|
}
|
|
16112
|
-
function planEntries(input) {
|
|
16113
|
-
return input.todos.map((input2) => ({
|
|
16114
|
-
content: input2.content,
|
|
16115
|
-
status: input2.status,
|
|
16116
|
-
priority: "medium"
|
|
16117
|
-
}));
|
|
16118
|
-
}
|
|
16119
16273
|
function resolveFileContent(filePath, oldText, cachedFileContent) {
|
|
16120
16274
|
if (cachedFileContent && filePath in cachedFileContent) {
|
|
16121
16275
|
const cached = cachedFileContent[filePath];
|
|
@@ -16201,14 +16355,7 @@ function handleThinkingChunk(chunk, parentToolCallId) {
|
|
|
16201
16355
|
function handleToolUseChunk(chunk, ctx) {
|
|
16202
16356
|
const alreadyCached = chunk.id in ctx.toolUseCache;
|
|
16203
16357
|
ctx.toolUseCache[chunk.id] = chunk;
|
|
16204
|
-
if (chunk.name === "
|
|
16205
|
-
const input = chunk.input;
|
|
16206
|
-
if (Array.isArray(input.todos)) {
|
|
16207
|
-
return {
|
|
16208
|
-
sessionUpdate: "plan",
|
|
16209
|
-
entries: planEntries(chunk.input)
|
|
16210
|
-
};
|
|
16211
|
-
}
|
|
16358
|
+
if (chunk.name === "TaskCreate" || chunk.name === "TaskUpdate" || chunk.name === "TaskList" || chunk.name === "TaskGet") {
|
|
16212
16359
|
return null;
|
|
16213
16360
|
}
|
|
16214
16361
|
if (!alreadyCached && ctx.registerHooks !== false) {
|
|
@@ -16216,7 +16363,7 @@ function handleToolUseChunk(chunk, ctx) {
|
|
|
16216
16363
|
onPostToolUseHook: async (toolUseId, _toolInput, toolResponse) => {
|
|
16217
16364
|
const toolUse = ctx.toolUseCache[toolUseId];
|
|
16218
16365
|
if (toolUse) {
|
|
16219
|
-
const editUpdate = toolUse.name === "Edit" ? toolUpdateFromEditToolResponse(toolResponse) : null;
|
|
16366
|
+
const editUpdate = toolUse.name === "Edit" || toolUse.name === "Write" ? toolUpdateFromEditToolResponse(toolResponse) : null;
|
|
16220
16367
|
await ctx.client.sessionUpdate({
|
|
16221
16368
|
sessionId: ctx.sessionId,
|
|
16222
16369
|
update: {
|
|
@@ -16328,7 +16475,28 @@ function handleToolResultChunk(chunk, ctx) {
|
|
|
16328
16475
|
);
|
|
16329
16476
|
return [];
|
|
16330
16477
|
}
|
|
16331
|
-
if (toolUse.name === "
|
|
16478
|
+
if (toolUse.name === "TaskCreate" || toolUse.name === "TaskUpdate" || toolUse.name === "TaskList" || toolUse.name === "TaskGet") {
|
|
16479
|
+
if (chunk.is_error || !ctx.taskState) return [];
|
|
16480
|
+
if (toolUse.name === "TaskCreate") {
|
|
16481
|
+
applyTaskCreate(
|
|
16482
|
+
ctx.taskState,
|
|
16483
|
+
toolUse.input,
|
|
16484
|
+
parseTaskCreateOutput(chunk.content)
|
|
16485
|
+
);
|
|
16486
|
+
} else if (toolUse.name === "TaskUpdate") {
|
|
16487
|
+
applyTaskUpdate(
|
|
16488
|
+
ctx.taskState,
|
|
16489
|
+
toolUse.input
|
|
16490
|
+
);
|
|
16491
|
+
}
|
|
16492
|
+
if (toolUse.name === "TaskCreate" || toolUse.name === "TaskUpdate") {
|
|
16493
|
+
return [
|
|
16494
|
+
{
|
|
16495
|
+
sessionUpdate: "plan",
|
|
16496
|
+
entries: taskStateToPlanEntries(ctx.taskState)
|
|
16497
|
+
}
|
|
16498
|
+
];
|
|
16499
|
+
}
|
|
16332
16500
|
return [];
|
|
16333
16501
|
}
|
|
16334
16502
|
if (!chunk.is_error) {
|
|
@@ -16425,13 +16593,15 @@ function processContentChunk(chunk, role, ctx) {
|
|
|
16425
16593
|
case "container_upload":
|
|
16426
16594
|
case "compaction":
|
|
16427
16595
|
case "compaction_delta":
|
|
16596
|
+
case "advisor_tool_result":
|
|
16597
|
+
case "mid_conv_system":
|
|
16428
16598
|
return [];
|
|
16429
16599
|
default:
|
|
16430
16600
|
unreachable(chunk, ctx.logger);
|
|
16431
16601
|
return [];
|
|
16432
16602
|
}
|
|
16433
16603
|
}
|
|
16434
|
-
function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, mcpToolUseResult, enrichedReadCache) {
|
|
16604
|
+
function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, mcpToolUseResult, enrichedReadCache, taskState) {
|
|
16435
16605
|
if (typeof content === "string") {
|
|
16436
16606
|
const update = {
|
|
16437
16607
|
sessionUpdate: messageUpdateType(role),
|
|
@@ -16457,7 +16627,8 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
|
|
|
16457
16627
|
registerHooks,
|
|
16458
16628
|
supportsTerminalOutput,
|
|
16459
16629
|
cwd,
|
|
16460
|
-
mcpToolUseResult
|
|
16630
|
+
mcpToolUseResult,
|
|
16631
|
+
taskState
|
|
16461
16632
|
};
|
|
16462
16633
|
const output = [];
|
|
16463
16634
|
for (const chunk of content) {
|
|
@@ -16467,7 +16638,7 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
|
|
|
16467
16638
|
}
|
|
16468
16639
|
return output;
|
|
16469
16640
|
}
|
|
16470
|
-
function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
|
|
16641
|
+
function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache, taskState) {
|
|
16471
16642
|
const event = message.event;
|
|
16472
16643
|
switch (event.type) {
|
|
16473
16644
|
case "content_block_start": {
|
|
@@ -16491,7 +16662,8 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUse
|
|
|
16491
16662
|
supportsTerminalOutput,
|
|
16492
16663
|
cwd,
|
|
16493
16664
|
void 0,
|
|
16494
|
-
enrichedReadCache
|
|
16665
|
+
enrichedReadCache,
|
|
16666
|
+
taskState
|
|
16495
16667
|
);
|
|
16496
16668
|
}
|
|
16497
16669
|
case "content_block_delta": {
|
|
@@ -16516,12 +16688,18 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUse
|
|
|
16516
16688
|
supportsTerminalOutput,
|
|
16517
16689
|
cwd,
|
|
16518
16690
|
void 0,
|
|
16519
|
-
enrichedReadCache
|
|
16691
|
+
enrichedReadCache,
|
|
16692
|
+
taskState
|
|
16520
16693
|
);
|
|
16521
16694
|
}
|
|
16522
16695
|
case "content_block_stop":
|
|
16523
16696
|
toolUseStreamCache.delete(event.index);
|
|
16524
16697
|
return [];
|
|
16698
|
+
// `ping` is a Messages-API keep-alive event that the SDK's
|
|
16699
|
+
// `BetaRawMessageStreamEvent` union doesn't include even though the
|
|
16700
|
+
// wire format emits it; the `as never` cast lets us no-op it here
|
|
16701
|
+
// instead of falling through to `unreachable`.
|
|
16702
|
+
case "ping":
|
|
16525
16703
|
case "message_start":
|
|
16526
16704
|
case "message_delta":
|
|
16527
16705
|
case "message_stop":
|
|
@@ -16592,6 +16770,38 @@ async function handleSystemMessage(message, context) {
|
|
|
16592
16770
|
});
|
|
16593
16771
|
break;
|
|
16594
16772
|
}
|
|
16773
|
+
case "memory_recall": {
|
|
16774
|
+
const isSynthesis = message.mode === "synthesize";
|
|
16775
|
+
if (!isSynthesis && message.memories.length === 0) break;
|
|
16776
|
+
const locations = isSynthesis ? [] : message.memories.map((m) => ({ path: m.path }));
|
|
16777
|
+
const content = isSynthesis ? message.memories.filter(
|
|
16778
|
+
(m) => typeof m.content === "string"
|
|
16779
|
+
).map((m) => ({
|
|
16780
|
+
type: "content",
|
|
16781
|
+
content: { type: "text", text: m.content }
|
|
16782
|
+
})) : [];
|
|
16783
|
+
const count = message.memories.length;
|
|
16784
|
+
const title = isSynthesis ? "Recalled synthesized memory" : `Recalled ${count} ${count === 1 ? "memory" : "memories"}`;
|
|
16785
|
+
await client.sessionUpdate({
|
|
16786
|
+
sessionId: message.session_id,
|
|
16787
|
+
update: {
|
|
16788
|
+
sessionUpdate: "tool_call",
|
|
16789
|
+
toolCallId: message.uuid,
|
|
16790
|
+
title,
|
|
16791
|
+
kind: "read",
|
|
16792
|
+
status: "completed",
|
|
16793
|
+
...locations.length > 0 && { locations },
|
|
16794
|
+
...content.length > 0 && { content },
|
|
16795
|
+
_meta: {
|
|
16796
|
+
claudeCode: {
|
|
16797
|
+
toolName: "memory_recall",
|
|
16798
|
+
toolResponse: { mode: message.mode }
|
|
16799
|
+
}
|
|
16800
|
+
}
|
|
16801
|
+
}
|
|
16802
|
+
});
|
|
16803
|
+
break;
|
|
16804
|
+
}
|
|
16595
16805
|
default:
|
|
16596
16806
|
break;
|
|
16597
16807
|
}
|
|
@@ -16701,7 +16911,8 @@ async function handleStreamEvent(message, context) {
|
|
|
16701
16911
|
context.registerHooks,
|
|
16702
16912
|
context.supportsTerminalOutput,
|
|
16703
16913
|
context.session.cwd,
|
|
16704
|
-
context.enrichedReadCache
|
|
16914
|
+
context.enrichedReadCache,
|
|
16915
|
+
context.session.taskState
|
|
16705
16916
|
)) {
|
|
16706
16917
|
await client.sessionUpdate(notification);
|
|
16707
16918
|
context.session.notificationHistory.push(notification);
|
|
@@ -16713,6 +16924,17 @@ function hasLocalCommandStdout(content) {
|
|
|
16713
16924
|
function hasLocalCommandStderr(content) {
|
|
16714
16925
|
return typeof content === "string" && content.includes("<local-command-stderr>");
|
|
16715
16926
|
}
|
|
16927
|
+
function isSdkLocalCommandMessage(content) {
|
|
16928
|
+
return typeof content === "string" && content.includes("<command-name>") && (content.includes("<local-command-stdout>") || content.includes("<local-command-stderr>"));
|
|
16929
|
+
}
|
|
16930
|
+
var LOCAL_COMMAND_TAG_PATTERN = /<(command-name|command-message|command-args|local-command-stdout|local-command-stderr)>[\s\S]*?<\/\1>/g;
|
|
16931
|
+
function stripMarkerTags(text2) {
|
|
16932
|
+
return text2.replace(LOCAL_COMMAND_TAG_PATTERN, "");
|
|
16933
|
+
}
|
|
16934
|
+
function stripLocalCommandMetadata(content) {
|
|
16935
|
+
const stripped = stripMarkerTags(content);
|
|
16936
|
+
return stripped.trim() === "" ? null : stripped;
|
|
16937
|
+
}
|
|
16716
16938
|
function isLoginRequiredMessage(message) {
|
|
16717
16939
|
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;
|
|
16718
16940
|
}
|
|
@@ -16721,7 +16943,7 @@ function isPlainTextUserMessage(message) {
|
|
|
16721
16943
|
return message.type === "user" && (typeof content === "string" || Array.isArray(content) && content.length === 1 && content[0].type === "text");
|
|
16722
16944
|
}
|
|
16723
16945
|
function shouldSkipUserAssistantMessage(message) {
|
|
16724
|
-
return
|
|
16946
|
+
return isSdkLocalCommandMessage(message.message.content) || isLoginRequiredMessage(message);
|
|
16725
16947
|
}
|
|
16726
16948
|
function logSpecialMessages(message, logger) {
|
|
16727
16949
|
const content = message.message.content;
|
|
@@ -16742,11 +16964,39 @@ function filterMessageContent(content) {
|
|
|
16742
16964
|
}
|
|
16743
16965
|
async function handleUserAssistantMessage(message, context) {
|
|
16744
16966
|
const { session, sessionId, client, toolUseCache, fileContentCache, logger } = context;
|
|
16967
|
+
if (message.message.role === "system") {
|
|
16968
|
+
return {};
|
|
16969
|
+
}
|
|
16745
16970
|
if (shouldSkipUserAssistantMessage(message)) {
|
|
16746
16971
|
logSpecialMessages(message, logger);
|
|
16747
16972
|
if (isLoginRequiredMessage(message)) {
|
|
16748
16973
|
return { shouldStop: true, error: import_sdk.RequestError.authRequired() };
|
|
16749
16974
|
}
|
|
16975
|
+
const rawContent = message.message.content;
|
|
16976
|
+
if (typeof rawContent === "string") {
|
|
16977
|
+
const stripped = stripLocalCommandMetadata(rawContent);
|
|
16978
|
+
if (stripped !== null) {
|
|
16979
|
+
for (const notification of toAcpNotifications(
|
|
16980
|
+
stripped,
|
|
16981
|
+
message.message.role,
|
|
16982
|
+
sessionId,
|
|
16983
|
+
toolUseCache,
|
|
16984
|
+
fileContentCache,
|
|
16985
|
+
client,
|
|
16986
|
+
logger,
|
|
16987
|
+
void 0,
|
|
16988
|
+
context.registerHooks,
|
|
16989
|
+
context.supportsTerminalOutput,
|
|
16990
|
+
session.cwd,
|
|
16991
|
+
void 0,
|
|
16992
|
+
context.enrichedReadCache,
|
|
16993
|
+
session.taskState
|
|
16994
|
+
)) {
|
|
16995
|
+
await client.sessionUpdate(notification);
|
|
16996
|
+
session.notificationHistory.push(notification);
|
|
16997
|
+
}
|
|
16998
|
+
}
|
|
16999
|
+
}
|
|
16750
17000
|
return {};
|
|
16751
17001
|
}
|
|
16752
17002
|
if (isPlainTextUserMessage(message)) {
|
|
@@ -16769,7 +17019,8 @@ async function handleUserAssistantMessage(message, context) {
|
|
|
16769
17019
|
context.supportsTerminalOutput,
|
|
16770
17020
|
session.cwd,
|
|
16771
17021
|
mcpToolUseResult,
|
|
16772
|
-
context.enrichedReadCache
|
|
17022
|
+
context.enrichedReadCache,
|
|
17023
|
+
session.taskState
|
|
16773
17024
|
)) {
|
|
16774
17025
|
await client.sessionUpdate(notification);
|
|
16775
17026
|
session.notificationHistory.push(notification);
|
|
@@ -16962,8 +17213,10 @@ var WEB_TOOLS = /* @__PURE__ */ new Set(["WebSearch", "WebFetch"]);
|
|
|
16962
17213
|
var AGENT_TOOLS = /* @__PURE__ */ new Set([
|
|
16963
17214
|
"Task",
|
|
16964
17215
|
"Agent",
|
|
16965
|
-
"
|
|
16966
|
-
"
|
|
17216
|
+
"TaskCreate",
|
|
17217
|
+
"TaskUpdate",
|
|
17218
|
+
"TaskGet",
|
|
17219
|
+
"TaskList"
|
|
16967
17220
|
]);
|
|
16968
17221
|
var BASE_ALLOWED_TOOLS = [
|
|
16969
17222
|
...READ_TOOLS,
|
|
@@ -17047,8 +17300,8 @@ function buildPermissionOptions(toolName, toolInput, repoRoot, suggestions) {
|
|
|
17047
17300
|
if (toolName === "Task") {
|
|
17048
17301
|
return permissionOptions("Yes, allow all sub-tasks");
|
|
17049
17302
|
}
|
|
17050
|
-
if (toolName === "
|
|
17051
|
-
return permissionOptions("Yes, allow all
|
|
17303
|
+
if (toolName === "TaskCreate" || toolName === "TaskUpdate" || toolName === "TaskGet" || toolName === "TaskList") {
|
|
17304
|
+
return permissionOptions("Yes, allow all task updates");
|
|
17052
17305
|
}
|
|
17053
17306
|
return permissionOptions("Yes, always allow");
|
|
17054
17307
|
}
|
|
@@ -17600,6 +17853,7 @@ async function canUseTool(context) {
|
|
|
17600
17853
|
|
|
17601
17854
|
// src/adapters/claude/session/commands.ts
|
|
17602
17855
|
var UNSUPPORTED_COMMANDS = [
|
|
17856
|
+
"clear",
|
|
17603
17857
|
"context",
|
|
17604
17858
|
"cost",
|
|
17605
17859
|
"keybindings-help",
|
|
@@ -17654,18 +17908,30 @@ function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os3.homedir()) {
|
|
|
17654
17908
|
const projectScoped = project?.mcpServers && typeof project.mcpServers === "object" ? project.mcpServers : {};
|
|
17655
17909
|
return { ...topLevel, ...projectScoped };
|
|
17656
17910
|
}
|
|
17657
|
-
function parseMcpServers(params) {
|
|
17911
|
+
function parseMcpServers(params, logger) {
|
|
17658
17912
|
const mcpServers = {};
|
|
17659
17913
|
if (!Array.isArray(params.mcpServers)) {
|
|
17660
17914
|
return mcpServers;
|
|
17661
17915
|
}
|
|
17662
17916
|
for (const server of params.mcpServers) {
|
|
17663
17917
|
if ("type" in server) {
|
|
17664
|
-
|
|
17665
|
-
|
|
17666
|
-
|
|
17667
|
-
|
|
17668
|
-
|
|
17918
|
+
if (server.type === "http" || server.type === "sse") {
|
|
17919
|
+
mcpServers[server.name] = {
|
|
17920
|
+
type: server.type,
|
|
17921
|
+
url: server.url,
|
|
17922
|
+
headers: server.headers ? Object.fromEntries(
|
|
17923
|
+
server.headers.map((e) => [
|
|
17924
|
+
e.name,
|
|
17925
|
+
e.value
|
|
17926
|
+
])
|
|
17927
|
+
) : void 0
|
|
17928
|
+
};
|
|
17929
|
+
} else {
|
|
17930
|
+
logger?.warn("parseMcpServers: dropping unsupported MCP server type", {
|
|
17931
|
+
name: server.name,
|
|
17932
|
+
type: server.type
|
|
17933
|
+
});
|
|
17934
|
+
}
|
|
17669
17935
|
} else {
|
|
17670
17936
|
mcpServers[server.name] = {
|
|
17671
17937
|
type: "stdio",
|
|
@@ -17678,6 +17944,36 @@ function parseMcpServers(params) {
|
|
|
17678
17944
|
return mcpServers;
|
|
17679
17945
|
}
|
|
17680
17946
|
|
|
17947
|
+
// src/adapters/claude/session/model-config.ts
|
|
17948
|
+
function applyAvailableModelsAllowlist(modelOptions, allowlist) {
|
|
17949
|
+
const filtered = [];
|
|
17950
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17951
|
+
for (const entry of allowlist) {
|
|
17952
|
+
const trimmed2 = entry.trim();
|
|
17953
|
+
if (!trimmed2 || seen.has(trimmed2)) continue;
|
|
17954
|
+
const match = modelOptions.options.find((o) => o.value === trimmed2);
|
|
17955
|
+
if (match) {
|
|
17956
|
+
filtered.push(match);
|
|
17957
|
+
seen.add(trimmed2);
|
|
17958
|
+
}
|
|
17959
|
+
}
|
|
17960
|
+
if (filtered.length === 0) return modelOptions;
|
|
17961
|
+
const currentModelId = filtered.some(
|
|
17962
|
+
(o) => o.value === modelOptions.currentModelId
|
|
17963
|
+
) ? modelOptions.currentModelId : filtered[0].value;
|
|
17964
|
+
return { currentModelId, options: filtered };
|
|
17965
|
+
}
|
|
17966
|
+
function resolveInitialModelId(modelOptions, preferredModelIds) {
|
|
17967
|
+
const allowedModelIds = new Set(modelOptions.options.map((opt) => opt.value));
|
|
17968
|
+
for (const candidate of preferredModelIds) {
|
|
17969
|
+
const trimmed2 = candidate?.trim();
|
|
17970
|
+
if (trimmed2 && allowedModelIds.has(trimmed2)) {
|
|
17971
|
+
return trimmed2;
|
|
17972
|
+
}
|
|
17973
|
+
}
|
|
17974
|
+
return modelOptions.currentModelId;
|
|
17975
|
+
}
|
|
17976
|
+
|
|
17681
17977
|
// src/adapters/claude/session/options.ts
|
|
17682
17978
|
var import_node_child_process3 = require("child_process");
|
|
17683
17979
|
var fs8 = __toESM(require("fs"), 1);
|
|
@@ -17745,6 +18041,7 @@ function buildEnvironment() {
|
|
|
17745
18041
|
const existingCustomHeaders = process.env.ANTHROPIC_CUSTOM_HEADERS;
|
|
17746
18042
|
const customHeaders = existingCustomHeaders ? `${existingCustomHeaders}
|
|
17747
18043
|
${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
18044
|
+
const mcpNonblocking = process.env.MCP_CONNECTION_NONBLOCKING;
|
|
17748
18045
|
return {
|
|
17749
18046
|
...process.env,
|
|
17750
18047
|
ELECTRON_RUN_AS_NODE: "1",
|
|
@@ -17753,11 +18050,14 @@ ${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
|
17753
18050
|
ENABLE_TOOL_SEARCH: "auto:0",
|
|
17754
18051
|
// Enable idle state as end-of-turn signal (required for SDK 0.2.114+)
|
|
17755
18052
|
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1",
|
|
18053
|
+
...mcpNonblocking !== void 0 && {
|
|
18054
|
+
MCP_CONNECTION_NONBLOCKING: mcpNonblocking
|
|
18055
|
+
},
|
|
17756
18056
|
// Route to AWS Bedrock as a fallback when Anthropic returns 5xx
|
|
17757
18057
|
ANTHROPIC_CUSTOM_HEADERS: customHeaders
|
|
17758
18058
|
};
|
|
17759
18059
|
}
|
|
17760
|
-
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode) {
|
|
18060
|
+
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode, taskState, onTaskStateChange) {
|
|
17761
18061
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange })];
|
|
17762
18062
|
if (enrichmentDeps && enrichedReadCache) {
|
|
17763
18063
|
postToolUseHooks.push(
|
|
@@ -17771,13 +18071,16 @@ function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichment
|
|
|
17771
18071
|
if (cloudMode) {
|
|
17772
18072
|
preToolUseHooks.push(createSignedCommitGuardHook(logger));
|
|
17773
18073
|
}
|
|
18074
|
+
const taskHook = createTaskHook(taskState, onTaskStateChange);
|
|
17774
18075
|
return {
|
|
17775
18076
|
...userHooks,
|
|
17776
18077
|
PostToolUse: [
|
|
17777
18078
|
...userHooks?.PostToolUse || [],
|
|
17778
18079
|
{ hooks: postToolUseHooks }
|
|
17779
18080
|
],
|
|
17780
|
-
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }]
|
|
18081
|
+
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }],
|
|
18082
|
+
TaskCreated: [...userHooks?.TaskCreated || [], { hooks: [taskHook] }],
|
|
18083
|
+
TaskCompleted: [...userHooks?.TaskCompleted || [], { hooks: [taskHook] }]
|
|
17781
18084
|
};
|
|
17782
18085
|
}
|
|
17783
18086
|
var PH_EXPLORE_AGENT = {
|
|
@@ -17808,7 +18111,10 @@ Rules:
|
|
|
17808
18111
|
"WebFetch",
|
|
17809
18112
|
"WebSearch",
|
|
17810
18113
|
"NotebookRead",
|
|
17811
|
-
"
|
|
18114
|
+
"TaskCreate",
|
|
18115
|
+
"TaskUpdate",
|
|
18116
|
+
"TaskGet",
|
|
18117
|
+
"TaskList"
|
|
17812
18118
|
]
|
|
17813
18119
|
};
|
|
17814
18120
|
function buildAgents(userAgents) {
|
|
@@ -17936,7 +18242,9 @@ function buildSessionOptions(params) {
|
|
|
17936
18242
|
params.enrichmentDeps,
|
|
17937
18243
|
params.enrichedReadCache,
|
|
17938
18244
|
registeredAgentNames,
|
|
17939
|
-
params.cloudMode ?? false
|
|
18245
|
+
params.cloudMode ?? false,
|
|
18246
|
+
params.taskState,
|
|
18247
|
+
params.onTaskStateChange
|
|
17940
18248
|
),
|
|
17941
18249
|
outputFormat: params.outputFormat,
|
|
17942
18250
|
abortController: getAbortController(
|
|
@@ -18165,6 +18473,15 @@ function getManagedSettingsPath() {
|
|
|
18165
18473
|
return "/etc/claude-code/managed-settings.json";
|
|
18166
18474
|
}
|
|
18167
18475
|
}
|
|
18476
|
+
function mergeAvailableModels(existing, incoming, layer) {
|
|
18477
|
+
if (incoming === void 0) {
|
|
18478
|
+
return existing;
|
|
18479
|
+
}
|
|
18480
|
+
if (layer === "enterprise") {
|
|
18481
|
+
return Array.from(new Set(incoming));
|
|
18482
|
+
}
|
|
18483
|
+
return Array.from(/* @__PURE__ */ new Set([...existing ?? [], ...incoming]));
|
|
18484
|
+
}
|
|
18168
18485
|
var SettingsManager = class {
|
|
18169
18486
|
cwd;
|
|
18170
18487
|
repoRoot;
|
|
@@ -18220,10 +18537,10 @@ var SettingsManager = class {
|
|
|
18220
18537
|
}
|
|
18221
18538
|
mergeAllSettings() {
|
|
18222
18539
|
const allSettings = [
|
|
18223
|
-
this.userSettings,
|
|
18224
|
-
this.projectSettings,
|
|
18225
|
-
this.localSettings,
|
|
18226
|
-
this.enterpriseSettings
|
|
18540
|
+
{ layer: "user", settings: this.userSettings },
|
|
18541
|
+
{ layer: "project", settings: this.projectSettings },
|
|
18542
|
+
{ layer: "local", settings: this.localSettings },
|
|
18543
|
+
{ layer: "enterprise", settings: this.enterpriseSettings }
|
|
18227
18544
|
];
|
|
18228
18545
|
const permissions = {
|
|
18229
18546
|
allow: [],
|
|
@@ -18232,7 +18549,7 @@ var SettingsManager = class {
|
|
|
18232
18549
|
};
|
|
18233
18550
|
const merged = { permissions };
|
|
18234
18551
|
const posthogApprovedExecTools = /* @__PURE__ */ new Set();
|
|
18235
|
-
for (const settings of allSettings) {
|
|
18552
|
+
for (const { layer, settings } of allSettings) {
|
|
18236
18553
|
if (settings.permissions) {
|
|
18237
18554
|
if (settings.permissions.allow) {
|
|
18238
18555
|
permissions.allow?.push(...settings.permissions.allow);
|
|
@@ -18259,6 +18576,11 @@ var SettingsManager = class {
|
|
|
18259
18576
|
if (settings.model) {
|
|
18260
18577
|
merged.model = settings.model;
|
|
18261
18578
|
}
|
|
18579
|
+
merged.availableModels = mergeAvailableModels(
|
|
18580
|
+
merged.availableModels,
|
|
18581
|
+
settings.availableModels,
|
|
18582
|
+
layer
|
|
18583
|
+
);
|
|
18262
18584
|
if (settings.posthogApprovedExecTools) {
|
|
18263
18585
|
for (const tool2 of settings.posthogApprovedExecTools) {
|
|
18264
18586
|
posthogApprovedExecTools.add(tool2);
|
|
@@ -18467,6 +18789,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18467
18789
|
},
|
|
18468
18790
|
loadSession: true,
|
|
18469
18791
|
sessionCapabilities: {
|
|
18792
|
+
additionalDirectories: {},
|
|
18470
18793
|
list: {},
|
|
18471
18794
|
fork: {},
|
|
18472
18795
|
resume: {}
|
|
@@ -18492,10 +18815,18 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18492
18815
|
if (fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json.backup")) && !fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json"))) {
|
|
18493
18816
|
throw import_sdk2.RequestError.authRequired();
|
|
18494
18817
|
}
|
|
18495
|
-
const response = await this.createSession(
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18818
|
+
const response = await this.createSession(
|
|
18819
|
+
{
|
|
18820
|
+
cwd: params.cwd,
|
|
18821
|
+
mcpServers: params.mcpServers ?? [],
|
|
18822
|
+
additionalDirectories: params.additionalDirectories,
|
|
18823
|
+
_meta: params._meta
|
|
18824
|
+
},
|
|
18825
|
+
{
|
|
18826
|
+
// Revisit these meta values once we support resume
|
|
18827
|
+
resume: params._meta?.claudeCode?.options?.resume
|
|
18828
|
+
}
|
|
18829
|
+
);
|
|
18499
18830
|
return response;
|
|
18500
18831
|
}
|
|
18501
18832
|
async unstable_forkSession(params) {
|
|
@@ -18503,24 +18834,27 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18503
18834
|
{
|
|
18504
18835
|
cwd: params.cwd,
|
|
18505
18836
|
mcpServers: params.mcpServers ?? [],
|
|
18837
|
+
additionalDirectories: params.additionalDirectories,
|
|
18506
18838
|
_meta: params._meta
|
|
18507
18839
|
},
|
|
18508
18840
|
{ resume: params.sessionId, forkSession: true }
|
|
18509
18841
|
);
|
|
18510
18842
|
}
|
|
18511
|
-
async
|
|
18843
|
+
async resumeSession(params) {
|
|
18512
18844
|
const existing = this.getExistingSessionState(params.sessionId);
|
|
18513
18845
|
if (existing) return existing;
|
|
18514
18846
|
const response = await this.createSession(
|
|
18515
18847
|
{
|
|
18516
18848
|
cwd: params.cwd,
|
|
18517
18849
|
mcpServers: params.mcpServers ?? [],
|
|
18850
|
+
additionalDirectories: params.additionalDirectories,
|
|
18518
18851
|
_meta: params._meta
|
|
18519
18852
|
},
|
|
18520
18853
|
{
|
|
18521
18854
|
resume: params.sessionId
|
|
18522
18855
|
}
|
|
18523
18856
|
);
|
|
18857
|
+
await this.rehydrateTaskStateFromJsonl(params.sessionId);
|
|
18524
18858
|
return response;
|
|
18525
18859
|
}
|
|
18526
18860
|
async loadSession(params) {
|
|
@@ -18530,6 +18864,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18530
18864
|
{
|
|
18531
18865
|
cwd: params.cwd,
|
|
18532
18866
|
mcpServers: params.mcpServers ?? [],
|
|
18867
|
+
additionalDirectories: params.additionalDirectories,
|
|
18533
18868
|
_meta: params._meta
|
|
18534
18869
|
},
|
|
18535
18870
|
{ resume: params.sessionId, skipBackgroundFetches: true }
|
|
@@ -18608,6 +18943,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18608
18943
|
await this.broadcastUserMessage(params);
|
|
18609
18944
|
this.session.promptRunning = true;
|
|
18610
18945
|
let handedOff = false;
|
|
18946
|
+
let errored = false;
|
|
18611
18947
|
let lastAssistantTotalUsage = null;
|
|
18612
18948
|
let lastStreamUsage = {
|
|
18613
18949
|
input_tokens: 0,
|
|
@@ -18615,6 +18951,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18615
18951
|
cache_read_input_tokens: 0,
|
|
18616
18952
|
cache_creation_input_tokens: 0
|
|
18617
18953
|
};
|
|
18954
|
+
let compactionInProgress = false;
|
|
18618
18955
|
if (this.session.lastContextWindowSize == null) {
|
|
18619
18956
|
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
18620
18957
|
this.session.modelId ?? ""
|
|
@@ -18672,6 +19009,40 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18672
19009
|
if (message.subtype === "local_command_output") {
|
|
18673
19010
|
promptReplayed = true;
|
|
18674
19011
|
}
|
|
19012
|
+
if (message.subtype === "status") {
|
|
19013
|
+
if (message.status === "compacting") {
|
|
19014
|
+
compactionInProgress = true;
|
|
19015
|
+
} else if (message.compact_result === "success" && compactionInProgress) {
|
|
19016
|
+
compactionInProgress = false;
|
|
19017
|
+
await this.client.sessionUpdate({
|
|
19018
|
+
sessionId: params.sessionId,
|
|
19019
|
+
update: {
|
|
19020
|
+
sessionUpdate: "agent_message_chunk",
|
|
19021
|
+
content: {
|
|
19022
|
+
type: "text",
|
|
19023
|
+
text: "\n\nCompacting completed."
|
|
19024
|
+
}
|
|
19025
|
+
}
|
|
19026
|
+
});
|
|
19027
|
+
break;
|
|
19028
|
+
} else if (message.compact_result === "failed" && compactionInProgress) {
|
|
19029
|
+
compactionInProgress = false;
|
|
19030
|
+
const reason = message.compact_error ? `: ${message.compact_error}` : ".";
|
|
19031
|
+
await this.client.sessionUpdate({
|
|
19032
|
+
sessionId: params.sessionId,
|
|
19033
|
+
update: {
|
|
19034
|
+
sessionUpdate: "agent_message_chunk",
|
|
19035
|
+
content: {
|
|
19036
|
+
type: "text",
|
|
19037
|
+
text: `
|
|
19038
|
+
|
|
19039
|
+
Compacting failed${reason}`
|
|
19040
|
+
}
|
|
19041
|
+
}
|
|
19042
|
+
});
|
|
19043
|
+
break;
|
|
19044
|
+
}
|
|
19045
|
+
}
|
|
18675
19046
|
if (message.subtype === "session_state_changed" && message.state === "idle") {
|
|
18676
19047
|
if (!promptReplayed) {
|
|
18677
19048
|
const cmdName = commandMatch?.[1].slice(1);
|
|
@@ -18711,7 +19082,9 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18711
19082
|
size: lastContextWindowSize
|
|
18712
19083
|
}
|
|
18713
19084
|
});
|
|
18714
|
-
return {
|
|
19085
|
+
return {
|
|
19086
|
+
stopReason: this.session.cancelled ? "cancelled" : "end_turn"
|
|
19087
|
+
};
|
|
18715
19088
|
}
|
|
18716
19089
|
await handleSystemMessage(message, context);
|
|
18717
19090
|
break;
|
|
@@ -18894,6 +19267,28 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18894
19267
|
}
|
|
18895
19268
|
throw new Error("Session did not end in result");
|
|
18896
19269
|
} catch (error) {
|
|
19270
|
+
errored = true;
|
|
19271
|
+
try {
|
|
19272
|
+
await this.session.query.interrupt();
|
|
19273
|
+
const MAX_DRAIN = 100;
|
|
19274
|
+
for (let i2 = 0; i2 < MAX_DRAIN; i2++) {
|
|
19275
|
+
const { value: m, done } = await this.session.query.next();
|
|
19276
|
+
if (done || !m) break;
|
|
19277
|
+
if (m.type === "system" && m.subtype === "session_state_changed" && m.state === "idle") {
|
|
19278
|
+
break;
|
|
19279
|
+
}
|
|
19280
|
+
if (i2 === MAX_DRAIN - 1) {
|
|
19281
|
+
this.logger.error(
|
|
19282
|
+
`Session ${params.sessionId}: drained ${MAX_DRAIN} messages after error without observing idle`
|
|
19283
|
+
);
|
|
19284
|
+
}
|
|
19285
|
+
}
|
|
19286
|
+
} catch (drainErr) {
|
|
19287
|
+
this.logger.error(
|
|
19288
|
+
`Session ${params.sessionId}: failed to drain query after prompt error`,
|
|
19289
|
+
{ error: drainErr }
|
|
19290
|
+
);
|
|
19291
|
+
}
|
|
18897
19292
|
if (error instanceof import_sdk2.RequestError || !(error instanceof Error)) {
|
|
18898
19293
|
throw error;
|
|
18899
19294
|
}
|
|
@@ -18914,9 +19309,19 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18914
19309
|
this.toolUseStreamCache.clear();
|
|
18915
19310
|
if (!handedOff) {
|
|
18916
19311
|
this.session.promptRunning = false;
|
|
18917
|
-
|
|
18918
|
-
pending.
|
|
18919
|
-
|
|
19312
|
+
if (errored) {
|
|
19313
|
+
for (const pending of this.session.pendingMessages.values()) {
|
|
19314
|
+
pending.resolve(true);
|
|
19315
|
+
}
|
|
19316
|
+
this.session.pendingMessages.clear();
|
|
19317
|
+
} else if (this.session.pendingMessages.size > 0) {
|
|
19318
|
+
const next = [...this.session.pendingMessages.entries()].sort(
|
|
19319
|
+
(a, b) => a[1].order - b[1].order
|
|
19320
|
+
)[0];
|
|
19321
|
+
if (next) {
|
|
19322
|
+
next[1].resolve(false);
|
|
19323
|
+
this.session.pendingMessages.delete(next[0]);
|
|
19324
|
+
}
|
|
18920
19325
|
}
|
|
18921
19326
|
}
|
|
18922
19327
|
}
|
|
@@ -18967,7 +19372,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
18967
19372
|
);
|
|
18968
19373
|
}
|
|
18969
19374
|
const mcpServers = parseMcpServers(
|
|
18970
|
-
params
|
|
19375
|
+
params,
|
|
19376
|
+
this.logger
|
|
18971
19377
|
);
|
|
18972
19378
|
await this.refreshSession(mcpServers);
|
|
18973
19379
|
return { refreshed: true };
|
|
@@ -19152,7 +19558,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19152
19558
|
const settingsManager = new SettingsManager(cwd);
|
|
19153
19559
|
await settingsManager.initialize();
|
|
19154
19560
|
const earlyModelId = settingsManager.getSettings().model || meta?.model || "";
|
|
19155
|
-
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params) : {};
|
|
19561
|
+
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params, this.logger) : {};
|
|
19156
19562
|
const localToolsServer = createLocalToolsMcpServer(
|
|
19157
19563
|
{ cwd, token: resolveGithubToken(), taskId },
|
|
19158
19564
|
meta
|
|
@@ -19176,6 +19582,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19176
19582
|
cwd
|
|
19177
19583
|
});
|
|
19178
19584
|
const permissionMode = meta?.permissionMode && CODE_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
|
|
19585
|
+
const taskState = /* @__PURE__ */ new Map();
|
|
19179
19586
|
const options = buildSessionOptions({
|
|
19180
19587
|
cwd,
|
|
19181
19588
|
mcpServers,
|
|
@@ -19189,7 +19596,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19189
19596
|
forkSession,
|
|
19190
19597
|
additionalDirectories: [
|
|
19191
19598
|
...meta?.claudeCode?.options?.additionalDirectories ?? [],
|
|
19192
|
-
|
|
19599
|
+
// Prefer the official ACP `additionalDirectories` field. Fall back
|
|
19600
|
+
// to the legacy `_meta.additionalRoots` extension for clients that
|
|
19601
|
+
// haven't been updated yet.
|
|
19602
|
+
...params.additionalDirectories ?? meta?.additionalRoots ?? []
|
|
19193
19603
|
],
|
|
19194
19604
|
disableBuiltInTools: meta?.disableBuiltInTools,
|
|
19195
19605
|
outputFormat,
|
|
@@ -19200,7 +19610,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19200
19610
|
effort,
|
|
19201
19611
|
enrichmentDeps: this.enrichment?.deps,
|
|
19202
19612
|
enrichedReadCache: this.enrichedReadCache,
|
|
19203
|
-
cloudMode: cloudRun
|
|
19613
|
+
cloudMode: cloudRun,
|
|
19614
|
+
taskState,
|
|
19615
|
+
onTaskStateChange: async () => {
|
|
19616
|
+
await this.client.sessionUpdate({
|
|
19617
|
+
sessionId,
|
|
19618
|
+
update: {
|
|
19619
|
+
sessionUpdate: "plan",
|
|
19620
|
+
entries: taskStateToPlanEntries(taskState)
|
|
19621
|
+
}
|
|
19622
|
+
});
|
|
19623
|
+
}
|
|
19204
19624
|
});
|
|
19205
19625
|
const abortController = options.abortController;
|
|
19206
19626
|
const q = (0, import_claude_agent_sdk2.query)({ prompt: input, options });
|
|
@@ -19229,6 +19649,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19229
19649
|
systemPrompt: estimateSystemPrompt(systemPrompt),
|
|
19230
19650
|
rules: estimateRulesTokens(readClaudeMdQuietly(cwd, this.logger))
|
|
19231
19651
|
},
|
|
19652
|
+
taskState,
|
|
19232
19653
|
// Custom properties
|
|
19233
19654
|
cwd,
|
|
19234
19655
|
notificationHistory: [],
|
|
@@ -19268,7 +19689,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19268
19689
|
}
|
|
19269
19690
|
}
|
|
19270
19691
|
const initPromise2 = !isResume ? withTimeout(q.initializationResult(), SESSION_VALIDATION_TIMEOUT_MS) : void 0;
|
|
19271
|
-
const [
|
|
19692
|
+
const [rawModelOptions] = await Promise.all([
|
|
19272
19693
|
this.getModelConfigOptions(
|
|
19273
19694
|
settingsManager.getSettings().model || meta?.model || void 0
|
|
19274
19695
|
),
|
|
@@ -19280,6 +19701,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19280
19701
|
})
|
|
19281
19702
|
] : []
|
|
19282
19703
|
]);
|
|
19704
|
+
const settingsAvailableModels = settingsManager.getSettings().availableModels;
|
|
19705
|
+
const modelOptions = Array.isArray(settingsAvailableModels) ? applyAvailableModelsAllowlist(rawModelOptions, settingsAvailableModels) : rawModelOptions;
|
|
19283
19706
|
if (initPromise2) {
|
|
19284
19707
|
try {
|
|
19285
19708
|
const initResult = await initPromise2;
|
|
@@ -19303,9 +19726,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19303
19726
|
throw err2;
|
|
19304
19727
|
}
|
|
19305
19728
|
}
|
|
19306
|
-
const
|
|
19307
|
-
|
|
19308
|
-
|
|
19729
|
+
const resolvedModelId = resolveInitialModelId(modelOptions, [
|
|
19730
|
+
settingsManager.getSettings().model,
|
|
19731
|
+
meta?.model
|
|
19732
|
+
]);
|
|
19309
19733
|
session.modelId = resolvedModelId;
|
|
19310
19734
|
session.lastContextWindowSize = this.getContextWindowForModel(resolvedModelId);
|
|
19311
19735
|
const resolvedSdkModel = toSdkModelId(resolvedModelId);
|
|
@@ -19513,6 +19937,34 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
19513
19937
|
[key]: tokens
|
|
19514
19938
|
};
|
|
19515
19939
|
}
|
|
19940
|
+
/**
|
|
19941
|
+
* Rebuild the in-memory taskState from JSONL and push a plan update so the
|
|
19942
|
+
* client's plan panel reflects pre-resume tasks. `loadSession` already covers
|
|
19943
|
+
* this via the full `replaySessionHistory` notification stream; resume
|
|
19944
|
+
* deliberately stays quiet (the client keeps its own message history) so we
|
|
19945
|
+
* walk the transcript here for state only.
|
|
19946
|
+
*/
|
|
19947
|
+
async rehydrateTaskStateFromJsonl(sessionId) {
|
|
19948
|
+
try {
|
|
19949
|
+
const messages = await (0, import_claude_agent_sdk2.getSessionMessages)(sessionId, {
|
|
19950
|
+
dir: this.session.cwd
|
|
19951
|
+
});
|
|
19952
|
+
rehydrateTaskState(messages, this.session.taskState);
|
|
19953
|
+
if (this.session.taskState.size === 0) return;
|
|
19954
|
+
await this.client.sessionUpdate({
|
|
19955
|
+
sessionId,
|
|
19956
|
+
update: {
|
|
19957
|
+
sessionUpdate: "plan",
|
|
19958
|
+
entries: taskStateToPlanEntries(this.session.taskState)
|
|
19959
|
+
}
|
|
19960
|
+
});
|
|
19961
|
+
} catch (err2) {
|
|
19962
|
+
this.logger.warn("Failed to rehydrate task state", {
|
|
19963
|
+
sessionId,
|
|
19964
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
19965
|
+
});
|
|
19966
|
+
}
|
|
19967
|
+
}
|
|
19516
19968
|
async replaySessionHistory(sessionId) {
|
|
19517
19969
|
try {
|
|
19518
19970
|
const messages = await (0, import_claude_agent_sdk2.getSessionMessages)(sessionId, {
|
|
@@ -20266,7 +20718,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
20266
20718
|
}
|
|
20267
20719
|
return response;
|
|
20268
20720
|
}
|
|
20269
|
-
async
|
|
20721
|
+
async resumeSession(params) {
|
|
20270
20722
|
const meta = params._meta;
|
|
20271
20723
|
const injectedParams = this.applyLocalTools(
|
|
20272
20724
|
this.applyStructuredOutput(
|