@agentclientprotocol/claude-agent-acp 0.65.0 → 0.67.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.
@@ -0,0 +1,36 @@
1
+ import type { SDKActiveGoalMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ export declare const GOAL_EXTENSION_VERSION: 1;
3
+ export declare const GOAL_CONTROL_METHOD = "_session/goal";
4
+ export declare const GOAL_ACTIONS: readonly ["set", "clear"];
5
+ export type GoalAction = (typeof GOAL_ACTIONS)[number];
6
+ export type GoalCapability = {
7
+ version: typeof GOAL_EXTENSION_VERSION;
8
+ controlMethod: typeof GOAL_CONTROL_METHOD;
9
+ actions: GoalAction[];
10
+ };
11
+ export type GoalStatus = "active" | "paused" | "blocked" | "limited" | "complete";
12
+ export type GoalSnapshot = {
13
+ objective: string;
14
+ status: GoalStatus;
15
+ iterations?: number;
16
+ lastReason?: string | null;
17
+ createdAt?: number;
18
+ updatedAt?: number;
19
+ tokenBudget?: number | null;
20
+ tokensUsed?: number;
21
+ timeUsedSeconds?: number;
22
+ controlMethod: typeof GOAL_CONTROL_METHOD;
23
+ };
24
+ export type GoalRequest = {
25
+ sessionId: string;
26
+ action: "clear";
27
+ } | {
28
+ sessionId: string;
29
+ action: "set";
30
+ objective: string;
31
+ };
32
+ export type GoalControlResponse = Record<string, never>;
33
+ export declare function goalUpdateFromPrompt(prompt: string): GoalSnapshot | null | undefined;
34
+ export declare function parseGoalRequest(params: unknown): GoalRequest;
35
+ export declare function toGoalSnapshot(message: SDKActiveGoalMessage): GoalSnapshot | null;
36
+ //# sourceMappingURL=goal-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-extension.d.ts","sourceRoot":"","sources":["../src/goal-extension.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC;AACjD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD,eAAO,MAAM,YAAY,2BAA4B,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,OAAO,sBAAsB,CAAC;IACvC,aAAa,EAAE,OAAO,mBAAmB,CAAC;IAC1C,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAElF,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,mBAAmB,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,WAAW,GACrB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAExD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,CAcpF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAiB7D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,YAAY,GAAG,IAAI,CAYjF"}
@@ -0,0 +1,50 @@
1
+ import { RequestError } from "@agentclientprotocol/sdk";
2
+ export const GOAL_EXTENSION_VERSION = 1;
3
+ export const GOAL_CONTROL_METHOD = "_session/goal";
4
+ export const GOAL_ACTIONS = ["set", "clear"];
5
+ export function goalUpdateFromPrompt(prompt) {
6
+ const match = /^\/goal(?:\s+([\s\S]*))?$/.exec(prompt);
7
+ const argument = match?.[1]?.trim();
8
+ if (!argument) {
9
+ return undefined;
10
+ }
11
+ if (argument === "clear") {
12
+ return null;
13
+ }
14
+ return {
15
+ objective: argument,
16
+ status: "active",
17
+ controlMethod: GOAL_CONTROL_METHOD,
18
+ };
19
+ }
20
+ export function parseGoalRequest(params) {
21
+ if (!params || typeof params !== "object") {
22
+ throw RequestError.invalidParams(undefined, "goal params must be an object");
23
+ }
24
+ const { sessionId, action, objective } = params;
25
+ if (typeof sessionId !== "string" || sessionId.length === 0) {
26
+ throw RequestError.invalidParams(undefined, "goal params require a non-empty sessionId");
27
+ }
28
+ if (!GOAL_ACTIONS.includes(action)) {
29
+ throw RequestError.invalidParams(undefined, 'goal action must be "set" or "clear"');
30
+ }
31
+ if (action === "set" && (typeof objective !== "string" || objective.trim().length === 0)) {
32
+ throw RequestError.invalidParams(undefined, 'goal action "set" requires a non-empty objective');
33
+ }
34
+ return action === "set"
35
+ ? { sessionId, action, objective: objective.trim() }
36
+ : { sessionId, action: "clear" };
37
+ }
38
+ export function toGoalSnapshot(message) {
39
+ if (message.value === null) {
40
+ return null;
41
+ }
42
+ return {
43
+ objective: message.value.condition.trim(),
44
+ status: "active",
45
+ iterations: message.value.iterations,
46
+ lastReason: message.value.last_reason ?? null,
47
+ createdAt: message.value.set_at,
48
+ controlMethod: GOAL_CONTROL_METHOD,
49
+ };
50
+ }
package/dist/tools.d.ts CHANGED
@@ -1,6 +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
+ import { TaskCreateInput, TaskCreateOutput, TaskListOutput, TaskUpdateInput, TaskUpdateOutput } from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
4
4
  import { ToolResultBlockParam, WebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources";
5
5
  import { BetaBashCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultBlockParam, BetaRequestMCPToolResultBlockParam, BetaTextEditorCodeExecutionToolResultBlockParam, BetaToolResultBlockParam, BetaToolSearchToolResultBlockParam, BetaWebFetchToolResultBlockParam, BetaWebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources/beta.mjs";
6
6
  interface ToolInfo {
@@ -57,14 +57,12 @@ export type TaskEntry = {
57
57
  description?: string;
58
58
  };
59
59
  export type TaskState = Map<string, TaskEntry>;
60
- /**
61
- * Best-effort parse of a TaskCreate tool_result content into the structured
62
- * TaskCreateOutput. The SDK delivers tool outputs either as a string or as
63
- * an array of TextBlockParam-like blocks containing JSON text; try both.
64
- */
65
60
  export declare function parseTaskCreateOutput(content: unknown): TaskCreateOutput | undefined;
61
+ export declare function parseTaskListOutput(content: unknown): TaskListOutput | undefined;
62
+ export declare function parseTaskUpdateOutput(content: unknown, expectedTaskId?: string): TaskUpdateOutput | undefined;
66
63
  export declare function applyTaskCreate(state: TaskState, input: TaskCreateInput | undefined, output: TaskCreateOutput | undefined): void;
67
64
  export declare function applyTaskUpdate(state: TaskState, input: TaskUpdateInput | undefined): void;
65
+ export declare function applyTaskList(state: TaskState, output: TaskListOutput): void;
68
66
  export declare function taskStateToPlanEntries(state: TaskState): PlanEntry[];
69
67
  export declare function markdownEscape(text: string): string;
70
68
  /**
@@ -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
@@ -96,7 +96,7 @@ export function toolInfoFromToolUse(toolUse, supportsTerminalOutput = false, cwd
96
96
  }
97
97
  const displayPath = input?.file_path ? toDisplayPath(input.file_path, cwd) : undefined;
98
98
  return {
99
- title: displayPath ? `Write ${displayPath}` : "Write",
99
+ title: displayPath ? `Write ${displayPath}` : "Preparing file…",
100
100
  kind: "edit",
101
101
  content,
102
102
  locations: input?.file_path ? [{ path: input.file_path }] : [],
@@ -291,6 +291,15 @@ export function toolInfoFromToolUse(toolUse, supportsTerminalOutput = false, cwd
291
291
  : [],
292
292
  };
293
293
  }
294
+ case "Skill": {
295
+ const input = toolUse.input;
296
+ const skillName = input?.skill;
297
+ return {
298
+ title: skillName ? `Load skill: ${skillName}` : "Load skill",
299
+ kind: "other",
300
+ content: [],
301
+ };
302
+ }
294
303
  case "AskUserQuestion": {
295
304
  const input = toolUse.input;
296
305
  const questions = Array.isArray(input?.questions) ? input.questions : [];
@@ -658,6 +667,9 @@ export function toolUpdateFromToolResult(toolResult, toolUse, supportsTerminalOu
658
667
  // renders, no worse than before.
659
668
  return toAcpContentUpdate(stripAgentTrailerFromContent(toolResult.content), "is_error" in toolResult ? toolResult.is_error : false);
660
669
  }
670
+ case "Skill": {
671
+ return {};
672
+ }
661
673
  case "Edit": // Edit is handled in hooks
662
674
  case "Write": {
663
675
  return {};
@@ -798,35 +810,32 @@ function toAcpContentBlock(content, isError) {
798
810
  }
799
811
  export function planEntries(input) {
800
812
  return (input?.todos ?? []).map((todo) => ({
801
- content: todo.content,
813
+ content: todo.status === "in_progress" && todo.activeForm ? todo.activeForm : todo.content,
802
814
  status: todo.status,
803
815
  priority: "medium",
804
816
  }));
805
817
  }
806
818
  /**
807
- * Best-effort parse of a TaskCreate tool_result content into the structured
808
- * TaskCreateOutput. The SDK delivers tool outputs either as a string or as
809
- * an array of TextBlockParam-like blocks containing JSON text; try both.
819
+ * Best-effort parse of a structured Task* tool_result. The SDK delivers tool
820
+ * outputs either as a string or as an array of TextBlockParam-like blocks
821
+ * containing JSON text; try both.
810
822
  */
811
- export function parseTaskCreateOutput(content) {
823
+ function parseJsonToolOutput(content, isExpectedOutput) {
812
824
  const tryParse = (text) => {
813
825
  try {
814
826
  const parsed = JSON.parse(text);
815
- if (parsed &&
816
- typeof parsed === "object" &&
817
- parsed.task &&
818
- typeof parsed.task.id === "string") {
819
- return parsed;
820
- }
827
+ return isExpectedOutput(parsed) ? parsed : undefined;
821
828
  }
822
829
  catch {
823
- // ignore
830
+ return undefined;
824
831
  }
825
- return undefined;
826
832
  };
827
833
  if (typeof content === "string") {
828
834
  return tryParse(content);
829
835
  }
836
+ if (content && typeof content === "object" && !Array.isArray(content)) {
837
+ return isExpectedOutput(content) ? content : undefined;
838
+ }
830
839
  if (Array.isArray(content)) {
831
840
  for (const block of content) {
832
841
  if (block && typeof block === "object" && "type" in block && block.type === "text") {
@@ -841,6 +850,96 @@ export function parseTaskCreateOutput(content) {
841
850
  }
842
851
  return undefined;
843
852
  }
853
+ function toolOutputTexts(content) {
854
+ if (typeof content === "string")
855
+ return [content];
856
+ if (!Array.isArray(content))
857
+ return [];
858
+ return content.flatMap((block) => block &&
859
+ typeof block === "object" &&
860
+ "type" in block &&
861
+ block.type === "text" &&
862
+ "text" in block &&
863
+ typeof block.text === "string"
864
+ ? [block.text]
865
+ : []);
866
+ }
867
+ export function parseTaskCreateOutput(content) {
868
+ const structured = parseJsonToolOutput(content, (parsed) => Boolean(parsed &&
869
+ typeof parsed === "object" &&
870
+ "task" in parsed &&
871
+ parsed.task &&
872
+ typeof parsed.task === "object" &&
873
+ "id" in parsed.task &&
874
+ typeof parsed.task.id === "string"));
875
+ if (structured)
876
+ return structured;
877
+ for (const text of toolOutputTexts(content)) {
878
+ const match = /^Task #(\S+) created successfully: (.+)$/.exec(text.trim());
879
+ if (match)
880
+ return { task: { id: match[1], subject: match[2] } };
881
+ }
882
+ return undefined;
883
+ }
884
+ export function parseTaskListOutput(content) {
885
+ const validStatuses = new Set(["pending", "in_progress", "completed"]);
886
+ const structured = parseJsonToolOutput(content, (parsed) => Boolean(parsed &&
887
+ typeof parsed === "object" &&
888
+ "tasks" in parsed &&
889
+ Array.isArray(parsed.tasks) &&
890
+ parsed.tasks.every((task) => task &&
891
+ typeof task === "object" &&
892
+ typeof task.id === "string" &&
893
+ typeof task.subject === "string" &&
894
+ typeof task.status === "string" &&
895
+ validStatuses.has(task.status))));
896
+ if (structured)
897
+ return structured;
898
+ for (const text of toolOutputTexts(content)) {
899
+ if (text.trim() === "No tasks found")
900
+ return { tasks: [] };
901
+ const tasks = [];
902
+ const lines = text.trim().split("\n");
903
+ for (const line of lines) {
904
+ const match = /^#(\S+) \[(pending|in_progress|completed)\] (.+?)(?: \(([^()]*)\))?(?: \[blocked by ((?:#[^,\]]+(?:, )?)+)\])?$/.exec(line);
905
+ if (!match) {
906
+ tasks.length = 0;
907
+ break;
908
+ }
909
+ tasks.push({
910
+ id: match[1],
911
+ subject: match[3],
912
+ status: match[2],
913
+ ...(match[4] ? { owner: match[4] } : {}),
914
+ blockedBy: match[5] ? match[5].split(", ").map((id) => id.slice(1)) : [],
915
+ });
916
+ }
917
+ if (tasks.length > 0)
918
+ return { tasks };
919
+ }
920
+ return undefined;
921
+ }
922
+ export function parseTaskUpdateOutput(content, expectedTaskId) {
923
+ const structured = parseJsonToolOutput(content, (parsed) => Boolean(parsed &&
924
+ typeof parsed === "object" &&
925
+ "success" in parsed &&
926
+ typeof parsed.success === "boolean" &&
927
+ "taskId" in parsed &&
928
+ typeof parsed.taskId === "string" &&
929
+ "updatedFields" in parsed &&
930
+ Array.isArray(parsed.updatedFields) &&
931
+ parsed.updatedFields.every((field) => typeof field === "string")));
932
+ if (structured)
933
+ return structured;
934
+ for (const text of toolOutputTexts(content)) {
935
+ const notFound = /^Task #(\S+) not found$/.exec(text.trim());
936
+ const taskId = notFound?.[1] ?? expectedTaskId;
937
+ if (taskId && (notFound || text.trim() === "Failed to delete task")) {
938
+ return { success: false, taskId, updatedFields: [], error: text.trim() };
939
+ }
940
+ }
941
+ return undefined;
942
+ }
844
943
  export function applyTaskCreate(state, input, output) {
845
944
  const taskId = output?.task?.id;
846
945
  if (!taskId || !input)
@@ -872,9 +971,22 @@ export function applyTaskUpdate(state, input) {
872
971
  description: input.description ?? existing?.description,
873
972
  });
874
973
  }
974
+ export function applyTaskList(state, output) {
975
+ const previous = new Map(state);
976
+ state.clear();
977
+ for (const task of output.tasks) {
978
+ const existing = previous.get(task.id);
979
+ state.set(task.id, {
980
+ subject: task.subject,
981
+ status: task.status,
982
+ activeForm: existing?.activeForm,
983
+ description: existing?.description,
984
+ });
985
+ }
986
+ }
875
987
  export function taskStateToPlanEntries(state) {
876
988
  return Array.from(state.values()).map((task) => ({
877
- content: task.subject,
989
+ content: task.status === "in_progress" && task.activeForm ? task.activeForm : task.subject,
878
990
  status: task.status,
879
991
  priority: "medium",
880
992
  }));
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.65.0",
6
+ "version": "0.67.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",
@@ -35,6 +35,7 @@
35
35
  "format": "prettier --write .",
36
36
  "format:check": "prettier --check .",
37
37
  "check": "npm run lint && npm run format:check",
38
+ "release:preflight": "bash scripts/release-preflight.sh",
38
39
  "test": "vitest",
39
40
  "test:integration": "RUN_INTEGRATION_TESTS=true vitest run",
40
41
  "test:run": "vitest run",
@@ -65,19 +66,19 @@
65
66
  },
66
67
  "dependencies": {
67
68
  "@agentclientprotocol/sdk": "1.3.0",
68
- "@anthropic-ai/claude-agent-sdk": "0.3.220",
69
+ "@anthropic-ai/claude-agent-sdk": "0.3.232",
69
70
  "zod": "^3.25.0 || ^4.0.0"
70
71
  },
71
72
  "devDependencies": {
72
- "@anthropic-ai/sdk": "0.115.0",
73
+ "@anthropic-ai/sdk": "0.117.1",
73
74
  "@eslint/js": "10.0.1",
74
75
  "@tsconfig/node22": "22.0.5",
75
- "@types/node": "26.1.2",
76
- "@typescript-eslint/eslint-plugin": "8.65.0",
77
- "@typescript-eslint/parser": "8.65.0",
78
- "eslint": "10.8.0",
76
+ "@types/node": "26.2.0",
77
+ "@typescript-eslint/eslint-plugin": "8.67.0",
78
+ "@typescript-eslint/parser": "8.67.0",
79
+ "eslint": "10.8.1",
79
80
  "eslint-config-prettier": "10.1.8",
80
- "globals": "17.8.0",
81
+ "globals": "17.11.0",
81
82
  "prettier": "3.9.6",
82
83
  "ts-node": "10.9.2",
83
84
  "typescript": "6.0.3",