acp-extension-claude 0.13.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.
- package/LICENSE +222 -0
- package/README.md +53 -0
- package/dist/acp-agent.d.ts +103 -0
- package/dist/acp-agent.d.ts.map +1 -0
- package/dist/acp-agent.js +944 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/lib.d.ts +7 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +6 -0
- package/dist/mcp-server.d.ts +21 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +782 -0
- package/dist/settings.d.ts +123 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +422 -0
- package/dist/tests/acp-agent.test.d.ts +2 -0
- package/dist/tests/acp-agent.test.d.ts.map +1 -0
- package/dist/tests/acp-agent.test.js +753 -0
- package/dist/tests/extract-lines.test.d.ts +2 -0
- package/dist/tests/extract-lines.test.d.ts.map +1 -0
- package/dist/tests/extract-lines.test.js +79 -0
- package/dist/tests/replace-and-calculate-location.test.d.ts +2 -0
- package/dist/tests/replace-and-calculate-location.test.d.ts.map +1 -0
- package/dist/tests/replace-and-calculate-location.test.js +266 -0
- package/dist/tests/settings.test.d.ts +2 -0
- package/dist/tests/settings.test.d.ts.map +1 -0
- package/dist/tests/settings.test.js +462 -0
- package/dist/tests/typescript-declarations.test.d.ts +2 -0
- package/dist/tests/typescript-declarations.test.d.ts.map +1 -0
- package/dist/tests/typescript-declarations.test.js +473 -0
- package/dist/tools.d.ts +50 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +555 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +150 -0
- package/package.json +71 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import * as os from "node:os";
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("TypeScript declaration files integration", () => {
|
|
7
|
+
let tempDir;
|
|
8
|
+
let tarballPath;
|
|
9
|
+
const projectRoot = path.resolve(__dirname, "../..");
|
|
10
|
+
// Base configuration templates
|
|
11
|
+
const basePackageJson = {
|
|
12
|
+
name: "ts-declaration-test",
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
type: "module",
|
|
15
|
+
dependencies: {},
|
|
16
|
+
devDependencies: {
|
|
17
|
+
typescript: "5.9.3",
|
|
18
|
+
"@types/node": "25.0.3",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const baseTsConfig = {
|
|
22
|
+
compilerOptions: {
|
|
23
|
+
target: "ES2020",
|
|
24
|
+
module: "NodeNext",
|
|
25
|
+
moduleResolution: "NodeNext",
|
|
26
|
+
lib: ["ES2020"],
|
|
27
|
+
strict: true,
|
|
28
|
+
esModuleInterop: true,
|
|
29
|
+
skipLibCheck: true, // Skip checking dependency internals, focus on our types
|
|
30
|
+
noEmit: true,
|
|
31
|
+
declaration: false,
|
|
32
|
+
},
|
|
33
|
+
include: ["*.ts"],
|
|
34
|
+
};
|
|
35
|
+
// Build and pack the package once for all tests
|
|
36
|
+
beforeAll(async () => {
|
|
37
|
+
// Step 1: Clean dist folder to ensure fresh build
|
|
38
|
+
const distPath = path.join(projectRoot, "dist");
|
|
39
|
+
await fs.promises.rm(distPath, { recursive: true, force: true });
|
|
40
|
+
console.log("Cleaned dist folder");
|
|
41
|
+
console.log("Building package...");
|
|
42
|
+
// Step 2: Build the package
|
|
43
|
+
const buildResult = spawnSync("npm", ["run", "build"], {
|
|
44
|
+
cwd: projectRoot,
|
|
45
|
+
stdio: "pipe",
|
|
46
|
+
encoding: "utf-8",
|
|
47
|
+
});
|
|
48
|
+
if (buildResult.status !== 0) {
|
|
49
|
+
throw new Error(`Build failed: ${buildResult.stderr || buildResult.stdout}`);
|
|
50
|
+
}
|
|
51
|
+
console.log("Packing package...");
|
|
52
|
+
// Step 3: Pack to create tarball
|
|
53
|
+
const packResult = spawnSync("npm", ["pack", "--pack-destination", os.tmpdir()], {
|
|
54
|
+
cwd: projectRoot,
|
|
55
|
+
stdio: "pipe",
|
|
56
|
+
encoding: "utf-8",
|
|
57
|
+
});
|
|
58
|
+
if (packResult.status !== 0) {
|
|
59
|
+
throw new Error(`Pack failed: ${packResult.stderr || packResult.stdout}`);
|
|
60
|
+
}
|
|
61
|
+
// Get the tarball filename from stdout (npm pack outputs the filename)
|
|
62
|
+
const tarballName = packResult.stdout.trim().split("\n").pop();
|
|
63
|
+
if (!tarballName) {
|
|
64
|
+
throw new Error("Failed to get tarball name from npm pack output");
|
|
65
|
+
}
|
|
66
|
+
tarballPath = path.join(os.tmpdir(), tarballName);
|
|
67
|
+
console.log(`Tarball created at: ${tarballPath}`);
|
|
68
|
+
}, 60000); // 60 second timeout for build
|
|
69
|
+
// Clean up the tarball after all tests
|
|
70
|
+
afterAll(async () => {
|
|
71
|
+
if (tarballPath && fs.existsSync(tarballPath)) {
|
|
72
|
+
await fs.promises.unlink(tarballPath);
|
|
73
|
+
console.log("Cleaned up tarball");
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// Create fresh temp directory for each test
|
|
77
|
+
beforeEach(async () => {
|
|
78
|
+
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "ts-declaration-test-"));
|
|
79
|
+
});
|
|
80
|
+
// Clean up temp directory after each test
|
|
81
|
+
afterEach(async () => {
|
|
82
|
+
if (tempDir) {
|
|
83
|
+
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// Helper function to set up a test TypeScript project
|
|
87
|
+
async function setupTestProject(packageJson = basePackageJson, tsconfig = baseTsConfig) {
|
|
88
|
+
// Write package.json
|
|
89
|
+
await fs.promises.writeFile(path.join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
90
|
+
// Write tsconfig.json
|
|
91
|
+
await fs.promises.writeFile(path.join(tempDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
92
|
+
// Install all dependencies (TypeScript, @types/node, and the tarball)
|
|
93
|
+
console.log(`Installing dependencies in ${tempDir}...`);
|
|
94
|
+
const installResult = spawnSync("npm", ["install", tarballPath], {
|
|
95
|
+
cwd: tempDir,
|
|
96
|
+
stdio: "pipe",
|
|
97
|
+
encoding: "utf-8",
|
|
98
|
+
timeout: 60000, // 60 second timeout
|
|
99
|
+
});
|
|
100
|
+
if (installResult.status !== 0) {
|
|
101
|
+
throw new Error(`npm install failed: ${installResult.stderr || installResult.stdout}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Helper function to run TypeScript type checking
|
|
105
|
+
function runTypeCheck(srcDir = tempDir) {
|
|
106
|
+
const result = spawnSync("npx", ["tsc", "--noEmit"], {
|
|
107
|
+
cwd: srcDir,
|
|
108
|
+
stdio: "pipe",
|
|
109
|
+
encoding: "utf-8",
|
|
110
|
+
timeout: 30000, // 30 second timeout
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
success: result.status === 0,
|
|
114
|
+
output: result.stdout + result.stderr,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Helper function to write a test TypeScript file
|
|
118
|
+
async function writeTestFile(filename, content) {
|
|
119
|
+
await fs.promises.writeFile(path.join(tempDir, filename), content);
|
|
120
|
+
}
|
|
121
|
+
// Test 1: Main exports import verification
|
|
122
|
+
it("should successfully type-check main exports", async () => {
|
|
123
|
+
await setupTestProject();
|
|
124
|
+
await writeTestFile("test-main-exports.ts", `
|
|
125
|
+
import {
|
|
126
|
+
ClaudeAcpAgent,
|
|
127
|
+
runAcp,
|
|
128
|
+
toAcpNotifications,
|
|
129
|
+
streamEventToAcpNotifications,
|
|
130
|
+
SettingsManager,
|
|
131
|
+
createMcpServer,
|
|
132
|
+
loadManagedSettings,
|
|
133
|
+
applyEnvironmentSettings,
|
|
134
|
+
nodeToWebReadable,
|
|
135
|
+
nodeToWebWritable,
|
|
136
|
+
Pushable,
|
|
137
|
+
unreachable,
|
|
138
|
+
toolInfoFromToolUse,
|
|
139
|
+
planEntries,
|
|
140
|
+
toolUpdateFromToolResult,
|
|
141
|
+
createPreToolUseHook,
|
|
142
|
+
toolNames,
|
|
143
|
+
} from "@zed-industries/claude-code-acp";
|
|
144
|
+
|
|
145
|
+
// Type-only imports
|
|
146
|
+
import type {
|
|
147
|
+
ToolUpdateMeta,
|
|
148
|
+
NewSessionMeta,
|
|
149
|
+
ClaudeCodeSettings,
|
|
150
|
+
PermissionSettings,
|
|
151
|
+
PermissionDecision,
|
|
152
|
+
PermissionCheckResult,
|
|
153
|
+
SettingsManagerOptions,
|
|
154
|
+
ClaudePlanEntry,
|
|
155
|
+
} from "@zed-industries/claude-code-acp";
|
|
156
|
+
|
|
157
|
+
// Verify exports exist and have expected types
|
|
158
|
+
const _runAcp: typeof runAcp = runAcp;
|
|
159
|
+
const _createMcpServer: typeof createMcpServer = createMcpServer;
|
|
160
|
+
const _toolNames: typeof toolNames = toolNames;
|
|
161
|
+
`);
|
|
162
|
+
const result = runTypeCheck();
|
|
163
|
+
if (!result.success) {
|
|
164
|
+
console.error("TypeScript errors:", result.output);
|
|
165
|
+
}
|
|
166
|
+
expect(result.success).toBe(true);
|
|
167
|
+
}, 120000);
|
|
168
|
+
// Test 2: Deep imports verification (backwards compatibility)
|
|
169
|
+
it("should successfully type-check deep imports", async () => {
|
|
170
|
+
await setupTestProject();
|
|
171
|
+
await writeTestFile("test-deep-imports.ts", `
|
|
172
|
+
// Deep import from dist/tools.js
|
|
173
|
+
import {
|
|
174
|
+
acpToolNames,
|
|
175
|
+
EDIT_TOOL_NAMES,
|
|
176
|
+
ACP_TOOL_NAME_PREFIX,
|
|
177
|
+
toolInfoFromToolUse,
|
|
178
|
+
planEntries,
|
|
179
|
+
} from "@zed-industries/claude-code-acp/dist/tools.js";
|
|
180
|
+
|
|
181
|
+
// Deep import from dist/settings.js
|
|
182
|
+
import {
|
|
183
|
+
SettingsManager,
|
|
184
|
+
getManagedSettingsPath,
|
|
185
|
+
} from "@zed-industries/claude-code-acp/dist/settings.js";
|
|
186
|
+
|
|
187
|
+
// Deep import from dist/utils.js
|
|
188
|
+
import {
|
|
189
|
+
Pushable,
|
|
190
|
+
nodeToWebReadable,
|
|
191
|
+
nodeToWebWritable,
|
|
192
|
+
loadManagedSettings,
|
|
193
|
+
} from "@zed-industries/claude-code-acp/dist/utils.js";
|
|
194
|
+
|
|
195
|
+
// Verify types work
|
|
196
|
+
const prefix: string = ACP_TOOL_NAME_PREFIX;
|
|
197
|
+
const editTools: readonly string[] = EDIT_TOOL_NAMES;
|
|
198
|
+
`);
|
|
199
|
+
const result = runTypeCheck();
|
|
200
|
+
if (!result.success) {
|
|
201
|
+
console.error("TypeScript errors:", result.output);
|
|
202
|
+
}
|
|
203
|
+
expect(result.success).toBe(true);
|
|
204
|
+
}, 120000);
|
|
205
|
+
// Test 3: SettingsManager type shape verification
|
|
206
|
+
it("should verify SettingsManager has correct type shape", async () => {
|
|
207
|
+
await setupTestProject();
|
|
208
|
+
await writeTestFile("test-settings-manager.ts", `
|
|
209
|
+
import {
|
|
210
|
+
SettingsManager,
|
|
211
|
+
ClaudeCodeSettings,
|
|
212
|
+
PermissionCheckResult,
|
|
213
|
+
SettingsManagerOptions
|
|
214
|
+
} from "@zed-industries/claude-code-acp";
|
|
215
|
+
|
|
216
|
+
// Test constructor signature
|
|
217
|
+
const options: SettingsManagerOptions = {
|
|
218
|
+
onChange: () => {},
|
|
219
|
+
logger: { log: console.log, error: console.error },
|
|
220
|
+
};
|
|
221
|
+
declare const cwd: string;
|
|
222
|
+
const manager = new SettingsManager(cwd, options);
|
|
223
|
+
|
|
224
|
+
// Test method signatures
|
|
225
|
+
async function testMethods() {
|
|
226
|
+
// initialize returns Promise<void>
|
|
227
|
+
await manager.initialize();
|
|
228
|
+
|
|
229
|
+
// checkPermission returns PermissionCheckResult
|
|
230
|
+
const result: PermissionCheckResult = manager.checkPermission(
|
|
231
|
+
"mcp__acp__Read",
|
|
232
|
+
{ file_path: "/some/path" }
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// Verify decision type
|
|
236
|
+
const decision: "allow" | "deny" | "ask" = result.decision;
|
|
237
|
+
const rule: string | undefined = result.rule;
|
|
238
|
+
const source: "allow" | "deny" | "ask" | undefined = result.source;
|
|
239
|
+
|
|
240
|
+
// getSettings returns ClaudeCodeSettings
|
|
241
|
+
const settings: ClaudeCodeSettings = manager.getSettings();
|
|
242
|
+
|
|
243
|
+
// getCwd returns string
|
|
244
|
+
const currentCwd: string = manager.getCwd();
|
|
245
|
+
|
|
246
|
+
// setCwd returns Promise<void>
|
|
247
|
+
await manager.setCwd("/new/path");
|
|
248
|
+
|
|
249
|
+
// dispose returns void
|
|
250
|
+
manager.dispose();
|
|
251
|
+
}
|
|
252
|
+
`);
|
|
253
|
+
const result = runTypeCheck();
|
|
254
|
+
if (!result.success) {
|
|
255
|
+
console.error("TypeScript errors:", result.output);
|
|
256
|
+
}
|
|
257
|
+
expect(result.success).toBe(true);
|
|
258
|
+
}, 120000);
|
|
259
|
+
// Test 4: ClaudeAcpAgent instantiation and type verification
|
|
260
|
+
it("should verify ClaudeAcpAgent has correct type shape", async () => {
|
|
261
|
+
await setupTestProject();
|
|
262
|
+
await writeTestFile("test-claude-acp-agent.ts", `
|
|
263
|
+
import { ClaudeAcpAgent } from "@zed-industries/claude-code-acp";
|
|
264
|
+
import type { AgentSideConnection } from "@agentclientprotocol/sdk";
|
|
265
|
+
|
|
266
|
+
// ClaudeAcpAgent should be a class that can be instantiated
|
|
267
|
+
declare const mockConnection: AgentSideConnection;
|
|
268
|
+
declare const mockLogger: { log: (...args: any[]) => void; error: (...args: any[]) => void };
|
|
269
|
+
|
|
270
|
+
// Test constructor - accepts AgentSideConnection and optional logger
|
|
271
|
+
const agent = new ClaudeAcpAgent(mockConnection, mockLogger);
|
|
272
|
+
|
|
273
|
+
// Verify it has sessions property
|
|
274
|
+
const sessions: Record<string, any> = agent.sessions;
|
|
275
|
+
|
|
276
|
+
// Verify it has client property
|
|
277
|
+
const client: AgentSideConnection = agent.client;
|
|
278
|
+
|
|
279
|
+
// Verify it has logger property
|
|
280
|
+
const logger = agent.logger;
|
|
281
|
+
`);
|
|
282
|
+
const result = runTypeCheck();
|
|
283
|
+
if (!result.success) {
|
|
284
|
+
console.error("TypeScript errors:", result.output);
|
|
285
|
+
}
|
|
286
|
+
expect(result.success).toBe(true);
|
|
287
|
+
}, 120000);
|
|
288
|
+
// Test 5: Type-only exports work correctly
|
|
289
|
+
it("should verify type-only exports are usable", async () => {
|
|
290
|
+
await setupTestProject();
|
|
291
|
+
await writeTestFile("test-type-exports.ts", `
|
|
292
|
+
import type {
|
|
293
|
+
ClaudeCodeSettings,
|
|
294
|
+
PermissionSettings,
|
|
295
|
+
PermissionDecision,
|
|
296
|
+
PermissionCheckResult,
|
|
297
|
+
SettingsManagerOptions,
|
|
298
|
+
ClaudePlanEntry,
|
|
299
|
+
ToolUpdateMeta,
|
|
300
|
+
NewSessionMeta,
|
|
301
|
+
} from "@zed-industries/claude-code-acp";
|
|
302
|
+
|
|
303
|
+
// Test ClaudeCodeSettings shape
|
|
304
|
+
const settings: ClaudeCodeSettings = {
|
|
305
|
+
permissions: {
|
|
306
|
+
allow: ["Read"],
|
|
307
|
+
deny: ["Read(./.env)"],
|
|
308
|
+
ask: ["Bash"],
|
|
309
|
+
additionalDirectories: ["/extra"],
|
|
310
|
+
defaultMode: "default",
|
|
311
|
+
},
|
|
312
|
+
env: {
|
|
313
|
+
API_KEY: "secret",
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// Test PermissionSettings shape
|
|
318
|
+
const perms: PermissionSettings = {
|
|
319
|
+
allow: ["Read"],
|
|
320
|
+
deny: ["Write"],
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Test PermissionDecision
|
|
324
|
+
const decisions: PermissionDecision[] = ["allow", "deny", "ask"];
|
|
325
|
+
|
|
326
|
+
// Test ClaudePlanEntry shape
|
|
327
|
+
const planEntry: ClaudePlanEntry = {
|
|
328
|
+
content: "Do something",
|
|
329
|
+
status: "pending",
|
|
330
|
+
activeForm: "Doing something",
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// Test valid status values
|
|
334
|
+
const validStatuses: ClaudePlanEntry["status"][] = [
|
|
335
|
+
"pending",
|
|
336
|
+
"in_progress",
|
|
337
|
+
"completed",
|
|
338
|
+
];
|
|
339
|
+
|
|
340
|
+
// Test ToolUpdateMeta shape
|
|
341
|
+
const toolMeta: ToolUpdateMeta = {
|
|
342
|
+
claudeCode: {
|
|
343
|
+
toolName: "Read",
|
|
344
|
+
toolResponse: { success: true },
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// Test NewSessionMeta shape
|
|
349
|
+
const sessionMeta: NewSessionMeta = {
|
|
350
|
+
claudeCode: {
|
|
351
|
+
options: {},
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
`);
|
|
355
|
+
const result = runTypeCheck();
|
|
356
|
+
if (!result.success) {
|
|
357
|
+
console.error("TypeScript errors:", result.output);
|
|
358
|
+
}
|
|
359
|
+
expect(result.success).toBe(true);
|
|
360
|
+
}, 120000);
|
|
361
|
+
// Test 6: Function signatures verification
|
|
362
|
+
it("should verify function signatures are correct", async () => {
|
|
363
|
+
await setupTestProject();
|
|
364
|
+
await writeTestFile("test-function-signatures.ts", `
|
|
365
|
+
import {
|
|
366
|
+
runAcp,
|
|
367
|
+
createMcpServer,
|
|
368
|
+
toolInfoFromToolUse,
|
|
369
|
+
planEntries,
|
|
370
|
+
createPreToolUseHook,
|
|
371
|
+
loadManagedSettings,
|
|
372
|
+
applyEnvironmentSettings,
|
|
373
|
+
SettingsManager,
|
|
374
|
+
} from "@zed-industries/claude-code-acp";
|
|
375
|
+
|
|
376
|
+
import type { ClaudeCodeSettings } from "@zed-industries/claude-code-acp";
|
|
377
|
+
|
|
378
|
+
// runAcp should be a function with no parameters that returns void
|
|
379
|
+
const runAcpType: () => void = runAcp;
|
|
380
|
+
|
|
381
|
+
// toolInfoFromToolUse should accept any and return object with title and kind
|
|
382
|
+
const info = toolInfoFromToolUse({ name: "Read", input: {} });
|
|
383
|
+
const title: string = info.title;
|
|
384
|
+
const kind: string = info.kind;
|
|
385
|
+
|
|
386
|
+
// planEntries should accept todos array and return array
|
|
387
|
+
const entries = planEntries({
|
|
388
|
+
todos: [
|
|
389
|
+
{ content: "test", status: "pending", activeForm: "testing" }
|
|
390
|
+
]
|
|
391
|
+
});
|
|
392
|
+
// entries should be an array
|
|
393
|
+
const entriesArray: any[] = entries;
|
|
394
|
+
|
|
395
|
+
// createPreToolUseHook should accept SettingsManager and optional logger
|
|
396
|
+
declare const settingsManager: SettingsManager;
|
|
397
|
+
const hook = createPreToolUseHook(settingsManager, console);
|
|
398
|
+
|
|
399
|
+
// loadManagedSettings should return ClaudeCodeSettings | null
|
|
400
|
+
const managedSettings: ClaudeCodeSettings | null = loadManagedSettings();
|
|
401
|
+
|
|
402
|
+
// applyEnvironmentSettings should accept ClaudeCodeSettings and return void
|
|
403
|
+
const applyResult: void = applyEnvironmentSettings({ permissions: {} });
|
|
404
|
+
`);
|
|
405
|
+
const result = runTypeCheck();
|
|
406
|
+
if (!result.success) {
|
|
407
|
+
console.error("TypeScript errors:", result.output);
|
|
408
|
+
}
|
|
409
|
+
expect(result.success).toBe(true);
|
|
410
|
+
}, 120000);
|
|
411
|
+
// Test 7: Pushable generic class verification
|
|
412
|
+
it("should verify Pushable class works correctly", async () => {
|
|
413
|
+
await setupTestProject();
|
|
414
|
+
await writeTestFile("test-pushable.ts", `
|
|
415
|
+
import { Pushable } from "@zed-industries/claude-code-acp";
|
|
416
|
+
|
|
417
|
+
// Pushable should be a generic class
|
|
418
|
+
const pushable = new Pushable<string>();
|
|
419
|
+
|
|
420
|
+
// Should have push method
|
|
421
|
+
pushable.push("test");
|
|
422
|
+
|
|
423
|
+
// Should have end method
|
|
424
|
+
pushable.end();
|
|
425
|
+
|
|
426
|
+
// Should implement AsyncIterable
|
|
427
|
+
async function consume() {
|
|
428
|
+
for await (const item of pushable) {
|
|
429
|
+
const str: string = item;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Generic type parameter should work
|
|
434
|
+
const numPushable = new Pushable<number>();
|
|
435
|
+
numPushable.push(42);
|
|
436
|
+
|
|
437
|
+
interface MyType { id: number; name: string; }
|
|
438
|
+
const customPushable = new Pushable<MyType>();
|
|
439
|
+
customPushable.push({ id: 1, name: "test" });
|
|
440
|
+
`);
|
|
441
|
+
const result = runTypeCheck();
|
|
442
|
+
if (!result.success) {
|
|
443
|
+
console.error("TypeScript errors:", result.output);
|
|
444
|
+
}
|
|
445
|
+
expect(result.success).toBe(true);
|
|
446
|
+
}, 120000);
|
|
447
|
+
// Test 8: Verify incorrect types fail
|
|
448
|
+
it("should fail type-check with incorrect types", async () => {
|
|
449
|
+
await setupTestProject();
|
|
450
|
+
await writeTestFile("test-invalid-types.ts", `
|
|
451
|
+
import { SettingsManager, ClaudeCodeSettings } from "@zed-industries/claude-code-acp";
|
|
452
|
+
|
|
453
|
+
// This should fail - SettingsManager constructor requires string cwd
|
|
454
|
+
// @ts-expect-error - Testing that wrong argument type fails
|
|
455
|
+
const badManager = new SettingsManager(123);
|
|
456
|
+
|
|
457
|
+
// This should fail - ClaudeCodeSettings permissions must be an object
|
|
458
|
+
const badSettings: ClaudeCodeSettings = {
|
|
459
|
+
// @ts-expect-error - Testing that wrong type fails
|
|
460
|
+
permissions: "not-an-object",
|
|
461
|
+
};
|
|
462
|
+
`);
|
|
463
|
+
// This test should PASS because we expect tsc to catch these errors
|
|
464
|
+
// with @ts-expect-error directives
|
|
465
|
+
const result = runTypeCheck();
|
|
466
|
+
if (!result.success) {
|
|
467
|
+
// If it fails, it means @ts-expect-error didn't catch the error
|
|
468
|
+
// which could mean the types are too permissive
|
|
469
|
+
console.error("TypeScript errors (expected @ts-expect-error to catch):", result.output);
|
|
470
|
+
}
|
|
471
|
+
expect(result.success).toBe(true);
|
|
472
|
+
}, 120000);
|
|
473
|
+
});
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PlanEntry, ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk";
|
|
2
|
+
import { ToolResultBlockParam, WebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources";
|
|
3
|
+
export declare const ACP_TOOL_NAME_PREFIX = "mcp__acp__";
|
|
4
|
+
export declare const acpToolNames: {
|
|
5
|
+
read: string;
|
|
6
|
+
edit: string;
|
|
7
|
+
write: string;
|
|
8
|
+
bash: string;
|
|
9
|
+
killShell: string;
|
|
10
|
+
bashOutput: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const EDIT_TOOL_NAMES: string[];
|
|
13
|
+
import { BetaBashCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultBlockParam, BetaRequestMCPToolResultBlockParam, BetaTextEditorCodeExecutionToolResultBlockParam, BetaToolSearchToolResultBlockParam, BetaWebFetchToolResultBlockParam, BetaWebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
14
|
+
import { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
15
|
+
import { Logger } from "./acp-agent.js";
|
|
16
|
+
import { SettingsManager } from "./settings.js";
|
|
17
|
+
interface ToolInfo {
|
|
18
|
+
title: string;
|
|
19
|
+
kind: ToolKind;
|
|
20
|
+
content: ToolCallContent[];
|
|
21
|
+
locations?: ToolCallLocation[];
|
|
22
|
+
}
|
|
23
|
+
interface ToolUpdate {
|
|
24
|
+
title?: string;
|
|
25
|
+
content?: ToolCallContent[];
|
|
26
|
+
locations?: ToolCallLocation[];
|
|
27
|
+
}
|
|
28
|
+
export declare function toolInfoFromToolUse(toolUse: any): ToolInfo;
|
|
29
|
+
export declare function toolUpdateFromToolResult(toolResult: ToolResultBlockParam | BetaWebSearchToolResultBlockParam | BetaWebFetchToolResultBlockParam | WebSearchToolResultBlockParam | BetaCodeExecutionToolResultBlockParam | BetaBashCodeExecutionToolResultBlockParam | BetaTextEditorCodeExecutionToolResultBlockParam | BetaRequestMCPToolResultBlockParam | BetaToolSearchToolResultBlockParam, toolUse: any | undefined): ToolUpdate;
|
|
30
|
+
export type ClaudePlanEntry = {
|
|
31
|
+
content: string;
|
|
32
|
+
status: "pending" | "in_progress" | "completed";
|
|
33
|
+
activeForm: string;
|
|
34
|
+
};
|
|
35
|
+
export declare function planEntries(input: {
|
|
36
|
+
todos: ClaudePlanEntry[];
|
|
37
|
+
}): PlanEntry[];
|
|
38
|
+
export declare function markdownEscape(text: string): string;
|
|
39
|
+
export declare const registerHookCallback: (toolUseID: string, { onPostToolUseHook, }: {
|
|
40
|
+
onPostToolUseHook?: (toolUseID: string, toolInput: unknown, toolResponse: unknown) => Promise<void>;
|
|
41
|
+
}) => void;
|
|
42
|
+
export declare const createPostToolUseHook: (logger?: Logger) => HookCallback;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a PreToolUse hook that checks permissions using the SettingsManager.
|
|
45
|
+
* This runs before the SDK's built-in permission rules, allowing us to enforce
|
|
46
|
+
* our own permission settings for ACP-prefixed tools.
|
|
47
|
+
*/
|
|
48
|
+
export declare const createPreToolUseHook: (settingsManager: SettingsManager, logger?: Logger) => HookCallback;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGlG,OAAO,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAWlG,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,YAAY;;;;;;;CAOxB,CAAC;AAEF,eAAO,MAAM,eAAe,UAA0C,CAAC;AAEvE,OAAO,EACL,yCAAyC,EACzC,qCAAqC,EACrC,kCAAkC,EAClC,+CAA+C,EAC/C,kCAAkC,EAClC,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,CA+V1D;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EACN,oBAAoB,GACpB,iCAAiC,GACjC,gCAAgC,GAChC,6BAA6B,GAC7B,qCAAqC,GACrC,yCAAyC,GACzC,+CAA+C,GAC/C,kCAAkC,GAClC,kCAAkC,EACtC,OAAO,EAAE,GAAG,GAAG,SAAS,GACvB,UAAU,CA4HZ;AAmCD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,eAAe,EAAE,CAAA;CAAE,GAAG,SAAS,EAAE,CAM5E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAcD,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,EACjB,wBAEG;IACD,iBAAiB,CAAC,EAAE,CAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,EAClB,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,SAKF,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAC/B,SAAQ,MAAgB,KAAG,YAa3B,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC9B,iBAAiB,eAAe,EAAE,SAAQ,MAAgB,KAAG,YA2C7D,CAAC"}
|