@agentclientprotocol/claude-agent-acp 0.30.0 → 0.31.1

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.
@@ -1,5 +1,5 @@
1
1
  import { Agent, AgentSideConnection, AuthenticateRequest, CancelNotification, ClientCapabilities, ForkSessionRequest, ForkSessionResponse, InitializeRequest, InitializeResponse, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, ReadTextFileRequest, ReadTextFileResponse, ResumeSessionRequest, ResumeSessionResponse, SessionConfigOption, SessionModelState, SessionModeState, SessionNotification, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, SetSessionModeResponse, CloseSessionRequest, CloseSessionResponse, TerminalHandle, TerminalOutputResponse, WriteTextFileRequest, WriteTextFileResponse } from "@agentclientprotocol/sdk";
2
- import { CanUseTool, Options, PermissionMode, Query, SDKPartialAssistantMessage, SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ import { CanUseTool, ModelInfo, Options, PermissionMode, PermissionUpdate, Query, SDKPartialAssistantMessage, SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
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";
@@ -30,6 +30,7 @@ type Session = {
30
30
  accumulatedUsage: AccumulatedUsage;
31
31
  modes: SessionModeState;
32
32
  models: SessionModelState;
33
+ modelInfos: ModelInfo[];
33
34
  configOptions: SessionConfigOption[];
34
35
  promptRunning: boolean;
35
36
  pendingMessages: Map<string, {
@@ -135,7 +136,22 @@ export type ToolUseCache = {
135
136
  };
136
137
  };
137
138
  export declare function claudeCliPath(): Promise<string>;
139
+ /**
140
+ * Return user-message content with local-command marker tags removed, or
141
+ * `null` if nothing meaningful remains (caller should skip the message).
142
+ * Preserves real prose that's mixed in alongside the markers — e.g. a
143
+ * message like `<command-name>…</command-name>hi` becomes `hi`.
144
+ */
145
+ export declare function stripLocalCommandMetadata(content: unknown): unknown | null;
146
+ export declare function isLocalCommandMetadata(content: unknown): boolean;
138
147
  export declare function resolvePermissionMode(defaultMode?: unknown): PermissionMode;
148
+ /**
149
+ * Builds the label for the "Always Allow" permission option so the user can see
150
+ * the exact scope they are committing to. Uses the SDK-provided suggestions
151
+ * when available (e.g. `Bash(npm test:*)`) and falls back to naming the whole
152
+ * tool so "Always Allow" is never a blank check without disclosure.
153
+ */
154
+ export declare function describeAlwaysAllow(suggestions: PermissionUpdate[] | undefined, toolName: string): string;
139
155
  export declare class ClaudeAcpAgent implements Agent {
140
156
  sessions: {
141
157
  [key: string]: Session;
@@ -152,7 +168,7 @@ export declare class ClaudeAcpAgent implements Agent {
152
168
  initialize(request: InitializeRequest): Promise<InitializeResponse>;
153
169
  newSession(params: NewSessionRequest): Promise<NewSessionResponse>;
154
170
  unstable_forkSession(params: ForkSessionRequest): Promise<ForkSessionResponse>;
155
- unstable_resumeSession(params: ResumeSessionRequest): Promise<ResumeSessionResponse>;
171
+ resumeSession(params: ResumeSessionRequest): Promise<ResumeSessionResponse>;
156
172
  loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse>;
157
173
  listSessions(params: ListSessionsRequest): Promise<ListSessionsResponse>;
158
174
  authenticate(_params: AuthenticateRequest): Promise<void>;
@@ -163,7 +179,7 @@ export declare class ClaudeAcpAgent implements Agent {
163
179
  private teardownSession;
164
180
  /** Tear down all active sessions. Called when the ACP connection closes. */
165
181
  dispose(): Promise<void>;
166
- unstable_closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse>;
182
+ closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse>;
167
183
  unstable_setSessionModel(params: SetSessionModelRequest): Promise<SetSessionModelResponse | void>;
168
184
  setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse>;
169
185
  setSessionConfigOption(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
@@ -174,7 +190,7 @@ export declare class ClaudeAcpAgent implements Agent {
174
190
  canUseTool(sessionId: string): CanUseTool;
175
191
  private sendAvailableCommandsUpdate;
176
192
  private updateConfigOption;
177
- private syncSessionConfigState;
193
+ private applyConfigOptionValue;
178
194
  private getOrCreateSession;
179
195
  private createSession;
180
196
  }
@@ -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
@@ -45,11 +45,21 @@ export async function claudeCliPath() {
45
45
  const { createRequire } = await import("node:module");
46
46
  const req = createRequire(import.meta.resolve("@anthropic-ai/claude-agent-sdk"));
47
47
  const ext = process.platform === "win32" ? ".exe" : "";
48
+ // On linux, both glibc and musl variants may be installed side-by-side
49
+ // (e.g. bunx hydrates every optional dep), so picking one by trial is
50
+ // unreliable: the wrong binary segfaults at runtime instead of failing to
51
+ // spawn. Detect the runtime libc and prefer the matching variant, falling
52
+ // back to the other only if the preferred one isn't installed.
48
53
  const candidates = process.platform === "linux"
49
- ? [
50
- `@anthropic-ai/claude-agent-sdk-linux-${process.arch}-musl/claude${ext}`,
51
- `@anthropic-ai/claude-agent-sdk-linux-${process.arch}/claude${ext}`,
52
- ]
54
+ ? isMuslLibc()
55
+ ? [
56
+ `@anthropic-ai/claude-agent-sdk-linux-${process.arch}-musl/claude${ext}`,
57
+ `@anthropic-ai/claude-agent-sdk-linux-${process.arch}/claude${ext}`,
58
+ ]
59
+ : [
60
+ `@anthropic-ai/claude-agent-sdk-linux-${process.arch}/claude${ext}`,
61
+ `@anthropic-ai/claude-agent-sdk-linux-${process.arch}-musl/claude${ext}`,
62
+ ]
53
63
  : [`@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}/claude${ext}`];
54
64
  for (const candidate of candidates) {
55
65
  try {
@@ -62,6 +72,12 @@ export async function claudeCliPath() {
62
72
  throw new Error(`Claude native binary not found for ${process.platform}-${process.arch}. ` +
63
73
  `Reinstall @anthropic-ai/claude-agent-sdk without --omit=optional, or set CLAUDE_CODE_EXECUTABLE.`);
64
74
  }
75
+ function isMuslLibc() {
76
+ // process.report.getReport().header.glibcVersionRuntime is populated when
77
+ // Node is dynamically linked against glibc, and absent on musl.
78
+ const report = process.report?.getReport();
79
+ return !report?.header?.glibcVersionRuntime;
80
+ }
65
81
  function shouldHideClaudeAuth() {
66
82
  return process.argv.includes("--hide-claude-auth");
67
83
  }
@@ -71,6 +87,52 @@ const ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
71
87
  // Slash commands that the SDK handles locally without replaying the user
72
88
  // message and without invoking the model.
73
89
  const LOCAL_ONLY_COMMANDS = new Set(["/context", "/heapdump", "/extra-usage"]);
90
+ // The Claude SDK persists local slash command invocations (e.g. `/model`) and
91
+ // their output as user messages in the session transcript, wrapping the
92
+ // payload in these XML-like markers that the CLI uses for its own display.
93
+ // The live prompt loop drops them; replay must strip them too or they leak
94
+ // into the UI on session/load.
95
+ const LOCAL_COMMAND_TAG_PATTERN = /<(command-name|command-message|command-args|local-command-stdout|local-command-stderr)>[\s\S]*?<\/\1>/g;
96
+ function stripMarkerTags(text) {
97
+ return text.replace(LOCAL_COMMAND_TAG_PATTERN, "");
98
+ }
99
+ /**
100
+ * Return user-message content with local-command marker tags removed, or
101
+ * `null` if nothing meaningful remains (caller should skip the message).
102
+ * Preserves real prose that's mixed in alongside the markers — e.g. a
103
+ * message like `<command-name>…</command-name>hi` becomes `hi`.
104
+ */
105
+ export function stripLocalCommandMetadata(content) {
106
+ if (typeof content === "string") {
107
+ const stripped = stripMarkerTags(content);
108
+ return stripped.trim() === "" ? null : stripped;
109
+ }
110
+ if (!Array.isArray(content))
111
+ return content;
112
+ const kept = [];
113
+ for (const block of content) {
114
+ if (block &&
115
+ typeof block === "object" &&
116
+ "type" in block &&
117
+ block.type === "text" &&
118
+ "text" in block &&
119
+ typeof block.text === "string") {
120
+ const stripped = stripMarkerTags(block.text);
121
+ if (stripped.trim() === "")
122
+ continue;
123
+ kept.push({ ...block, text: stripped });
124
+ }
125
+ else {
126
+ kept.push(block);
127
+ }
128
+ }
129
+ if (kept.length === 0)
130
+ return null;
131
+ return kept;
132
+ }
133
+ export function isLocalCommandMetadata(content) {
134
+ return stripLocalCommandMetadata(content) === null;
135
+ }
74
136
  const PERMISSION_MODE_ALIASES = {
75
137
  auto: "auto",
76
138
  default: "default",
@@ -100,6 +162,40 @@ export function resolvePermissionMode(defaultMode) {
100
162
  }
101
163
  return mapped;
102
164
  }
165
+ /**
166
+ * Builds the label for the "Always Allow" permission option so the user can see
167
+ * the exact scope they are committing to. Uses the SDK-provided suggestions
168
+ * when available (e.g. `Bash(npm test:*)`) and falls back to naming the whole
169
+ * tool so "Always Allow" is never a blank check without disclosure.
170
+ */
171
+ export function describeAlwaysAllow(suggestions, toolName) {
172
+ if (!suggestions || suggestions.length === 0) {
173
+ return `Always Allow all ${toolName}`;
174
+ }
175
+ const ruleLabels = [];
176
+ const directories = [];
177
+ for (const update of suggestions) {
178
+ if (update.type === "addRules" && update.behavior === "allow") {
179
+ for (const rule of update.rules) {
180
+ ruleLabels.push(rule.ruleContent ? `${rule.toolName}(${rule.ruleContent})` : `all ${rule.toolName}`);
181
+ }
182
+ }
183
+ else if (update.type === "addDirectories") {
184
+ directories.push(...update.directories);
185
+ }
186
+ }
187
+ const parts = [];
188
+ if (ruleLabels.length > 0) {
189
+ parts.push(ruleLabels.join(", "));
190
+ }
191
+ if (directories.length > 0) {
192
+ parts.push(`access to ${directories.join(", ")}`);
193
+ }
194
+ if (parts.length === 0) {
195
+ return `Always Allow all ${toolName}`;
196
+ }
197
+ return `Always Allow ${parts.join(" and ")}`;
198
+ }
103
199
  // Implement the ACP Agent interface
104
200
  export class ClaudeAcpAgent {
105
201
  constructor(client, logger) {
@@ -254,7 +350,7 @@ export class ClaudeAcpAgent {
254
350
  }, 0);
255
351
  return response;
256
352
  }
257
- async unstable_resumeSession(params) {
353
+ async resumeSession(params) {
258
354
  const result = await this.getOrCreateSession(params);
259
355
  // Needs to happen after we return the session
260
356
  setTimeout(() => {
@@ -310,6 +406,13 @@ export class ClaudeAcpAgent {
310
406
  let lastAssistantTotalUsage = null;
311
407
  let lastAssistantUsage = null;
312
408
  let lastAssistantModel = null;
409
+ // When the Claude SDK classifies a turn as failed (e.g. rate limit, auth
410
+ // problem, billing), it sets a categorical `error` field on the
411
+ // `SDKAssistantMessage` that precedes the final `result` message. We
412
+ // capture it here so the subsequent `RequestError.internalError` can
413
+ // forward it to clients as structured `data`, sparing them from
414
+ // pattern-matching on the human-readable message text.
415
+ let lastAssistantError;
313
416
  const userMessage = promptToClaude(params);
314
417
  const promptUuid = randomUUID();
315
418
  userMessage.uuid = promptUuid;
@@ -480,7 +583,7 @@ export class ClaudeAcpAgent {
480
583
  break;
481
584
  }
482
585
  if (message.is_error) {
483
- throw RequestError.internalError(undefined, message.result);
586
+ throw RequestError.internalError(errorKindData(lastAssistantError), message.result);
484
587
  }
485
588
  // For local-only commands (no model invocation), the result
486
589
  // text is the command output — forward it to the client.
@@ -497,7 +600,7 @@ export class ClaudeAcpAgent {
497
600
  break;
498
601
  }
499
602
  if (message.is_error) {
500
- throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
603
+ throw RequestError.internalError(errorKindData(lastAssistantError), message.errors.join(", ") || message.subtype);
501
604
  }
502
605
  stopReason = "end_turn";
503
606
  break;
@@ -506,7 +609,7 @@ export class ClaudeAcpAgent {
506
609
  case "error_max_turns":
507
610
  case "error_max_structured_output_retries":
508
611
  if (message.is_error) {
509
- throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
612
+ throw RequestError.internalError(errorKindData(lastAssistantError), message.errors.join(", ") || message.subtype);
510
613
  }
511
614
  stopReason = "max_turn_requests";
512
615
  break;
@@ -606,6 +709,9 @@ export class ClaudeAcpAgent {
606
709
  if (message.message.model && message.message.model !== "<synthetic>") {
607
710
  lastAssistantModel = message.message.model;
608
711
  }
712
+ if (message.error) {
713
+ lastAssistantError = message.error;
714
+ }
609
715
  }
610
716
  // Slash commands like /compact can generate invalid output... doesn't match
611
717
  // their own docs: https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-slash-commands#%2Fcompact-compact-conversation-history
@@ -724,7 +830,7 @@ export class ClaudeAcpAgent {
724
830
  async dispose() {
725
831
  await Promise.all(Object.keys(this.sessions).map((id) => this.teardownSession(id)));
726
832
  }
727
- async unstable_closeSession(params) {
833
+ async closeSession(params) {
728
834
  if (!this.sessions[params.sessionId]) {
729
835
  throw new Error("Session not found");
730
836
  }
@@ -732,11 +838,17 @@ export class ClaudeAcpAgent {
732
838
  return {};
733
839
  }
734
840
  async unstable_setSessionModel(params) {
735
- if (!this.sessions[params.sessionId]) {
841
+ const session = this.sessions[params.sessionId];
842
+ if (!session) {
736
843
  throw new Error("Session not found");
737
844
  }
738
- await this.sessions[params.sessionId].query.setModel(params.modelId);
739
- await this.updateConfigOption(params.sessionId, "model", params.modelId);
845
+ // Resolve aliases (e.g. "opus", "opus[1m]") to canonical model IDs so
846
+ // downstream lookups in modelInfos succeed and the effort option isn't
847
+ // silently dropped.
848
+ const resolved = resolveModelPreference(session.modelInfos, params.modelId);
849
+ const modelId = resolved?.value ?? params.modelId;
850
+ await session.query.setModel(modelId);
851
+ await this.updateConfigOption(params.sessionId, "model", modelId);
740
852
  }
741
853
  async setSessionMode(params) {
742
854
  if (!this.sessions[params.sessionId]) {
@@ -795,10 +907,10 @@ export class ClaudeAcpAgent {
795
907
  else if (params.configId === "model") {
796
908
  await this.sessions[params.sessionId].query.setModel(resolvedValue);
797
909
  }
798
- this.syncSessionConfigState(session, params.configId, params.value);
799
- session.configOptions = session.configOptions.map((o) => o.id === params.configId && typeof o.currentValue === "string"
800
- ? { ...o, currentValue: resolvedValue }
801
- : o);
910
+ // Effort SDK sync is handled inside applyConfigOptionValue so that direct
911
+ // effort changes and effort changes induced by a model switch go through
912
+ // the same path.
913
+ await this.applyConfigOptionValue(session, params.configId, resolvedValue);
802
914
  return { configOptions: session.configOptions };
803
915
  }
804
916
  async applySessionMode(sessionId, modeId) {
@@ -833,9 +945,17 @@ export class ClaudeAcpAgent {
833
945
  const toolUseCache = {};
834
946
  const messages = await getSessionMessages(sessionId);
835
947
  for (const message of messages) {
948
+ // @ts-expect-error - untyped in SDK but we handle all of these
949
+ let content = message.message.content;
950
+ // @ts-expect-error - untyped in SDK but we handle all of these
951
+ if (message.message.role === "user") {
952
+ content = stripLocalCommandMetadata(content);
953
+ if (content === null)
954
+ continue;
955
+ }
836
956
  for (const notification of toAcpNotifications(
837
957
  // @ts-expect-error - untyped in SDK but we handle all of these
838
- message.message.content,
958
+ content,
839
959
  // @ts-expect-error - untyped in SDK but we handle all of these
840
960
  message.message.role, sessionId, toolUseCache, this.client, this.logger, {
841
961
  registerHooks: false,
@@ -856,6 +976,7 @@ export class ClaudeAcpAgent {
856
976
  }
857
977
  canUseTool(sessionId) {
858
978
  return async (toolName, toolInput, { signal, suggestions, toolUseID }) => {
979
+ const alwaysAllowLabel = describeAlwaysAllow(suggestions, toolName);
859
980
  const supportsTerminalOutput = this.clientCapabilities?._meta?.["terminal_output"] === true;
860
981
  const session = this.sessions[sessionId];
861
982
  if (!session) {
@@ -935,7 +1056,7 @@ export class ClaudeAcpAgent {
935
1056
  options: [
936
1057
  {
937
1058
  kind: "allow_always",
938
- name: "Always Allow",
1059
+ name: alwaysAllowLabel,
939
1060
  optionId: "allow_always",
940
1061
  },
941
1062
  { kind: "allow_once", name: "Allow", optionId: "allow" },
@@ -998,8 +1119,7 @@ export class ClaudeAcpAgent {
998
1119
  const session = this.sessions[sessionId];
999
1120
  if (!session)
1000
1121
  return;
1001
- this.syncSessionConfigState(session, configId, value);
1002
- session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
1122
+ await this.applyConfigOptionValue(session, configId, value);
1003
1123
  await this.client.sessionUpdate({
1004
1124
  sessionId,
1005
1125
  update: {
@@ -1008,7 +1128,8 @@ export class ClaudeAcpAgent {
1008
1128
  },
1009
1129
  });
1010
1130
  }
1011
- syncSessionConfigState(session, configId, value) {
1131
+ async applyConfigOptionValue(session, configId, value) {
1132
+ // Sync top-level session state
1012
1133
  if (configId === "mode") {
1013
1134
  session.modes = { ...session.modes, currentModeId: value };
1014
1135
  }
@@ -1022,6 +1143,29 @@ export class ClaudeAcpAgent {
1022
1143
  }
1023
1144
  session.models = { ...session.models, currentModelId: value };
1024
1145
  }
1146
+ // Update configOptions
1147
+ if (configId === "model") {
1148
+ // Rebuild config options since effort levels depend on the selected model
1149
+ const effortOpt = session.configOptions.find((o) => o.id === "effort");
1150
+ const currentEffort = typeof effortOpt?.currentValue === "string" ? effortOpt.currentValue : undefined;
1151
+ session.configOptions = buildConfigOptions(session.modes, session.models, session.modelInfos, currentEffort);
1152
+ // Sync effort with the SDK if it changed after the model switch
1153
+ const newEffortOpt = session.configOptions.find((o) => o.id === "effort");
1154
+ const newEffort = typeof newEffortOpt?.currentValue === "string" ? newEffortOpt.currentValue : undefined;
1155
+ if (newEffort !== currentEffort) {
1156
+ await session.query.applyFlagSettings({
1157
+ effortLevel: newEffort,
1158
+ });
1159
+ }
1160
+ }
1161
+ else {
1162
+ session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
1163
+ if (configId === "effort") {
1164
+ await session.query.applyFlagSettings({
1165
+ effortLevel: value,
1166
+ });
1167
+ }
1168
+ }
1025
1169
  }
1026
1170
  async getOrCreateSession(params) {
1027
1171
  const existingSession = this.sessions[params.sessionId];
@@ -1105,9 +1249,15 @@ export class ClaudeAcpAgent {
1105
1249
  systemPrompt = customPrompt;
1106
1250
  }
1107
1251
  else if (typeof customPrompt === "object" &&
1108
- "append" in customPrompt &&
1109
- typeof customPrompt.append === "string") {
1110
- systemPrompt.append = customPrompt.append;
1252
+ customPrompt !== null &&
1253
+ !Array.isArray(customPrompt)) {
1254
+ // Forward all preset options (append, excludeDynamicSections, and
1255
+ // anything the SDK adds later) while locking type/preset.
1256
+ systemPrompt = {
1257
+ ...customPrompt,
1258
+ type: "preset",
1259
+ preset: "claude_code",
1260
+ };
1111
1261
  }
1112
1262
  }
1113
1263
  const permissionMode = resolvePermissionMode(settingsManager.getSettings().permissions?.defaultMode);
@@ -1118,6 +1268,8 @@ export class ClaudeAcpAgent {
1118
1268
  const maxThinkingTokens = process.env.MAX_THINKING_TOKENS
1119
1269
  ? parseInt(process.env.MAX_THINKING_TOKENS, 10)
1120
1270
  : undefined;
1271
+ // Parse model configuration from environment (e.g. Bedrock model overrides)
1272
+ const modelConfig = parseModelConfig(process.env.CLAUDE_MODEL_CONFIG);
1121
1273
  // Disable this for now, not a great way to expose this over ACP at the moment (in progress work so we can revisit)
1122
1274
  const disallowedTools = ["AskUserQuestion"];
1123
1275
  // Resolve which built-in tools to expose.
@@ -1132,6 +1284,17 @@ export class ClaudeAcpAgent {
1132
1284
  settingSources: ["user", "project", "local"],
1133
1285
  ...(maxThinkingTokens !== undefined && { maxThinkingTokens }),
1134
1286
  ...userProvidedOptions,
1287
+ // CLAUDE_MODEL_CONFIG env var is a fallback for model
1288
+ // configuration (e.g. Bedrock model ID overrides). When the caller
1289
+ // provides settings via _meta, we intentionally ignore the env var —
1290
+ // the caller is assumed to have full control over model configuration.
1291
+ ...(!userProvidedOptions?.settings &&
1292
+ modelConfig && {
1293
+ settings: {
1294
+ ...(modelConfig.modelOverrides && { modelOverrides: modelConfig.modelOverrides }),
1295
+ ...(modelConfig.availableModels && { availableModels: modelConfig.availableModels }),
1296
+ },
1297
+ }),
1135
1298
  env: {
1136
1299
  ...process.env,
1137
1300
  ...userProvidedOptions?.env,
@@ -1148,7 +1311,7 @@ export class ClaudeAcpAgent {
1148
1311
  allowDangerouslySkipPermissions: ALLOW_BYPASS,
1149
1312
  permissionMode,
1150
1313
  canUseTool: this.canUseTool(sessionId),
1151
- pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE,
1314
+ pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE ?? (await claudeCliPath()),
1152
1315
  extraArgs: {
1153
1316
  ...userProvidedOptions?.extraArgs,
1154
1317
  "replay-user-messages": "",
@@ -1254,7 +1417,14 @@ export class ClaudeAcpAgent {
1254
1417
  currentModeId: permissionMode,
1255
1418
  availableModes,
1256
1419
  };
1257
- const configOptions = buildConfigOptions(modes, models);
1420
+ const configOptions = buildConfigOptions(modes, models, initializationResult.models, settingsManager.getSettings().effortLevel);
1421
+ // Apply the initial effort level to the SDK so it matches the UI default
1422
+ const initialEffort = configOptions.find((o) => o.id === "effort");
1423
+ if (initialEffort && typeof initialEffort.currentValue === "string") {
1424
+ await q.applyFlagSettings({
1425
+ effortLevel: initialEffort.currentValue,
1426
+ });
1427
+ }
1258
1428
  this.sessions[sessionId] = {
1259
1429
  query: q,
1260
1430
  input: input,
@@ -1270,6 +1440,7 @@ export class ClaudeAcpAgent {
1270
1440
  },
1271
1441
  modes,
1272
1442
  models,
1443
+ modelInfos: initializationResult.models,
1273
1444
  configOptions,
1274
1445
  promptRunning: false,
1275
1446
  pendingMessages: new Map(),
@@ -1315,6 +1486,19 @@ function totalTokens(usage) {
1315
1486
  usage.cache_read_input_tokens +
1316
1487
  usage.cache_creation_input_tokens);
1317
1488
  }
1489
+ /**
1490
+ * Build the `data` payload attached to a `RequestError.internalError` when we
1491
+ * have a categorical error from the Claude SDK. Returns `undefined` when no
1492
+ * categorical error is available, matching the previous behavior of passing
1493
+ * `undefined` to `RequestError.internalError`.
1494
+ *
1495
+ * The `errorKind` field is a convention for ACP clients to dispatch on
1496
+ * without having to pattern-match the human-readable message text. Clients
1497
+ * that don't understand it fall back to the existing message-based rendering.
1498
+ */
1499
+ function errorKindData(errorKind) {
1500
+ return errorKind ? { errorKind } : undefined;
1501
+ }
1318
1502
  /** Project a nullable API usage object into our non-null snapshot shape.
1319
1503
  * Both SDK message_start and assistant message `usage` have `number | null`
1320
1504
  * cache fields; we coerce absent values to 0 so `totalTokens` never hits
@@ -1343,8 +1527,8 @@ function createEnvForGateway(gatewayMeta) {
1343
1527
  ANTHROPIC_AUTH_TOKEN: "", // Must be specified to bypass claude login requirement
1344
1528
  };
1345
1529
  }
1346
- function buildConfigOptions(modes, models) {
1347
- return [
1530
+ function buildConfigOptions(modes, models, modelInfos, currentEffortLevel) {
1531
+ const options = [
1348
1532
  {
1349
1533
  id: "mode",
1350
1534
  name: "Mode",
@@ -1372,6 +1556,40 @@ function buildConfigOptions(modes, models) {
1372
1556
  })),
1373
1557
  },
1374
1558
  ];
1559
+ // Add effort level option based on the currently selected model
1560
+ const currentModelInfo = modelInfos.find((m) => m.value === models.currentModelId);
1561
+ const supportedLevels = currentModelInfo?.supportsEffort
1562
+ ? (currentModelInfo.supportedEffortLevels ?? [])
1563
+ : [];
1564
+ if (supportedLevels.length > 0) {
1565
+ const effortOptions = supportedLevels.map((level) => ({
1566
+ value: level,
1567
+ name: level
1568
+ .split(/[_-]/)
1569
+ .map((part) => (part ? part.charAt(0).toUpperCase() + part.slice(1) : part))
1570
+ .join(" "),
1571
+ }));
1572
+ // Keep the current level if valid, otherwise prefer xhigh (Claude Code's
1573
+ // recommended default for capable models), then high (the API default).
1574
+ const includes = (l) => supportedLevels.includes(l);
1575
+ const validEffort = currentEffortLevel && includes(currentEffortLevel)
1576
+ ? currentEffortLevel
1577
+ : includes("xhigh")
1578
+ ? "xhigh"
1579
+ : includes("high")
1580
+ ? "high"
1581
+ : supportedLevels[0];
1582
+ options.push({
1583
+ id: "effort",
1584
+ name: "Effort",
1585
+ description: "Available effort levels for this model",
1586
+ category: "effort",
1587
+ type: "select",
1588
+ currentValue: validEffort,
1589
+ options: effortOptions,
1590
+ });
1591
+ }
1592
+ return options;
1375
1593
  }
1376
1594
  // Claude Code CLI persists display strings like "opus[1m]" in settings,
1377
1595
  // but the SDK model list uses IDs like "claude-opus-4-6-1m".
@@ -1877,6 +2095,20 @@ function inferContextWindowFromModel(model) {
1877
2095
  return 1_000_000;
1878
2096
  return null;
1879
2097
  }
2098
+ function parseModelConfig(raw) {
2099
+ if (!raw)
2100
+ return undefined;
2101
+ const parsed = JSON.parse(raw);
2102
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
2103
+ throw new Error("CLAUDE_MODEL_CONFIG must be a JSON object");
2104
+ }
2105
+ const result = {};
2106
+ if (parsed.modelOverrides !== undefined)
2107
+ result.modelOverrides = parsed.modelOverrides;
2108
+ if (parsed.availableModels !== undefined)
2109
+ result.availableModels = parsed.availableModels;
2110
+ return Object.keys(result).length > 0 ? result : undefined;
2111
+ }
1880
2112
  function getMatchingModelUsage(modelUsage, currentModel) {
1881
2113
  let bestKey = null;
1882
2114
  let bestLen = 0;
package/dist/lib.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ClaudeAcpAgent, runAcp, toAcpNotifications, streamEventToAcpNotifications, type ToolUpdateMeta, type NewSessionMeta, type SDKMessageFilter, } from "./acp-agent.js";
1
+ export { ClaudeAcpAgent, isLocalCommandMetadata, stripLocalCommandMetadata, runAcp, toAcpNotifications, streamEventToAcpNotifications, type ToolUpdateMeta, type NewSessionMeta, type SDKMessageFilter, } from "./acp-agent.js";
2
2
  export { loadManagedSettings, applyEnvironmentSettings, nodeToWebReadable, nodeToWebWritable, Pushable, unreachable, } from "./utils.js";
3
3
  export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
4
4
  export { SettingsManager, type ClaudeCodeSettings, type SettingsManagerOptions, } from "./settings.js";
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,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,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"}
package/dist/lib.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Export the main agent class and utilities for library usage
2
- export { ClaudeAcpAgent, runAcp, toAcpNotifications, streamEventToAcpNotifications, } from "./acp-agent.js";
2
+ export { ClaudeAcpAgent, isLocalCommandMetadata, stripLocalCommandMetadata, runAcp, toAcpNotifications, streamEventToAcpNotifications, } from "./acp-agent.js";
3
3
  export { loadManagedSettings, applyEnvironmentSettings, nodeToWebReadable, nodeToWebWritable, Pushable, unreachable, } from "./utils.js";
4
4
  export { toolInfoFromToolUse, toDisplayPath, planEntries, toolUpdateFromToolResult, } from "./tools.js";
5
5
  export { SettingsManager, } from "./settings.js";
@@ -16,6 +16,7 @@ export interface ClaudeCodeSettings {
16
16
  permissions?: PermissionSettings;
17
17
  env?: Record<string, string>;
18
18
  model?: string;
19
+ effortLevel?: string;
19
20
  }
20
21
  /**
21
22
  * Gets the enterprise settings path based on the current platform
@@ -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;CAChB;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;IA8BrB;;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;;;;;;;;;;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;CACtB;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;IAkCrB;;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"}
package/dist/settings.js CHANGED
@@ -138,6 +138,9 @@ export class SettingsManager {
138
138
  if (settings.model) {
139
139
  merged.model = settings.model;
140
140
  }
141
+ if (settings.effortLevel !== undefined) {
142
+ merged.effortLevel = settings.effortLevel;
143
+ }
141
144
  if (settings.permissions?.defaultMode !== undefined) {
142
145
  merged.permissions = {
143
146
  ...merged.permissions,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.30.0",
6
+ "version": "0.31.1",
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.19.0",
64
- "@anthropic-ai/claude-agent-sdk": "0.2.114",
63
+ "@agentclientprotocol/sdk": "0.20.0",
64
+ "@anthropic-ai/claude-agent-sdk": "0.2.119",
65
65
  "zod": "^3.25.0 || ^4.0.0"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@anthropic-ai/sdk": "0.89.0",
69
69
  "@eslint/js": "10.0.1",
70
70
  "@types/node": "25.6.0",
71
- "@typescript-eslint/eslint-plugin": "8.58.2",
72
- "@typescript-eslint/parser": "8.58.2",
71
+ "@typescript-eslint/eslint-plugin": "8.59.0",
72
+ "@typescript-eslint/parser": "8.59.0",
73
73
  "eslint": "10.2.1",
74
74
  "eslint-config-prettier": "10.1.8",
75
75
  "globals": "17.5.0",
76
76
  "prettier": "3.8.3",
77
77
  "ts-node": "10.9.2",
78
78
  "typescript": "6.0.3",
79
- "vitest": "4.1.4"
79
+ "vitest": "4.1.5"
80
80
  }
81
81
  }