@agentclientprotocol/claude-agent-acp 0.34.1 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp-agent.d.ts +6 -0
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +104 -2
- package/dist/index.js +8 -5
- package/dist/lib.d.ts +2 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +2 -2
- package/dist/settings.d.ts +14 -56
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +40 -114
- package/dist/tools.d.ts +38 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +143 -0
- package/dist/utils.d.ts +0 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -17
- package/package.json +9 -9
package/dist/acp-agent.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { CanUseTool, ModelInfo, Options, PermissionMode, PermissionUpdate, Query
|
|
|
3
3
|
import { ContentBlockParam } from "@anthropic-ai/sdk/resources";
|
|
4
4
|
import { BetaContentBlock, BetaRawContentBlockDelta } from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
5
5
|
import { SettingsManager } from "./settings.js";
|
|
6
|
+
import { TaskState } from "./tools.js";
|
|
6
7
|
import { Pushable } from "./utils.js";
|
|
7
8
|
export declare const CLAUDE_CONFIG_DIR: string;
|
|
8
9
|
/**
|
|
@@ -46,6 +47,9 @@ type Session = {
|
|
|
46
47
|
* DEFAULT_CONTEXT_WINDOW, refreshed from each result's modelUsage, and
|
|
47
48
|
* invalidated when the user switches the session's model. */
|
|
48
49
|
contextWindowSize: number;
|
|
50
|
+
/** Accumulated task list for the session, keyed by task ID. Task IDs are
|
|
51
|
+
* per-session, so this state must not be shared across sessions. */
|
|
52
|
+
taskState: TaskState;
|
|
49
53
|
};
|
|
50
54
|
type BackgroundTerminal = {
|
|
51
55
|
handle: TerminalHandle;
|
|
@@ -208,10 +212,12 @@ export declare function toAcpNotifications(content: string | ContentBlockParam[]
|
|
|
208
212
|
clientCapabilities?: ClientCapabilities;
|
|
209
213
|
parentToolUseId?: string | null;
|
|
210
214
|
cwd?: string;
|
|
215
|
+
taskState?: TaskState;
|
|
211
216
|
}): SessionNotification[];
|
|
212
217
|
export declare function streamEventToAcpNotifications(message: SDKPartialAssistantMessage, sessionId: string, toolUseCache: ToolUseCache, client: AgentSideConnection, logger: Logger, options?: {
|
|
213
218
|
clientCapabilities?: ClientCapabilities;
|
|
214
219
|
cwd?: string;
|
|
220
|
+
taskState?: TaskState;
|
|
215
221
|
}): SessionNotification[];
|
|
216
222
|
export declare function runAcp(): {
|
|
217
223
|
connection: AgentSideConnection;
|
package/dist/acp-agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,mBAAmB,EACnB,mBAAmB,EAGnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EAEnB,iBAAiB,EACjB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"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"}
|
package/dist/acp-agent.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as os from "node:os";
|
|
|
5
5
|
import * as path from "node:path";
|
|
6
6
|
import packageJson from "../package.json" with { type: "json" };
|
|
7
7
|
import { SettingsManager } from "./settings.js";
|
|
8
|
-
import { createPostToolUseHook, planEntries, registerHookCallback, toolInfoFromToolUse, toolUpdateFromDiffToolResponse, toolUpdateFromToolResult, } from "./tools.js";
|
|
8
|
+
import { applyTaskCreate, applyTaskUpdate, createPostToolUseHook, createTaskHook, parseTaskCreateOutput, planEntries, registerHookCallback, taskStateToPlanEntries, toolInfoFromToolUse, toolUpdateFromDiffToolResponse, toolUpdateFromToolResult, } from "./tools.js";
|
|
9
9
|
import { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
|
|
10
10
|
export const CLAUDE_CONFIG_DIR = process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
|
|
11
11
|
const MAX_TITLE_LENGTH = 256;
|
|
@@ -548,6 +548,7 @@ export class ClaudeAcpAgent {
|
|
|
548
548
|
case "notification":
|
|
549
549
|
case "api_retry":
|
|
550
550
|
case "mirror_error":
|
|
551
|
+
case "permission_denied":
|
|
551
552
|
// Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
|
|
552
553
|
break;
|
|
553
554
|
default:
|
|
@@ -707,6 +708,7 @@ export class ClaudeAcpAgent {
|
|
|
707
708
|
for (const notification of streamEventToAcpNotifications(message, params.sessionId, this.toolUseCache, this.client, this.logger, {
|
|
708
709
|
clientCapabilities: this.clientCapabilities,
|
|
709
710
|
cwd: session.cwd,
|
|
711
|
+
taskState: session.taskState,
|
|
710
712
|
})) {
|
|
711
713
|
await this.client.sessionUpdate(notification);
|
|
712
714
|
}
|
|
@@ -752,9 +754,28 @@ export class ClaudeAcpAgent {
|
|
|
752
754
|
}
|
|
753
755
|
// Slash commands like /compact can generate invalid output... doesn't match
|
|
754
756
|
// their own docs: https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-slash-commands#%2Fcompact-compact-conversation-history
|
|
757
|
+
//
|
|
758
|
+
// Strip local-command marker tags from the content and render whatever
|
|
759
|
+
// real prose remains, so that custom slash commands / user-defined
|
|
760
|
+
// skills (whose bodies arrive wrapped in <command-*> / <local-command-stdout>
|
|
761
|
+
// markers) and built-in commands that emit textual output reach the UI.
|
|
762
|
+
// Previously this branch dropped every message containing a stdout
|
|
763
|
+
// marker, which silently swallowed every successful skill invocation
|
|
764
|
+
// and any built-in command that emits output through these tags.
|
|
765
|
+
// strip-and-render is safe because stripLocalCommandMetadata returns
|
|
766
|
+
// null when nothing renderable remains (e.g. pure-marker /compact
|
|
767
|
+
// payloads), so the no-render no-op path is preserved for those cases.
|
|
768
|
+
//
|
|
769
|
+
// Refs zed-industries/claude-code-acp#624, #642.
|
|
755
770
|
if (typeof message.message.content === "string" &&
|
|
756
771
|
message.message.content.includes("<local-command-stdout>")) {
|
|
757
772
|
this.logger.log(message.message.content);
|
|
773
|
+
const stripped = stripLocalCommandMetadata(message.message.content);
|
|
774
|
+
if (typeof stripped === "string") {
|
|
775
|
+
for (const notification of toAcpNotifications(stripped, message.message.role, params.sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
776
|
+
await this.client.sessionUpdate(notification);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
758
779
|
break;
|
|
759
780
|
}
|
|
760
781
|
if (typeof message.message.content === "string" &&
|
|
@@ -786,6 +807,7 @@ export class ClaudeAcpAgent {
|
|
|
786
807
|
clientCapabilities: this.clientCapabilities,
|
|
787
808
|
parentToolUseId: message.parent_tool_use_id,
|
|
788
809
|
cwd: session.cwd,
|
|
810
|
+
taskState: session.taskState,
|
|
789
811
|
})) {
|
|
790
812
|
await this.client.sessionUpdate(notification);
|
|
791
813
|
}
|
|
@@ -1005,6 +1027,7 @@ export class ClaudeAcpAgent {
|
|
|
1005
1027
|
registerHooks: false,
|
|
1006
1028
|
clientCapabilities: this.clientCapabilities,
|
|
1007
1029
|
cwd: this.sessions[sessionId]?.cwd,
|
|
1030
|
+
taskState: this.sessions[sessionId]?.taskState,
|
|
1008
1031
|
})) {
|
|
1009
1032
|
await this.client.sessionUpdate(notification);
|
|
1010
1033
|
}
|
|
@@ -1372,6 +1395,10 @@ export class ClaudeAcpAgent {
|
|
|
1372
1395
|
const tools = userProvidedOptions?.tools ??
|
|
1373
1396
|
(params._meta?.disableBuiltInTools === true ? [] : { type: "preset", preset: "claude_code" });
|
|
1374
1397
|
const abortController = userProvidedOptions?.abortController || new AbortController();
|
|
1398
|
+
// Per-session task state. Created here (rather than in the session record
|
|
1399
|
+
// below) so the TaskCreated/TaskCompleted hook callbacks can close over
|
|
1400
|
+
// the same Map that the streaming message handler will read from.
|
|
1401
|
+
const taskState = new Map();
|
|
1375
1402
|
const options = {
|
|
1376
1403
|
systemPrompt,
|
|
1377
1404
|
settingSources: ["user", "project", "local"],
|
|
@@ -1432,6 +1459,44 @@ export class ClaudeAcpAgent {
|
|
|
1432
1459
|
],
|
|
1433
1460
|
},
|
|
1434
1461
|
],
|
|
1462
|
+
TaskCreated: [
|
|
1463
|
+
...(userProvidedOptions?.hooks?.TaskCreated || []),
|
|
1464
|
+
{
|
|
1465
|
+
hooks: [
|
|
1466
|
+
createTaskHook({
|
|
1467
|
+
taskState,
|
|
1468
|
+
onChange: async () => {
|
|
1469
|
+
await this.client.sessionUpdate({
|
|
1470
|
+
sessionId,
|
|
1471
|
+
update: {
|
|
1472
|
+
sessionUpdate: "plan",
|
|
1473
|
+
entries: taskStateToPlanEntries(taskState),
|
|
1474
|
+
},
|
|
1475
|
+
});
|
|
1476
|
+
},
|
|
1477
|
+
}),
|
|
1478
|
+
],
|
|
1479
|
+
},
|
|
1480
|
+
],
|
|
1481
|
+
TaskCompleted: [
|
|
1482
|
+
...(userProvidedOptions?.hooks?.TaskCompleted || []),
|
|
1483
|
+
{
|
|
1484
|
+
hooks: [
|
|
1485
|
+
createTaskHook({
|
|
1486
|
+
taskState,
|
|
1487
|
+
onChange: async () => {
|
|
1488
|
+
await this.client.sessionUpdate({
|
|
1489
|
+
sessionId,
|
|
1490
|
+
update: {
|
|
1491
|
+
sessionUpdate: "plan",
|
|
1492
|
+
entries: taskStateToPlanEntries(taskState),
|
|
1493
|
+
},
|
|
1494
|
+
});
|
|
1495
|
+
},
|
|
1496
|
+
}),
|
|
1497
|
+
],
|
|
1498
|
+
},
|
|
1499
|
+
],
|
|
1435
1500
|
},
|
|
1436
1501
|
...creationOpts,
|
|
1437
1502
|
abortController,
|
|
@@ -1546,6 +1611,7 @@ export class ClaudeAcpAgent {
|
|
|
1546
1611
|
abortController,
|
|
1547
1612
|
emitRawSDKMessages: sessionMeta?.claudeCode?.emitRawSDKMessages ?? false,
|
|
1548
1613
|
contextWindowSize: inferContextWindowFromModel(models.currentModelId) ?? DEFAULT_CONTEXT_WINDOW,
|
|
1614
|
+
taskState,
|
|
1549
1615
|
};
|
|
1550
1616
|
return {
|
|
1551
1617
|
sessionId,
|
|
@@ -2019,6 +2085,7 @@ export function promptToClaude(prompt) {
|
|
|
2019
2085
|
* Only handles text, image, and thinking chunks for now.
|
|
2020
2086
|
*/
|
|
2021
2087
|
export function toAcpNotifications(content, role, sessionId, toolUseCache, client, logger, options) {
|
|
2088
|
+
const taskState = options?.taskState ?? new Map();
|
|
2022
2089
|
const registerHooks = options?.registerHooks !== false;
|
|
2023
2090
|
const supportsTerminalOutput = options?.clientCapabilities?._meta?.["terminal_output"] === true;
|
|
2024
2091
|
if (typeof content === "string") {
|
|
@@ -2090,6 +2157,14 @@ export function toAcpNotifications(content, role, sessionId, toolUseCache, clien
|
|
|
2090
2157
|
};
|
|
2091
2158
|
}
|
|
2092
2159
|
}
|
|
2160
|
+
else if (chunk.name === "TaskCreate" ||
|
|
2161
|
+
chunk.name === "TaskUpdate" ||
|
|
2162
|
+
chunk.name === "TaskList" ||
|
|
2163
|
+
chunk.name === "TaskGet") {
|
|
2164
|
+
// Task* tool_use is suppressed; the plan update is emitted at
|
|
2165
|
+
// tool_result time once we have the task ID (for TaskCreate) and
|
|
2166
|
+
// confirmation that the change took effect.
|
|
2167
|
+
}
|
|
2093
2168
|
else {
|
|
2094
2169
|
// Only register hooks on first encounter to avoid double-firing
|
|
2095
2170
|
if (registerHooks && !alreadyCached) {
|
|
@@ -2188,7 +2263,32 @@ export function toAcpNotifications(content, role, sessionId, toolUseCache, clien
|
|
|
2188
2263
|
logger.error(`[claude-agent-acp] Got a tool result for tool use that wasn't tracked: ${chunk.tool_use_id}`);
|
|
2189
2264
|
break;
|
|
2190
2265
|
}
|
|
2191
|
-
if (toolUse.name
|
|
2266
|
+
if (toolUse.name === "TaskCreate" ||
|
|
2267
|
+
toolUse.name === "TaskUpdate" ||
|
|
2268
|
+
toolUse.name === "TaskList" ||
|
|
2269
|
+
toolUse.name === "TaskGet") {
|
|
2270
|
+
// Headless/SDK sessions emit Task* tools instead of TodoWrite.
|
|
2271
|
+
// TaskCreate / TaskUpdate mutate the accumulated task list; TaskList
|
|
2272
|
+
// and TaskGet are read-only so we just suppress their tool_call /
|
|
2273
|
+
// tool_result events. The plan update is emitted as a snapshot of
|
|
2274
|
+
// the accumulated state, mirroring the legacy TodoWrite behavior.
|
|
2275
|
+
const isError = "is_error" in chunk && chunk.is_error;
|
|
2276
|
+
if (!isError) {
|
|
2277
|
+
if (toolUse.name === "TaskCreate") {
|
|
2278
|
+
applyTaskCreate(taskState, toolUse.input, parseTaskCreateOutput(chunk.content));
|
|
2279
|
+
}
|
|
2280
|
+
else if (toolUse.name === "TaskUpdate") {
|
|
2281
|
+
applyTaskUpdate(taskState, toolUse.input);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
if (!isError && (toolUse.name === "TaskCreate" || toolUse.name === "TaskUpdate")) {
|
|
2285
|
+
update = {
|
|
2286
|
+
sessionUpdate: "plan",
|
|
2287
|
+
entries: taskStateToPlanEntries(taskState),
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
else if (toolUse.name !== "TodoWrite") {
|
|
2192
2292
|
const { _meta: toolMeta, ...toolUpdate } = toolUpdateFromToolResult(chunk, toolUseCache[chunk.tool_use_id], supportsTerminalOutput);
|
|
2193
2293
|
// When terminal output is supported, send terminal_output as a
|
|
2194
2294
|
// separate notification to match codex-acp's streaming lifecycle:
|
|
@@ -2264,12 +2364,14 @@ export function streamEventToAcpNotifications(message, sessionId, toolUseCache,
|
|
|
2264
2364
|
clientCapabilities: options?.clientCapabilities,
|
|
2265
2365
|
parentToolUseId: message.parent_tool_use_id,
|
|
2266
2366
|
cwd: options?.cwd,
|
|
2367
|
+
taskState: options?.taskState,
|
|
2267
2368
|
});
|
|
2268
2369
|
case "content_block_delta":
|
|
2269
2370
|
return toAcpNotifications([event.delta], "assistant", sessionId, toolUseCache, client, logger, {
|
|
2270
2371
|
clientCapabilities: options?.clientCapabilities,
|
|
2271
2372
|
parentToolUseId: message.parent_tool_use_id,
|
|
2272
2373
|
cwd: options?.cwd,
|
|
2374
|
+
taskState: options?.taskState,
|
|
2273
2375
|
});
|
|
2274
2376
|
// No content
|
|
2275
2377
|
case "message_start":
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { loadManagedSettings, applyEnvironmentSettings } from "./utils.js";
|
|
2
|
+
import { resolveSettings } from "@anthropic-ai/claude-agent-sdk";
|
|
4
3
|
import { claudeCliPath, runAcp } from "./acp-agent.js";
|
|
5
4
|
if (process.argv.includes("--cli")) {
|
|
6
5
|
const { spawn } = await import("node:child_process");
|
|
@@ -33,9 +32,13 @@ if (process.argv.includes("--cli")) {
|
|
|
33
32
|
});
|
|
34
33
|
}
|
|
35
34
|
else {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
// Apply env vars from the managed-policy tier before any SDK call so the
|
|
36
|
+
// SDK subprocess inherits them. Going through resolveSettings (vs. a raw
|
|
37
|
+
// read of managed-settings.json) also picks up MDM sources on macOS and
|
|
38
|
+
// HKLM/HKCU on Windows.
|
|
39
|
+
const policy = await resolveSettings({ settingSources: [] });
|
|
40
|
+
for (const [key, value] of Object.entries(policy.effective.env ?? {})) {
|
|
41
|
+
process.env[key] = value;
|
|
39
42
|
}
|
|
40
43
|
// stdout is used to send messages to the client
|
|
41
44
|
// we redirect everything else to stderr to make sure it doesn't interfere with ACP
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ClaudeAcpAgent, isLocalCommandMetadata, stripLocalCommandMetadata, runAcp, toAcpNotifications, streamEventToAcpNotifications, type ToolUpdateMeta, type NewSessionMeta, type SDKMessageFilter, } from "./acp-agent.js";
|
|
2
|
-
export {
|
|
2
|
+
export { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
|
|
3
3
|
export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
|
|
4
|
-
export { SettingsManager, type
|
|
4
|
+
export { SettingsManager, type SettingsManagerOptions } from "./settings.js";
|
|
5
5
|
export type { ClaudePlanEntry } from "./tools.js";
|
|
6
6
|
//# sourceMappingURL=lib.d.ts.map
|
package/dist/lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,MAAM,EACN,kBAAkB,EAClB,6BAA6B,EAC7B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,MAAM,EACN,kBAAkB,EAClB,6BAA6B,EAC7B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAG7E,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/lib.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Export the main agent class and utilities for library usage
|
|
2
2
|
export { ClaudeAcpAgent, isLocalCommandMetadata, stripLocalCommandMetadata, runAcp, toAcpNotifications, streamEventToAcpNotifications, } from "./acp-agent.js";
|
|
3
|
-
export {
|
|
3
|
+
export { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
|
|
4
4
|
export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
|
|
5
|
-
export { SettingsManager
|
|
5
|
+
export { SettingsManager } from "./settings.js";
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Permission rule format examples:
|
|
3
|
-
* - "Read" - matches all Read tool calls
|
|
4
|
-
* - "Read(./.env)" - matches specific path
|
|
5
|
-
* - "Read(./.env.*)" - glob pattern
|
|
6
|
-
* - "Read(./secrets/**)" - recursive glob
|
|
7
|
-
* - "Bash(npm run lint)" - exact command prefix
|
|
8
|
-
* - "Bash(npm run:*)" - command prefix with wildcard
|
|
9
|
-
*
|
|
10
|
-
* Docs: https://code.claude.com/docs/en/iam#tool-specific-permission-rules
|
|
11
|
-
*/
|
|
12
|
-
export interface PermissionSettings {
|
|
13
|
-
defaultMode?: string;
|
|
14
|
-
}
|
|
15
|
-
export interface ClaudeCodeSettings {
|
|
16
|
-
permissions?: PermissionSettings;
|
|
17
|
-
env?: Record<string, string>;
|
|
18
|
-
model?: string;
|
|
19
|
-
effortLevel?: string;
|
|
20
|
-
availableModels?: string[];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Gets the enterprise settings path based on the current platform
|
|
24
|
-
*/
|
|
25
|
-
export declare function getManagedSettingsPath(): string;
|
|
1
|
+
import { type Settings } from "@anthropic-ai/claude-agent-sdk";
|
|
26
2
|
export interface SettingsManagerOptions {
|
|
27
3
|
onChange?: () => void;
|
|
28
4
|
logger?: {
|
|
@@ -31,23 +7,17 @@ export interface SettingsManagerOptions {
|
|
|
31
7
|
};
|
|
32
8
|
}
|
|
33
9
|
/**
|
|
34
|
-
* Manages Claude Code settings
|
|
10
|
+
* Manages Claude Code settings using the SDK's `resolveSettings` merge engine
|
|
11
|
+
* so the values we see match what `query()` would observe.
|
|
35
12
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* 4. Enterprise managed settings (platform-specific path)
|
|
41
|
-
*
|
|
42
|
-
* The manager watches all settings files for changes and automatically reloads.
|
|
13
|
+
* Watches the user/project/local/managed settings files for changes and
|
|
14
|
+
* re-resolves through the SDK on update. Escalating `permissions.defaultMode`
|
|
15
|
+
* values from repo-committed sources are filtered out via
|
|
16
|
+
* `filterEscalatingDefaultMode`, matching the CLI's trust policy.
|
|
43
17
|
*/
|
|
44
18
|
export declare class SettingsManager {
|
|
45
19
|
private cwd;
|
|
46
|
-
private
|
|
47
|
-
private projectSettings;
|
|
48
|
-
private localSettings;
|
|
49
|
-
private enterpriseSettings;
|
|
50
|
-
private mergedSettings;
|
|
20
|
+
private effective;
|
|
51
21
|
private watchers;
|
|
52
22
|
private onChange?;
|
|
53
23
|
private logger;
|
|
@@ -61,27 +31,15 @@ export declare class SettingsManager {
|
|
|
61
31
|
*/
|
|
62
32
|
initialize(): Promise<void>;
|
|
63
33
|
/**
|
|
64
|
-
*
|
|
65
|
-
|
|
66
|
-
private getUserSettingsPath;
|
|
67
|
-
/**
|
|
68
|
-
* Returns the path to the project settings file
|
|
34
|
+
* Paths the SDK reads when resolving settings for this cwd. Watching the
|
|
35
|
+
* containing directories means we pick up file creation as well as edits.
|
|
69
36
|
*/
|
|
70
|
-
private
|
|
37
|
+
private getWatchedPaths;
|
|
71
38
|
/**
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
private getLocalSettingsPath;
|
|
75
|
-
/**
|
|
76
|
-
* Loads settings from all sources
|
|
39
|
+
* Resolves the effective settings via the SDK and applies the CLI's trust
|
|
40
|
+
* filter for escalating `permissions.defaultMode` values.
|
|
77
41
|
*/
|
|
78
42
|
private loadAllSettings;
|
|
79
|
-
/**
|
|
80
|
-
* Merges all settings sources with proper precedence.
|
|
81
|
-
* For permissions, rules from all sources are combined.
|
|
82
|
-
* Deny rules always take precedence during permission checks.
|
|
83
|
-
*/
|
|
84
|
-
private mergeSettings;
|
|
85
43
|
/**
|
|
86
44
|
* Sets up file watchers for all settings files
|
|
87
45
|
*/
|
|
@@ -93,7 +51,7 @@ export declare class SettingsManager {
|
|
|
93
51
|
/**
|
|
94
52
|
* Returns the current merged settings
|
|
95
53
|
*/
|
|
96
|
-
getSettings():
|
|
54
|
+
getSettings(): Settings;
|
|
97
55
|
/**
|
|
98
56
|
* Returns the current working directory
|
|
99
57
|
*/
|
package/dist/settings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,gCAAgC,CAAC;AA0BxC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7E;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,MAAM,CAAqE;IACnF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,WAAW,CAA8B;gBAErC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB;IAMzD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBjC;;;OAGG;IACH,OAAO,CAAC,eAAe;IASvB;;;OAGG;YACW,eAAe;IAU7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,WAAW,IAAI,QAAQ;IAIvB;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxC;;OAEG;IACH,OAAO,IAAI,IAAI;CAehB"}
|
package/dist/settings.js
CHANGED
|
@@ -1,36 +1,24 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
// resolveSettings and filterEscalatingDefaultMode are marked @alpha in the
|
|
4
|
+
// SDK; API may shift in a future release.
|
|
5
|
+
import { filterEscalatingDefaultMode, resolveSettings, } from "@anthropic-ai/claude-agent-sdk";
|
|
3
6
|
import { CLAUDE_CONFIG_DIR } from "./acp-agent.js";
|
|
4
7
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const content = await fs.promises.readFile(filePath, "utf-8");
|
|
15
|
-
return JSON.parse(content);
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
19
|
-
return {};
|
|
20
|
-
}
|
|
21
|
-
logger?.error(`Failed to load settings from ${filePath}:`, error);
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Gets the enterprise settings path based on the current platform
|
|
8
|
+
* Permission rule format examples:
|
|
9
|
+
* - "Read" - matches all Read tool calls
|
|
10
|
+
* - "Read(./.env)" - matches specific path
|
|
11
|
+
* - "Read(./.env.*)" - glob pattern
|
|
12
|
+
* - "Read(./secrets/**)" - recursive glob
|
|
13
|
+
* - "Bash(npm run lint)" - exact command prefix
|
|
14
|
+
* - "Bash(npm run:*)" - command prefix with wildcard
|
|
15
|
+
*
|
|
16
|
+
* Docs: https://code.claude.com/docs/en/iam#tool-specific-permission-rules
|
|
27
17
|
*/
|
|
28
|
-
|
|
18
|
+
function getManagedSettingsPath() {
|
|
29
19
|
switch (process.platform) {
|
|
30
20
|
case "darwin":
|
|
31
21
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
32
|
-
case "linux":
|
|
33
|
-
return "/etc/claude-code/managed-settings.json";
|
|
34
22
|
case "win32":
|
|
35
23
|
return "C:\\Program Files\\ClaudeCode\\managed-settings.json";
|
|
36
24
|
default:
|
|
@@ -38,23 +26,17 @@ export function getManagedSettingsPath() {
|
|
|
38
26
|
}
|
|
39
27
|
}
|
|
40
28
|
/**
|
|
41
|
-
* Manages Claude Code settings
|
|
42
|
-
*
|
|
43
|
-
* Settings are loaded from (in order of increasing precedence):
|
|
44
|
-
* 1. User settings (~/.claude/settings.json)
|
|
45
|
-
* 2. Project settings (<cwd>/.claude/settings.json)
|
|
46
|
-
* 3. Local project settings (<cwd>/.claude/settings.local.json)
|
|
47
|
-
* 4. Enterprise managed settings (platform-specific path)
|
|
29
|
+
* Manages Claude Code settings using the SDK's `resolveSettings` merge engine
|
|
30
|
+
* so the values we see match what `query()` would observe.
|
|
48
31
|
*
|
|
49
|
-
*
|
|
32
|
+
* Watches the user/project/local/managed settings files for changes and
|
|
33
|
+
* re-resolves through the SDK on update. Escalating `permissions.defaultMode`
|
|
34
|
+
* values from repo-committed sources are filtered out via
|
|
35
|
+
* `filterEscalatingDefaultMode`, matching the CLI's trust policy.
|
|
50
36
|
*/
|
|
51
37
|
export class SettingsManager {
|
|
52
38
|
constructor(cwd, options) {
|
|
53
|
-
this.
|
|
54
|
-
this.projectSettings = {};
|
|
55
|
-
this.localSettings = {};
|
|
56
|
-
this.enterpriseSettings = {};
|
|
57
|
-
this.mergedSettings = {};
|
|
39
|
+
this.effective = {};
|
|
58
40
|
this.watchers = [];
|
|
59
41
|
this.initialized = false;
|
|
60
42
|
this.disposed = false;
|
|
@@ -85,92 +67,36 @@ export class SettingsManager {
|
|
|
85
67
|
return this.initPromise;
|
|
86
68
|
}
|
|
87
69
|
/**
|
|
88
|
-
*
|
|
89
|
-
|
|
90
|
-
getUserSettingsPath() {
|
|
91
|
-
return path.join(CLAUDE_CONFIG_DIR, "settings.json");
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Returns the path to the project settings file
|
|
95
|
-
*/
|
|
96
|
-
getProjectSettingsPath() {
|
|
97
|
-
return path.join(this.cwd, ".claude", "settings.json");
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Returns the path to the local project settings file
|
|
70
|
+
* Paths the SDK reads when resolving settings for this cwd. Watching the
|
|
71
|
+
* containing directories means we pick up file creation as well as edits.
|
|
101
72
|
*/
|
|
102
|
-
|
|
103
|
-
return
|
|
73
|
+
getWatchedPaths() {
|
|
74
|
+
return [
|
|
75
|
+
path.join(CLAUDE_CONFIG_DIR, "settings.json"),
|
|
76
|
+
path.join(this.cwd, ".claude", "settings.json"),
|
|
77
|
+
path.join(this.cwd, ".claude", "settings.local.json"),
|
|
78
|
+
getManagedSettingsPath(),
|
|
79
|
+
];
|
|
104
80
|
}
|
|
105
81
|
/**
|
|
106
|
-
*
|
|
82
|
+
* Resolves the effective settings via the SDK and applies the CLI's trust
|
|
83
|
+
* filter for escalating `permissions.defaultMode` values.
|
|
107
84
|
*/
|
|
108
85
|
async loadAllSettings() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.projectSettings = projectSettings;
|
|
117
|
-
this.localSettings = localSettings;
|
|
118
|
-
this.enterpriseSettings = enterpriseSettings;
|
|
119
|
-
this.mergeSettings();
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Merges all settings sources with proper precedence.
|
|
123
|
-
* For permissions, rules from all sources are combined.
|
|
124
|
-
* Deny rules always take precedence during permission checks.
|
|
125
|
-
*/
|
|
126
|
-
mergeSettings() {
|
|
127
|
-
const allSettings = [
|
|
128
|
-
this.userSettings,
|
|
129
|
-
this.projectSettings,
|
|
130
|
-
this.localSettings,
|
|
131
|
-
this.enterpriseSettings,
|
|
132
|
-
];
|
|
133
|
-
const merged = {};
|
|
134
|
-
for (const settings of allSettings) {
|
|
135
|
-
if (settings.env) {
|
|
136
|
-
merged.env = { ...merged.env, ...settings.env };
|
|
137
|
-
}
|
|
138
|
-
if (settings.model) {
|
|
139
|
-
merged.model = settings.model;
|
|
140
|
-
}
|
|
141
|
-
if (settings.effortLevel !== undefined) {
|
|
142
|
-
merged.effortLevel = settings.effortLevel;
|
|
143
|
-
}
|
|
144
|
-
if (settings.availableModels !== undefined) {
|
|
145
|
-
// Per Claude Code docs: "When `availableModels` is set at multiple
|
|
146
|
-
// levels, such as user settings and project settings, arrays are
|
|
147
|
-
// merged and deduplicated."
|
|
148
|
-
// https://code.claude.com/docs/en/model-config#merge-behavior
|
|
149
|
-
const combined = [...(merged.availableModels ?? []), ...settings.availableModels];
|
|
150
|
-
merged.availableModels = Array.from(new Set(combined));
|
|
151
|
-
}
|
|
152
|
-
if (settings.permissions?.defaultMode !== undefined) {
|
|
153
|
-
merged.permissions = {
|
|
154
|
-
...merged.permissions,
|
|
155
|
-
defaultMode: settings.permissions.defaultMode,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
86
|
+
try {
|
|
87
|
+
const resolved = await resolveSettings({ cwd: this.cwd });
|
|
88
|
+
this.effective = filterEscalatingDefaultMode(resolved);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
this.logger.error("Failed to resolve settings:", error);
|
|
92
|
+
this.effective = {};
|
|
158
93
|
}
|
|
159
|
-
this.mergedSettings = merged;
|
|
160
94
|
}
|
|
161
95
|
/**
|
|
162
96
|
* Sets up file watchers for all settings files
|
|
163
97
|
*/
|
|
164
98
|
setupWatchers() {
|
|
165
|
-
const
|
|
166
|
-
this.getUserSettingsPath(),
|
|
167
|
-
this.getProjectSettingsPath(),
|
|
168
|
-
this.getLocalSettingsPath(),
|
|
169
|
-
getManagedSettingsPath(),
|
|
170
|
-
];
|
|
171
|
-
for (const filePath of paths) {
|
|
172
|
-
if (!filePath)
|
|
173
|
-
continue;
|
|
99
|
+
for (const filePath of this.getWatchedPaths()) {
|
|
174
100
|
try {
|
|
175
101
|
const dir = path.dirname(filePath);
|
|
176
102
|
const filename = path.basename(filePath);
|
|
@@ -218,7 +144,7 @@ export class SettingsManager {
|
|
|
218
144
|
* Returns the current merged settings
|
|
219
145
|
*/
|
|
220
146
|
getSettings() {
|
|
221
|
-
return this.
|
|
147
|
+
return this.effective;
|
|
222
148
|
}
|
|
223
149
|
/**
|
|
224
150
|
* Returns the current working directory
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PlanEntry, ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk";
|
|
2
2
|
import { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
3
|
+
import { TaskCreateInput, TaskCreateOutput, TaskUpdateInput } from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
|
|
3
4
|
import { ToolResultBlockParam, WebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources";
|
|
4
5
|
import { BetaBashCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultBlockParam, BetaRequestMCPToolResultBlockParam, BetaTextEditorCodeExecutionToolResultBlockParam, BetaToolResultBlockParam, BetaToolSearchToolResultBlockParam, BetaWebFetchToolResultBlockParam, BetaWebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
5
6
|
import { Logger } from "./acp-agent.js";
|
|
@@ -43,6 +44,29 @@ export type ClaudePlanEntry = {
|
|
|
43
44
|
export declare function planEntries(input: {
|
|
44
45
|
todos: ClaudePlanEntry[];
|
|
45
46
|
} | undefined): PlanEntry[];
|
|
47
|
+
/**
|
|
48
|
+
* Per-session task list accumulated from Task* tool calls (TaskCreate /
|
|
49
|
+
* TaskUpdate). The headless/SDK session emits these as incremental tool
|
|
50
|
+
* calls keyed by task ID, replacing the snapshot-style TodoWrite tool.
|
|
51
|
+
* Iteration order is insertion order (Map semantics), matching the order
|
|
52
|
+
* tasks are created.
|
|
53
|
+
*/
|
|
54
|
+
export type TaskEntry = {
|
|
55
|
+
subject: string;
|
|
56
|
+
status: "pending" | "in_progress" | "completed";
|
|
57
|
+
activeForm?: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
};
|
|
60
|
+
export type TaskState = Map<string, TaskEntry>;
|
|
61
|
+
/**
|
|
62
|
+
* Best-effort parse of a TaskCreate tool_result content into the structured
|
|
63
|
+
* TaskCreateOutput. The SDK delivers tool outputs either as a string or as
|
|
64
|
+
* an array of TextBlockParam-like blocks containing JSON text; try both.
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseTaskCreateOutput(content: unknown): TaskCreateOutput | undefined;
|
|
67
|
+
export declare function applyTaskCreate(state: TaskState, input: TaskCreateInput | undefined, output: TaskCreateOutput | undefined): void;
|
|
68
|
+
export declare function applyTaskUpdate(state: TaskState, input: TaskUpdateInput | undefined): void;
|
|
69
|
+
export declare function taskStateToPlanEntries(state: TaskState): PlanEntry[];
|
|
46
70
|
export declare function markdownEscape(text: string): string;
|
|
47
71
|
/**
|
|
48
72
|
* Builds diff ToolUpdate content from the structured toolResponse provided by
|
|
@@ -61,5 +85,19 @@ export declare const registerHookCallback: (toolUseID: string, { onPostToolUseHo
|
|
|
61
85
|
export declare const createPostToolUseHook: (logger?: Logger, options?: {
|
|
62
86
|
onEnterPlanMode?: () => Promise<void>;
|
|
63
87
|
}) => HookCallback;
|
|
88
|
+
/**
|
|
89
|
+
* Hook callback for `TaskCreated` / `TaskCompleted` events. The SDK fires
|
|
90
|
+
* these for both user-facing TaskCreate tool calls and subagent task
|
|
91
|
+
* creation, giving us `task_id` + `task_subject` without having to parse
|
|
92
|
+
* tool_result payloads.
|
|
93
|
+
*
|
|
94
|
+
* Populating `taskState` from the hook means a later `TaskUpdate` (which
|
|
95
|
+
* typically only carries `taskId` + `status`) finds an existing entry with
|
|
96
|
+
* a real subject, instead of synthesizing a placeholder with empty content.
|
|
97
|
+
*/
|
|
98
|
+
export declare const createTaskHook: (options: {
|
|
99
|
+
taskState: TaskState;
|
|
100
|
+
onChange?: () => Promise<void>;
|
|
101
|
+
}) => HookCallback;
|
|
64
102
|
export {};
|
|
65
103
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
CHANGED
|
@@ -234,6 +234,36 @@ export function toolInfoFromToolUse(toolUse, supportsTerminalOutput = false, cwd
|
|
|
234
234
|
content: [],
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
|
+
case "TaskCreate": {
|
|
238
|
+
const input = toolUse.input;
|
|
239
|
+
return {
|
|
240
|
+
title: input?.subject ? `Create task: ${input.subject}` : "Create task",
|
|
241
|
+
kind: "think",
|
|
242
|
+
content: [],
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
case "TaskUpdate": {
|
|
246
|
+
const input = toolUse.input;
|
|
247
|
+
return {
|
|
248
|
+
title: input?.subject ? `Update task: ${input.subject}` : "Update task",
|
|
249
|
+
kind: "think",
|
|
250
|
+
content: [],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
case "TaskList": {
|
|
254
|
+
return {
|
|
255
|
+
title: "List tasks",
|
|
256
|
+
kind: "think",
|
|
257
|
+
content: [],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
case "TaskGet": {
|
|
261
|
+
return {
|
|
262
|
+
title: "Get task",
|
|
263
|
+
kind: "think",
|
|
264
|
+
content: [],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
237
267
|
case "ExitPlanMode": {
|
|
238
268
|
const planInput = toolUse.input;
|
|
239
269
|
return {
|
|
@@ -483,6 +513,82 @@ export function planEntries(input) {
|
|
|
483
513
|
priority: "medium",
|
|
484
514
|
}));
|
|
485
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Best-effort parse of a TaskCreate tool_result content into the structured
|
|
518
|
+
* TaskCreateOutput. The SDK delivers tool outputs either as a string or as
|
|
519
|
+
* an array of TextBlockParam-like blocks containing JSON text; try both.
|
|
520
|
+
*/
|
|
521
|
+
export function parseTaskCreateOutput(content) {
|
|
522
|
+
const tryParse = (text) => {
|
|
523
|
+
try {
|
|
524
|
+
const parsed = JSON.parse(text);
|
|
525
|
+
if (parsed &&
|
|
526
|
+
typeof parsed === "object" &&
|
|
527
|
+
parsed.task &&
|
|
528
|
+
typeof parsed.task.id === "string") {
|
|
529
|
+
return parsed;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
// ignore
|
|
534
|
+
}
|
|
535
|
+
return undefined;
|
|
536
|
+
};
|
|
537
|
+
if (typeof content === "string") {
|
|
538
|
+
return tryParse(content);
|
|
539
|
+
}
|
|
540
|
+
if (Array.isArray(content)) {
|
|
541
|
+
for (const block of content) {
|
|
542
|
+
if (block && typeof block === "object" && "type" in block && block.type === "text") {
|
|
543
|
+
const text = block.text;
|
|
544
|
+
if (typeof text === "string") {
|
|
545
|
+
const parsed = tryParse(text);
|
|
546
|
+
if (parsed)
|
|
547
|
+
return parsed;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
554
|
+
export function applyTaskCreate(state, input, output) {
|
|
555
|
+
const taskId = output?.task?.id;
|
|
556
|
+
if (!taskId || !input)
|
|
557
|
+
return;
|
|
558
|
+
state.set(taskId, {
|
|
559
|
+
subject: input.subject,
|
|
560
|
+
status: "pending",
|
|
561
|
+
activeForm: input.activeForm,
|
|
562
|
+
description: input.description,
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
export function applyTaskUpdate(state, input) {
|
|
566
|
+
if (!input?.taskId)
|
|
567
|
+
return;
|
|
568
|
+
if (input.status === "deleted") {
|
|
569
|
+
state.delete(input.taskId);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
const existing = state.get(input.taskId);
|
|
573
|
+
// Without a subject from either the existing entry or the update payload,
|
|
574
|
+
// we'd produce a plan entry with empty `content` — drop the update.
|
|
575
|
+
const subject = input.subject ?? existing?.subject;
|
|
576
|
+
if (!subject)
|
|
577
|
+
return;
|
|
578
|
+
state.set(input.taskId, {
|
|
579
|
+
subject,
|
|
580
|
+
status: input.status ?? existing?.status ?? "pending",
|
|
581
|
+
activeForm: input.activeForm ?? existing?.activeForm,
|
|
582
|
+
description: input.description ?? existing?.description,
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
export function taskStateToPlanEntries(state) {
|
|
586
|
+
return Array.from(state.values()).map((task) => ({
|
|
587
|
+
content: task.subject,
|
|
588
|
+
status: task.status,
|
|
589
|
+
priority: "medium",
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
486
592
|
export function markdownEscape(text) {
|
|
487
593
|
let escape = "```";
|
|
488
594
|
for (const [m] of text.matchAll(/^```+/gm)) {
|
|
@@ -568,3 +674,40 @@ export const createPostToolUseHook = (logger = console, options) => async (input
|
|
|
568
674
|
}
|
|
569
675
|
return { continue: true };
|
|
570
676
|
};
|
|
677
|
+
/**
|
|
678
|
+
* Hook callback for `TaskCreated` / `TaskCompleted` events. The SDK fires
|
|
679
|
+
* these for both user-facing TaskCreate tool calls and subagent task
|
|
680
|
+
* creation, giving us `task_id` + `task_subject` without having to parse
|
|
681
|
+
* tool_result payloads.
|
|
682
|
+
*
|
|
683
|
+
* Populating `taskState` from the hook means a later `TaskUpdate` (which
|
|
684
|
+
* typically only carries `taskId` + `status`) finds an existing entry with
|
|
685
|
+
* a real subject, instead of synthesizing a placeholder with empty content.
|
|
686
|
+
*/
|
|
687
|
+
export const createTaskHook = (options) => async (input) => {
|
|
688
|
+
const taskId = "task_id" in input && typeof input.task_id === "string" ? input.task_id : undefined;
|
|
689
|
+
if (!taskId)
|
|
690
|
+
return { continue: true };
|
|
691
|
+
if (input.hook_event_name === "TaskCreated") {
|
|
692
|
+
if (!input.task_subject)
|
|
693
|
+
return { continue: true };
|
|
694
|
+
if (options.taskState.has(taskId))
|
|
695
|
+
return { continue: true };
|
|
696
|
+
options.taskState.set(taskId, {
|
|
697
|
+
subject: input.task_subject,
|
|
698
|
+
status: "pending",
|
|
699
|
+
description: input.task_description,
|
|
700
|
+
});
|
|
701
|
+
if (options.onChange)
|
|
702
|
+
await options.onChange();
|
|
703
|
+
}
|
|
704
|
+
else if (input.hook_event_name === "TaskCompleted") {
|
|
705
|
+
const existing = options.taskState.get(taskId);
|
|
706
|
+
if (!existing || existing.status === "completed")
|
|
707
|
+
return { continue: true };
|
|
708
|
+
options.taskState.set(taskId, { ...existing, status: "completed" });
|
|
709
|
+
if (options.onChange)
|
|
710
|
+
await options.onChange();
|
|
711
|
+
}
|
|
712
|
+
return { continue: true };
|
|
713
|
+
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Readable, Writable } from "node:stream";
|
|
2
2
|
import { WritableStream, ReadableStream } from "node:stream/web";
|
|
3
3
|
import { Logger } from "./acp-agent.js";
|
|
4
|
-
import { ClaudeCodeSettings } from "./settings.js";
|
|
5
4
|
export declare class Pushable<T> implements AsyncIterable<T> {
|
|
6
5
|
private queue;
|
|
7
6
|
private resolvers;
|
|
@@ -14,6 +13,4 @@ export declare function nodeToWebWritable(nodeStream: Writable): WritableStream<
|
|
|
14
13
|
export declare function nodeToWebReadable(nodeStream: Readable): ReadableStream<Uint8Array>;
|
|
15
14
|
export declare function unreachable(value: never, logger?: Logger): void;
|
|
16
15
|
export declare function sleep(time: number): Promise<void>;
|
|
17
|
-
export declare function loadManagedSettings(): ClaudeCodeSettings | null;
|
|
18
|
-
export declare function applyEnvironmentSettings(settings: ClaudeCodeSettings): void;
|
|
19
16
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGxC,qBAAa,QAAQ,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,IAAI,CAAS;IAErB,IAAI,CAAC,IAAI,EAAE,CAAC;IASZ,GAAG;IAQH,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC;CAgB3C;AAGD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAclF;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAUlF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,GAAE,MAAgB,QAQjE;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjD"}
|
package/dist/utils.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// A pushable async iterable: allows you to push items and consume them with for-await.
|
|
2
2
|
import { WritableStream, ReadableStream } from "node:stream/web";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
import { getManagedSettingsPath } from "./settings.js";
|
|
5
3
|
// Useful for bridging push-based and async-iterator-based code.
|
|
6
4
|
export class Pushable {
|
|
7
5
|
constructor() {
|
|
@@ -83,18 +81,3 @@ export function unreachable(value, logger = console) {
|
|
|
83
81
|
export function sleep(time) {
|
|
84
82
|
return new Promise((resolve) => setTimeout(resolve, time));
|
|
85
83
|
}
|
|
86
|
-
export function loadManagedSettings() {
|
|
87
|
-
try {
|
|
88
|
-
return JSON.parse(readFileSync(getManagedSettingsPath(), "utf8"));
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export function applyEnvironmentSettings(settings) {
|
|
95
|
-
if (settings.env) {
|
|
96
|
-
for (const [key, value] of Object.entries(settings.env)) {
|
|
97
|
-
process.env[key] = value;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.35.0",
|
|
7
7
|
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
|
8
8
|
"main": "dist/lib.js",
|
|
9
9
|
"types": "dist/lib.d.ts",
|
|
@@ -60,22 +60,22 @@
|
|
|
60
60
|
"author": "Zed Industries",
|
|
61
61
|
"license": "Apache-2.0",
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@agentclientprotocol/sdk": "0.21.
|
|
64
|
-
"@anthropic-ai/claude-agent-sdk": "0.
|
|
63
|
+
"@agentclientprotocol/sdk": "0.21.1",
|
|
64
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.143",
|
|
65
65
|
"zod": "^3.25.0 || ^4.0.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@anthropic-ai/sdk": "0.
|
|
68
|
+
"@anthropic-ai/sdk": "0.96.0",
|
|
69
69
|
"@eslint/js": "10.0.1",
|
|
70
|
-
"@types/node": "25.
|
|
71
|
-
"@typescript-eslint/eslint-plugin": "8.59.
|
|
72
|
-
"@typescript-eslint/parser": "8.59.
|
|
73
|
-
"eslint": "10.
|
|
70
|
+
"@types/node": "25.8.0",
|
|
71
|
+
"@typescript-eslint/eslint-plugin": "8.59.3",
|
|
72
|
+
"@typescript-eslint/parser": "8.59.3",
|
|
73
|
+
"eslint": "10.4.0",
|
|
74
74
|
"eslint-config-prettier": "10.1.8",
|
|
75
75
|
"globals": "17.6.0",
|
|
76
76
|
"prettier": "3.8.3",
|
|
77
77
|
"ts-node": "10.9.2",
|
|
78
78
|
"typescript": "6.0.3",
|
|
79
|
-
"vitest": "4.1.
|
|
79
|
+
"vitest": "4.1.6"
|
|
80
80
|
}
|
|
81
81
|
}
|