@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.
@@ -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;
@@ -1 +1 @@
1
- {"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"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"}
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 !== "TodoWrite") {
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
- // Load managed settings and apply environment variables
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
- const managedSettings = loadManagedSettings();
37
- if (managedSettings) {
38
- applyEnvironmentSettings(managedSettings);
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 { loadManagedSettings, applyEnvironmentSettings, nodeToWebReadable, nodeToWebWritable, Pushable, unreachable, } from "./utils.js";
2
+ export { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
3
3
  export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
4
- export { SettingsManager, type ClaudeCodeSettings, type SettingsManagerOptions, } from "./settings.js";
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,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AAGvB,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
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 { loadManagedSettings, applyEnvironmentSettings, nodeToWebReadable, nodeToWebWritable, Pushable, unreachable, } from "./utils.js";
3
+ export { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
4
4
  export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
5
- export { SettingsManager, } from "./settings.js";
5
+ export { SettingsManager } from "./settings.js";
@@ -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 from multiple sources with proper precedence.
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
- * Settings are loaded from (in order of increasing precedence):
37
- * 1. User settings (~/.claude/settings.json)
38
- * 2. Project settings (<cwd>/.claude/settings.json)
39
- * 3. Local project settings (<cwd>/.claude/settings.local.json)
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 userSettings;
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
- * Returns the path to the user settings file
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 getProjectSettingsPath;
37
+ private getWatchedPaths;
71
38
  /**
72
- * Returns the path to the local project settings file
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(): ClaudeCodeSettings;
54
+ getSettings(): Settings;
97
55
  /**
98
56
  * Returns the current working directory
99
57
  */
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AA2BD;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAW/C;AAED,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;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,kBAAkB,CAA0B;IACpD,OAAO,CAAC,cAAc,CAA0B;IAChD,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;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAI9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;YACW,eAAe;IAgB7B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IA2CrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,WAAW,IAAI,kBAAkB;IAIjC;;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"}
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
- * Reads and parses a JSON settings file, returning an empty object if not found or invalid.
6
- * Silently ignores missing files (ENOENT) but logs warnings for other errors
7
- * (malformed JSON, permission errors, etc.) to aid debugging.
8
- */
9
- async function loadSettingsFile(filePath, logger) {
10
- if (!filePath) {
11
- return {};
12
- }
13
- try {
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
- export function getManagedSettingsPath() {
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 from multiple sources with proper precedence.
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
- * The manager watches all settings files for changes and automatically reloads.
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.userSettings = {};
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
- * Returns the path to the user settings file
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
- getLocalSettingsPath() {
103
- return path.join(this.cwd, ".claude", "settings.local.json");
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
- * Loads settings from all sources
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
- const [userSettings, projectSettings, localSettings, enterpriseSettings] = await Promise.all([
110
- loadSettingsFile(this.getUserSettingsPath(), this.logger),
111
- loadSettingsFile(this.getProjectSettingsPath(), this.logger),
112
- loadSettingsFile(this.getLocalSettingsPath(), this.logger),
113
- loadSettingsFile(getManagedSettingsPath(), this.logger),
114
- ]);
115
- this.userSettings = userSettings;
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 paths = [
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.mergedSettings;
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
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
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
@@ -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;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAA0B,MAAM,eAAe,CAAC;AAG3E,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;AAED,wBAAgB,mBAAmB,IAAI,kBAAkB,GAAG,IAAI,CAM/D;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAM3E"}
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.34.1",
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.0",
64
- "@anthropic-ai/claude-agent-sdk": "0.2.132",
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.89.0",
68
+ "@anthropic-ai/sdk": "0.96.0",
69
69
  "@eslint/js": "10.0.1",
70
- "@types/node": "25.6.0",
71
- "@typescript-eslint/eslint-plugin": "8.59.2",
72
- "@typescript-eslint/parser": "8.59.2",
73
- "eslint": "10.3.0",
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.5"
79
+ "vitest": "4.1.6"
80
80
  }
81
81
  }