@agentclientprotocol/claude-agent-acp 0.77.1-preview.2 → 0.77.1-preview.4

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.
@@ -2,6 +2,7 @@ export declare const AIR_NATIVE_SUBAGENT_SESSIONS_CAPABILITY = "nativeSubagentSe
2
2
  export declare const AIR_ASYNC_TASKS_CAPABILITY = "asyncTasks";
3
3
  export declare const AIR_SESSION_FAILURE_CAPABILITY = "sessionFailure";
4
4
  export declare const AIR_RECOMMENDED_CONFIG_VALUE_CAPABILITY = "recommendedValue";
5
+ export declare const AIR_DIFF_STATS_KEY = "diffStats";
5
6
  /** The capability list this side advertises, as its own `_meta` object. */
6
7
  export declare function airCapabilityMeta(...capabilities: string[]): Record<string, unknown>;
7
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"air-extension.d.ts","sourceRoot":"","sources":["../src/air-extension.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uCAAuC,2BAA2B,CAAC;AAChF,eAAO,MAAM,0BAA0B,eAAe,CAAC;AACvD,eAAO,MAAM,8BAA8B,mBAAmB,CAAC;AAC/D,eAAO,MAAM,uCAAuC,qBAAqB,CAAC;AAQ1E,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,GAAG,YAAY,EAAE,MAAM,EAAE,2BAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAChD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKnF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAY9F"}
1
+ {"version":3,"file":"air-extension.d.ts","sourceRoot":"","sources":["../src/air-extension.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uCAAuC,2BAA2B,CAAC;AAChF,eAAO,MAAM,0BAA0B,eAAe,CAAC;AACvD,eAAO,MAAM,8BAA8B,mBAAmB,CAAC;AAC/D,eAAO,MAAM,uCAAuC,qBAAqB,CAAC;AAC1E,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAQ9C,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,GAAG,YAAY,EAAE,MAAM,EAAE,2BAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAChD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKnF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAY9F"}
@@ -2,6 +2,7 @@ export const AIR_NATIVE_SUBAGENT_SESSIONS_CAPABILITY = "nativeSubagentSessions";
2
2
  export const AIR_ASYNC_TASKS_CAPABILITY = "asyncTasks";
3
3
  export const AIR_SESSION_FAILURE_CAPABILITY = "sessionFailure";
4
4
  export const AIR_RECOMMENDED_CONFIG_VALUE_CAPABILITY = "recommendedValue";
5
+ export const AIR_DIFF_STATS_KEY = "diffStats";
5
6
  const JETBRAINS_META_KEY = "jetbrains";
6
7
  const AIR_META_KEY = "air";
7
8
  const AIR_EXTENSION_VERSION_KEY = "version";
package/dist/diff.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { ToolCallContent, ToolCallLocation } from "@agentclientprotocol/sdk";
2
+ /**
3
+ * Builds diff ToolUpdate content from the structured toolResponse provided by
4
+ * the PostToolUse hook for diff-producing tools (Edit, Write). Unlike parsing
5
+ * the plain unified diff string, this uses the pre-parsed structuredPatch
6
+ * which supports multiple replacement sites (replaceAll) and always includes
7
+ * context lines for better readability.
8
+ */
9
+ export declare function toolUpdateFromDiffToolResponse(toolResponse: unknown): {
10
+ content?: ToolCallContent[];
11
+ locations?: ToolCallLocation[];
12
+ };
13
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAwB7E;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,OAAO,GAAG;IACrE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC,CA2HA"}
package/dist/diff.js ADDED
@@ -0,0 +1,131 @@
1
+ import { AIR_DIFF_STATS_KEY, withAirMeta } from "./air-extension.js";
2
+ /**
3
+ * Builds diff ToolUpdate content from the structured toolResponse provided by
4
+ * the PostToolUse hook for diff-producing tools (Edit, Write). Unlike parsing
5
+ * the plain unified diff string, this uses the pre-parsed structuredPatch
6
+ * which supports multiple replacement sites (replaceAll) and always includes
7
+ * context lines for better readability.
8
+ */
9
+ export function toolUpdateFromDiffToolResponse(toolResponse) {
10
+ if (!toolResponse || typeof toolResponse !== "object")
11
+ return {};
12
+ const response = toolResponse;
13
+ if (!response.filePath || !Array.isArray(response.structuredPatch))
14
+ return {};
15
+ const content = [];
16
+ const locations = [];
17
+ let previousOldEnd = 0;
18
+ let previousNewEnd = 0;
19
+ let accumulatedDelta = 0;
20
+ let coordinatesRemainConsistent = true;
21
+ for (const { lines, oldStart, newStart, oldLines, newLines } of response.structuredPatch) {
22
+ const oldText = [];
23
+ const newText = [];
24
+ let added = 0;
25
+ let removed = 0;
26
+ let validPrefixes = true;
27
+ let validEofMarkers = true;
28
+ const oldPosition = oldStart + (oldLines === 0 ? 1 : 0);
29
+ const newPosition = newStart + (newLines === 0 ? 1 : 0);
30
+ const oldEnd = oldPosition + oldLines;
31
+ const newEnd = newPosition + newLines;
32
+ const nextDelta = accumulatedDelta + newLines - oldLines;
33
+ const validCoordinates = coordinatesRemainConsistent &&
34
+ Number.isSafeInteger(oldStart) &&
35
+ Number.isSafeInteger(newStart) &&
36
+ Number.isSafeInteger(oldLines) &&
37
+ Number.isSafeInteger(newLines) &&
38
+ oldStart >= (oldLines === 0 ? 0 : 1) &&
39
+ newStart >= (newLines === 0 ? 0 : 1) &&
40
+ oldLines >= 0 &&
41
+ newLines >= 0 &&
42
+ Number.isSafeInteger(oldPosition) &&
43
+ Number.isSafeInteger(newPosition) &&
44
+ Number.isSafeInteger(oldEnd) &&
45
+ Number.isSafeInteger(newEnd) &&
46
+ Number.isSafeInteger(nextDelta) &&
47
+ oldPosition >= previousOldEnd &&
48
+ newPosition >= previousNewEnd &&
49
+ newPosition - oldPosition === accumulatedDelta;
50
+ coordinatesRemainConsistent = validCoordinates;
51
+ if (validCoordinates) {
52
+ previousOldEnd = oldEnd;
53
+ previousNewEnd = newEnd;
54
+ accumulatedDelta = nextDelta;
55
+ }
56
+ for (const [index, line] of lines.entries()) {
57
+ if (line.startsWith("-")) {
58
+ oldText.push(line.slice(1));
59
+ removed++;
60
+ }
61
+ else if (line.startsWith("+")) {
62
+ newText.push(line.slice(1));
63
+ added++;
64
+ }
65
+ else if (line === "\") {
66
+ const previousLine = lines[index - 1];
67
+ if (typeof previousLine !== "string" ||
68
+ (!previousLine.startsWith("-") &&
69
+ !previousLine.startsWith("+") &&
70
+ !previousLine.startsWith(" "))) {
71
+ validEofMarkers = false;
72
+ }
73
+ continue;
74
+ }
75
+ else {
76
+ if (!line.startsWith(" "))
77
+ validPrefixes = false;
78
+ oldText.push(line.slice(1));
79
+ newText.push(line.slice(1));
80
+ }
81
+ }
82
+ if (oldText.length > 0 || newText.length > 0) {
83
+ locations.push({ path: response.filePath, line: newStart });
84
+ content.push({
85
+ type: "diff",
86
+ path: response.filePath,
87
+ oldText: oldText.join("\n") || null,
88
+ newText: newText.join("\n"),
89
+ ...(validCoordinates &&
90
+ validPrefixes &&
91
+ validEofMarkers &&
92
+ oldText.length === oldLines &&
93
+ newText.length === newLines
94
+ ? { _meta: withAirMeta(undefined, AIR_DIFF_STATS_KEY, { version: 1, added, removed }) }
95
+ : {}),
96
+ });
97
+ }
98
+ }
99
+ // A Write `update` can arrive with an empty structuredPatch — nothing
100
+ // changed, the diff timed out, or the previous content was too large to
101
+ // diff (originalFile null; SDK 0.3.252 documents the lane). Returning `{}`
102
+ // would leave Write's optimistic tool_use-time content standing, and that
103
+ // was built with `oldText: null` — "creation" semantics — so an overwrite
104
+ // of a large existing file would render as creating it. Emit a truthful
105
+ // replacement instead. Gated on `type` so Edit (whose output carries no
106
+ // `type` and whose optimistic old/new diff is already truthful) keeps the
107
+ // empty-return behavior.
108
+ if (content.length === 0 && response.type === "update" && typeof response.content === "string") {
109
+ locations.push({ path: response.filePath });
110
+ content.push(typeof response.originalFile === "string"
111
+ ? {
112
+ type: "diff",
113
+ path: response.filePath,
114
+ oldText: response.originalFile,
115
+ newText: response.content,
116
+ }
117
+ : {
118
+ type: "content",
119
+ content: {
120
+ type: "text",
121
+ text: `Updated \`${response.filePath}\` (previous content too large to diff)`,
122
+ },
123
+ });
124
+ }
125
+ const result = {};
126
+ if (content.length > 0)
127
+ result.content = content;
128
+ if (locations.length > 0)
129
+ result.locations = locations;
130
+ return result;
131
+ }
@@ -1,22 +1,19 @@
1
- import { type HookCallback, type McpSdkServerConfigWithInstance } from "@anthropic-ai/claude-agent-sdk";
1
+ import type { Query } from "@anthropic-ai/claude-agent-sdk";
2
2
  export declare const AGENT_FILE_CHANGE_REPORT_CAPABILITY = "agentFileChangeReport";
3
- export declare const FILE_CHANGE_AUDIT_SERVER_NAME = "claude_agent_acp";
4
- export declare const FILE_CHANGE_AUDIT_TOOL_NAME = "report_changed_files";
5
- export declare const FILE_CHANGE_AUDIT_WIRE_TOOL_NAME = "mcp__claude_agent_acp__report_changed_files";
6
3
  export declare const AGENT_FILE_CHANGE_REPORT_MAX_BYTES: number;
7
- export type FileChangeAuditTurnState = {
4
+ export declare const AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS = 2000;
5
+ export type FileChangeReportTurnState = {
8
6
  requestId: string;
9
7
  phase: "requested" | "collecting" | "finished";
10
8
  };
11
- export type FileChangeAuditWorkspace = {
9
+ export type NativeFileChangeReportTurn = {
10
+ promptUuid: string;
11
+ fileChangeReport?: FileChangeReportTurnState;
12
+ };
13
+ export type FileChangeReportWorkspace = {
12
14
  cwd: string;
13
15
  additionalDirectories: string[];
14
16
  };
15
- export type AgentFileChangeReport = {
16
- paths: string[];
17
- complete: boolean;
18
- uncertainty?: string;
19
- };
20
17
  export type AgentFileChangeReportResult = {
21
18
  version: 1;
22
19
  requestId: string;
@@ -25,32 +22,26 @@ export type AgentFileChangeReportResult = {
25
22
  paths: string[];
26
23
  declaredComplete: boolean;
27
24
  truncated: boolean;
28
- uncertainty?: string;
29
25
  } | {
30
26
  status: "unavailable";
31
27
  reason: FileChangeReportUnavailableReason;
32
28
  });
33
29
  export type FileChangeReportUnavailableReason = "cancelled" | "timeout" | "invalidOutput" | "notReported" | "providerError";
34
- type FileChangeAuditSupportOptions = {
30
+ type NativeFileChangeReporterOptions = {
35
31
  cwd: string;
36
32
  additionalDirectories: string[];
37
- getActiveState: () => FileChangeAuditTurnState | undefined;
38
33
  publish: (result: AgentFileChangeReportResult) => Promise<void>;
39
34
  logError: (message: string) => void;
35
+ timeoutMs?: number;
40
36
  };
41
- export type FileChangeAuditSupport = {
42
- mcpServer: McpSdkServerConfigWithInstance;
43
- preToolUseHook: HookCallback;
44
- stopHook: HookCallback;
45
- finishUnavailable: (state: FileChangeAuditTurnState, reason: FileChangeReportUnavailableReason) => Promise<void>;
37
+ export type NativeFileChangeReporter = {
38
+ request(meta: unknown): FileChangeReportTurnState | undefined;
39
+ report(turn: NativeFileChangeReportTurn | null | undefined, query: Pick<Query, "rewindFiles">): Promise<void>;
40
+ finish(state: FileChangeReportTurnState | undefined, reason: FileChangeReportUnavailableReason): void;
46
41
  };
47
42
  export declare function agentFileChangeReportRequestId(meta: unknown): string | undefined;
48
43
  export declare function supportsAgentFileChangeReport(capabilities: unknown): boolean;
49
44
  export declare function agentFileChangeReportMeta(result: AgentFileChangeReportResult): Record<string, unknown>;
50
- export declare function createFileChangeAuditTurnState(requestId: string): FileChangeAuditTurnState;
51
- export declare function isFileChangeAuditReportPhase(state: FileChangeAuditTurnState | undefined): boolean;
52
- export declare function isFileChangeAuditTool(toolName: string): boolean;
53
- export declare function containsFileChangeAuditMarker(text: string): boolean;
54
- export declare function createFileChangeAuditSupport(options: FileChangeAuditSupportOptions): FileChangeAuditSupport;
45
+ export declare function createNativeFileChangeReporter(options: NativeFileChangeReporterOptions): NativeFileChangeReporter;
55
46
  export {};
56
47
  //# sourceMappingURL=file-change-audit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,8BAA8B,EAEpC,MAAM,gCAAgC,CAAC;AAMxC,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAC3E,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAChE,eAAO,MAAM,2BAA2B,yBAAyB,CAAC;AAClE,eAAO,MAAM,gCAAgC,gDAA0E,CAAC;AAKxH,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAG7D,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iCAAiC,CAAC;CAC3C,CACJ,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAC3C,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,CAAC;AAE9E,KAAK,6BAA6B,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,wBAAwB,GAAG,SAAS,CAAC;IAC3D,OAAO,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,8BAA8B,CAAC;IAC1C,cAAc,EAAE,YAAY,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,iBAAiB,EAAE,CACjB,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE,iCAAiC,KACtC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAoBF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBhF;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAE5E;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,2BAA2B,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,wBAAwB,CAK1F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAEjG;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,CAmJxB"}
1
+ {"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gCAAgC,CAAC;AAK/E,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAI3E,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAC7D,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AAGzD,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB,GACD;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iCAAiC,CAAC;CAC3C,CACJ,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAC3C,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,CAAC;AAE9E,KAAK,+BAA+B,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,OAAO,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAAC;IAC9D,MAAM,CACJ,IAAI,EAAE,0BAA0B,GAAG,IAAI,GAAG,SAAS,EACnD,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,CACJ,KAAK,EAAE,yBAAyB,GAAG,SAAS,EAC5C,MAAM,EAAE,iCAAiC,GACxC,IAAI,CAAC;CACT,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBhF;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAE5E;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,2BAA2B,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,wBAAwB,CA4F1B"}
@@ -1,32 +1,12 @@
1
- import { createSdkMcpServer, } from "@anthropic-ai/claude-agent-sdk";
2
1
  import * as fs from "node:fs";
3
2
  import * as path from "node:path";
4
- import { z } from "zod";
5
3
  import { airExtensionMeta, clientSupportsAirCapability, withAirMeta } from "./air-extension.js";
6
4
  export const AGENT_FILE_CHANGE_REPORT_CAPABILITY = "agentFileChangeReport";
7
- export const FILE_CHANGE_AUDIT_SERVER_NAME = "claude_agent_acp";
8
- export const FILE_CHANGE_AUDIT_TOOL_NAME = "report_changed_files";
9
- export const FILE_CHANGE_AUDIT_WIRE_TOOL_NAME = `mcp__${FILE_CHANGE_AUDIT_SERVER_NAME}__${FILE_CHANGE_AUDIT_TOOL_NAME}`;
10
- const FILE_CHANGE_AUDIT_MARKER = "claude-agent-acp-file-change-audit";
11
5
  const MAX_REPORTED_PATHS = 1024;
12
6
  const MAX_REPORTED_PATH_LENGTH = 4096;
13
7
  export const AGENT_FILE_CHANGE_REPORT_MAX_BYTES = 256 * 1024;
8
+ export const AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS = 2_000;
14
9
  const REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
15
- const reportInputSchema = {
16
- paths: z
17
- .array(z.string())
18
- .describe("Workspace file paths changed during this turn. Use absolute paths or paths relative to cwd."),
19
- complete: z
20
- .boolean()
21
- .describe("True only when paths contains every workspace file changed during this turn."),
22
- uncertainty: z
23
- .string()
24
- .trim()
25
- .min(1)
26
- .max(2000)
27
- .optional()
28
- .describe("Why the report may be incomplete or uncertain."),
29
- };
30
10
  export function agentFileChangeReportRequestId(meta) {
31
11
  const air = airExtensionMeta(meta);
32
12
  const request = air?.agentFileChangeReportRequest;
@@ -50,160 +30,90 @@ export function supportsAgentFileChangeReport(capabilities) {
50
30
  export function agentFileChangeReportMeta(result) {
51
31
  return withAirMeta(undefined, AGENT_FILE_CHANGE_REPORT_CAPABILITY, result);
52
32
  }
53
- export function createFileChangeAuditTurnState(requestId) {
54
- return {
55
- requestId,
56
- phase: "requested",
57
- };
58
- }
59
- export function isFileChangeAuditReportPhase(state) {
60
- return state?.phase === "collecting" || state?.phase === "finished";
61
- }
62
- export function isFileChangeAuditTool(toolName) {
63
- return toolName === FILE_CHANGE_AUDIT_WIRE_TOOL_NAME;
64
- }
65
- export function containsFileChangeAuditMarker(text) {
66
- return text.includes(`<${FILE_CHANGE_AUDIT_MARKER}>`);
67
- }
68
- export function createFileChangeAuditSupport(options) {
33
+ export function createNativeFileChangeReporter(options) {
69
34
  const workspace = normalizeWorkspace(options.cwd, options.additionalDirectories);
70
- const finishUnavailable = async (state, reason) => {
71
- // Claim the terminal outcome before the first await. The report tool, a
72
- // Stop hook, cancellation, and stream teardown can race, but only the
73
- // winner may publish for this request id. Publication remains fail-open:
74
- // an audit transport failure must never hold the user prompt open.
35
+ const timeoutMs = options.timeoutMs ?? AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS;
36
+ const requestIds = new Set();
37
+ const publish = async (state, result) => {
75
38
  if (state.phase === "finished")
76
39
  return;
77
40
  state.phase = "finished";
78
41
  try {
79
- await options.publish({
80
- version: 1,
81
- requestId: state.requestId,
82
- status: "unavailable",
83
- reason,
84
- });
42
+ await options.publish(result);
85
43
  }
86
44
  catch (error) {
87
- options.logError(`Failed to publish unavailable report ${state.requestId}: ${error}`);
45
+ options.logError(`Failed to publish file-change report ${state.requestId}: ${error}`);
88
46
  }
89
47
  };
90
- const tool = {
91
- name: FILE_CHANGE_AUDIT_TOOL_NAME,
92
- description: "Internal audit tool. Call it only when a stop-hook message explicitly requests the file-change audit.",
93
- inputSchema: reportInputSchema,
94
- _meta: {
95
- "anthropic/alwaysLoad": true,
96
- "claude/endTurn": true,
97
- },
98
- handler: async (report) => {
99
- const state = options.getActiveState();
100
- if (!state || state.phase !== "collecting") {
101
- return {
102
- isError: true,
103
- content: [
104
- {
105
- type: "text",
106
- text: `<${FILE_CHANGE_AUDIT_MARKER}>No file-change audit is active.</${FILE_CHANGE_AUDIT_MARKER}>`,
107
- },
108
- ],
109
- };
48
+ const finishUnavailable = async (state, reason) => {
49
+ await publish(state, {
50
+ version: 1,
51
+ requestId: state.requestId,
52
+ status: "unavailable",
53
+ reason,
54
+ });
55
+ };
56
+ const report = async (turn, query) => {
57
+ const state = turn?.fileChangeReport;
58
+ if (!state || state.phase !== "requested")
59
+ return;
60
+ state.phase = "collecting";
61
+ let timer;
62
+ const previewPromise = query.rewindFiles(turn.promptUuid, { dryRun: true });
63
+ // A timed-out control request may still settle later. Observe it so a late
64
+ // rejection cannot become unhandled, but never let it publish a second terminal.
65
+ void previewPromise.catch(() => { });
66
+ try {
67
+ const preview = await Promise.race([
68
+ previewPromise,
69
+ new Promise((resolve) => {
70
+ timer = setTimeout(() => resolve(null), timeoutMs);
71
+ timer.unref?.();
72
+ }),
73
+ ]);
74
+ if (preview === null) {
75
+ await finishUnavailable(state, "timeout");
76
+ return;
77
+ }
78
+ if (!preview.canRewind || !Array.isArray(preview.filesChanged)) {
79
+ await finishUnavailable(state, "invalidOutput");
80
+ return;
110
81
  }
111
- // Flip before publishing: a client transport failure must not make the
112
- // model retry the report and produce duplicates. Delivery is audit-only
113
- // and fail-open; the normal turn must still finish.
114
- state.phase = "finished";
115
- const normalized = normalizeReportedPaths(report.paths, workspace);
116
- const result = fitReportedAgentFileChangeReport({
82
+ const normalized = normalizeReportedPaths(preview.filesChanged, workspace);
83
+ await publish(state, fitReportedAgentFileChangeReport({
117
84
  version: 1,
118
85
  requestId: state.requestId,
119
86
  status: "reported",
120
87
  paths: normalized.paths,
121
- declaredComplete: report.complete && !normalized.truncated,
88
+ // Checkpoints cover Claude file tools, but not every mutation source
89
+ // (notably Bash and most subagents), so this list is never exhaustive.
90
+ declaredComplete: false,
122
91
  truncated: normalized.truncated,
123
- ...(report.uncertainty ? { uncertainty: report.uncertainty } : {}),
124
- });
125
- try {
126
- await options.publish(result);
127
- }
128
- catch (error) {
129
- options.logError(`Failed to publish file-change report ${state.requestId}: ${error}`);
130
- }
131
- return {
132
- content: [
133
- {
134
- type: "text",
135
- text: `<${FILE_CHANGE_AUDIT_MARKER}>File-change audit recorded.</${FILE_CHANGE_AUDIT_MARKER}>`,
136
- },
137
- ],
138
- structuredContent: result,
139
- };
140
- },
141
- };
142
- // canUseTool is not guaranteed to run for tools that the current permission
143
- // mode auto-allows (notably bypassPermissions). A PreToolUse hook is the
144
- // enforcement boundary that keeps the hidden continuation read-only in every
145
- // mode: it can submit the report, but cannot inspect or mutate more files.
146
- const preToolUseHook = async (input) => {
147
- if (input.hook_event_name !== "PreToolUse")
148
- return {};
149
- const state = options.getActiveState();
150
- const isReportTool = isFileChangeAuditTool(input.tool_name);
151
- if (!isReportTool && !isFileChangeAuditReportPhase(state))
152
- return {};
153
- const allowReport = state?.phase === "collecting" && isReportTool;
154
- return {
155
- hookSpecificOutput: {
156
- hookEventName: "PreToolUse",
157
- permissionDecision: allowReport ? "allow" : "deny",
158
- ...(!allowReport
159
- ? {
160
- permissionDecisionReason: "Only the internal file-change report is allowed during the audit.",
161
- }
162
- : {}),
163
- },
164
- };
165
- };
166
- const stopHook = async (input) => {
167
- if (input.hook_event_name !== "Stop")
168
- return {};
169
- const state = options.getActiveState();
170
- if (!state || state.phase === "finished")
171
- return {};
172
- // A Stop can be only a pause while a background generator is still
173
- // running. Keep the request pending so a later final Stop can include its
174
- // writes instead of declaring a prematurely complete path set.
175
- if (state.phase === "requested" && (input.background_tasks?.length ?? 0) > 0)
176
- return {};
177
- if (state.phase === "collecting" || input.stop_hook_active) {
178
- await finishUnavailable(state, "notReported");
179
- return {};
92
+ }));
93
+ }
94
+ catch (error) {
95
+ options.logError(`Failed to inspect Claude file checkpoint ${turn.promptUuid}: ${error}`);
96
+ await finishUnavailable(state, "providerError");
97
+ }
98
+ finally {
99
+ if (timer)
100
+ clearTimeout(timer);
180
101
  }
181
- // Set the phase before returning the continuation so every following SDK
182
- // message is hidden even if the next stream starts immediately.
183
- state.phase = "collecting";
184
- return {
185
- hookSpecificOutput: {
186
- hookEventName: "Stop",
187
- additionalContext: `<${FILE_CHANGE_AUDIT_MARKER}>` +
188
- `Before stopping, call ${FILE_CHANGE_AUDIT_WIRE_TOOL_NAME} exactly once. ` +
189
- "Report every workspace file changed during this user turn, including files changed " +
190
- "by commands, generators, version-control operations, and child processes. " +
191
- "Do not call any other tool and do not emit user-facing prose. " +
192
- "Set complete to false and explain uncertainty when you are not sure the list is complete." +
193
- `</${FILE_CHANGE_AUDIT_MARKER}>`,
194
- },
195
- };
196
102
  };
197
103
  return {
198
- mcpServer: createSdkMcpServer({
199
- name: FILE_CHANGE_AUDIT_SERVER_NAME,
200
- version: "1.0.0",
201
- tools: [tool],
202
- alwaysLoad: true,
203
- }),
204
- preToolUseHook,
205
- stopHook,
206
- finishUnavailable,
104
+ request(meta) {
105
+ const requestId = agentFileChangeReportRequestId(meta);
106
+ if (!requestId || requestIds.has(requestId))
107
+ return undefined;
108
+ requestIds.add(requestId);
109
+ return { requestId, phase: "requested" };
110
+ },
111
+ report,
112
+ finish(state, reason) {
113
+ if (!state)
114
+ return;
115
+ void finishUnavailable(state, reason);
116
+ },
207
117
  };
208
118
  }
209
119
  function normalizeWorkspace(cwd, additionalDirectories) {
@@ -230,7 +140,8 @@ function normalizeReportedPaths(reportedPaths, workspace) {
230
140
  let totalBytes = 0;
231
141
  let truncated = false;
232
142
  for (const reportedPath of reportedPaths) {
233
- if (reportedPath.trim().length === 0 ||
143
+ if (typeof reportedPath !== "string" ||
144
+ reportedPath.trim().length === 0 ||
234
145
  reportedPath.length > MAX_REPORTED_PATH_LENGTH ||
235
146
  hasControlCharacter(reportedPath)) {
236
147
  truncated = true;
@@ -257,9 +168,8 @@ function normalizeReportedPaths(reportedPaths, workspace) {
257
168
  truncated = true;
258
169
  continue;
259
170
  }
260
- if (seen.has(key)) {
171
+ if (seen.has(key))
261
172
  continue;
262
- }
263
173
  const pathBytes = Buffer.byteLength(normalized, "utf8");
264
174
  if (result.length >= MAX_REPORTED_PATHS ||
265
175
  totalBytes + pathBytes > AGENT_FILE_CHANGE_REPORT_MAX_BYTES) {
@@ -272,14 +182,11 @@ function normalizeReportedPaths(reportedPaths, workspace) {
272
182
  }
273
183
  return { paths: result, truncated };
274
184
  }
275
- /** Keep the complete serialized report within AIR's wire limit. */
276
185
  function fitReportedAgentFileChangeReport(report) {
277
186
  const paths = [...report.paths];
278
187
  let fitted = report;
279
188
  while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_BYTES) {
280
189
  if (paths.length === 0) {
281
- // The fixed fields and bounded uncertainty are far below the cap. Keep
282
- // this loud if the wire contract changes without updating this helper.
283
190
  throw new Error("Agent file-change report exceeds the wire limit without paths");
284
191
  }
285
192
  paths.pop();
@@ -296,18 +203,9 @@ function isWithinRoot(candidate, root) {
296
203
  const relative = path.relative(root, candidate);
297
204
  return !path.isAbsolute(relative) && !relative.startsWith(`..${path.sep}`) && relative !== "..";
298
205
  }
299
- /**
300
- * Resolve filesystem aliases in a workspace root, including macOS' /tmp ->
301
- * /private/tmp alias. For a root that does not exist yet, resolve its nearest
302
- * existing ancestor and retain the missing suffix.
303
- */
304
206
  function canonicalizeWorkspaceRoot(value) {
305
207
  return canonicalizeFromExistingAncestor(value);
306
208
  }
307
- /**
308
- * Canonicalize the parent but not the leaf itself. A changed path may be
309
- * deleted, or it may be a symlink whose node (rather than target) changed.
310
- */
311
209
  function canonicalizeReportedPath(value) {
312
210
  const parent = canonicalizeFromExistingAncestor(path.dirname(value));
313
211
  return path.resolve(parent, path.basename(value));
package/dist/tools.d.ts CHANGED
@@ -65,17 +65,6 @@ export declare function applyTaskUpdate(state: TaskState, input: TaskUpdateInput
65
65
  export declare function applyTaskList(state: TaskState, output: TaskListOutput): void;
66
66
  export declare function taskStateToPlanEntries(state: TaskState): PlanEntry[];
67
67
  export declare function markdownEscape(text: string): string;
68
- /**
69
- * Builds diff ToolUpdate content from the structured toolResponse provided by
70
- * the PostToolUse hook for diff-producing tools (Edit, Write). Unlike parsing
71
- * the plain unified diff string, this uses the pre-parsed structuredPatch
72
- * which supports multiple replacement sites (replaceAll) and always includes
73
- * context lines for better readability.
74
- */
75
- export declare function toolUpdateFromDiffToolResponse(toolResponse: unknown): {
76
- content?: ToolCallContent[];
77
- locations?: ToolCallLocation[];
78
- };
79
68
  export declare const registerHookCallback: (toolUseID: string, { onPostToolUseHook, }: {
80
69
  onPostToolUseHook?: (toolUseID: string, toolInput: unknown, toolResponse: unknown) => Promise<void>;
81
70
  }, ownerId?: string) => void;
@@ -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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"}