@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.
- package/dist/acp-agent.d.ts +14 -18
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +83 -214
- package/dist/air-extension.d.ts +1 -0
- package/dist/air-extension.d.ts.map +1 -1
- package/dist/air-extension.js +1 -0
- package/dist/diff.d.ts +13 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +131 -0
- package/dist/file-change-audit.d.ts +15 -24
- package/dist/file-change-audit.d.ts.map +1 -1
- package/dist/file-change-audit.js +70 -172
- package/dist/tools.d.ts +0 -11
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +0 -73
- package/package.json +1 -1
package/dist/air-extension.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/air-extension.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
45
|
+
options.logError(`Failed to publish file-change report ${state.requestId}: ${error}`);
|
|
88
46
|
}
|
|
89
47
|
};
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
112
|
-
|
|
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
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
|
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;
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -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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"}
|