mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 12:40:32 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44bb150b5d | ||
|
|
18bd9f2490 | ||
|
|
b8e655d7ac | ||
|
|
0e77751692 |
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 0.17.1
|
||||
|
||||
- Update to @anthropic-ai/claude-agent-sdk@0.2.45 to add access to Sonnet 4.6
|
||||
|
||||
## 0.17.0
|
||||
|
||||
Rename from `@zed-industries/claude-code-acp` to `@zed-industries/claude-agent-acp` to align with the current [branding guidelines](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines)
|
||||
|
||||
## 0.16.2
|
||||
|
||||
- Update to @anthropic-ai/claude-agent-sdk@0.2.44
|
||||
|
||||
14
README.md
14
README.md
@@ -1,8 +1,8 @@
|
||||
# ACP adapter for Claude Code
|
||||
# ACP adapter for the Claude Agent SDK
|
||||
|
||||
[](https://www.npmjs.com/package/@zed-industries/claude-code-acp)
|
||||
[](https://www.npmjs.com/package/@zed-industries/claude-agent-acp)
|
||||
|
||||
Use [Claude Code](https://www.anthropic.com/claude-code) from [ACP-compatible](https://agentclientprotocol.com) clients such as [Zed](https://zed.dev)!
|
||||
Use [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines) from [ACP-compatible](https://agentclientprotocol.com) clients such as [Zed](https://zed.dev)!
|
||||
|
||||
This tool implements an ACP agent by using the official [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), supporting:
|
||||
|
||||
@@ -24,7 +24,7 @@ Learn more about the [Agent Client Protocol](https://agentclientprotocol.com/).
|
||||
|
||||
The latest version of Zed can already use this adapter out of the box.
|
||||
|
||||
To use Claude Code, open the Agent Panel and click "New Claude Code Thread" from the `+` button menu in the top-right:
|
||||
To use Claude Agent, open the Agent Panel and click "New Claude Agent Thread" from the `+` button menu in the top-right:
|
||||
|
||||
https://github.com/user-attachments/assets/ddce66c7-79ac-47a3-ad59-4a6a3ca74903
|
||||
|
||||
@@ -39,13 +39,13 @@ Or try it with any of the other [ACP compatible clients](https://agentclientprot
|
||||
Install the adapter from `npm`:
|
||||
|
||||
```bash
|
||||
npm install -g @zed-industries/claude-code-acp
|
||||
npm install -g @zed-industries/claude-agent-acp
|
||||
```
|
||||
|
||||
You can then use `claude-code-acp` as a regular ACP agent:
|
||||
You can then use `claude-agent-acp` as a regular ACP agent:
|
||||
|
||||
```
|
||||
ANTHROPIC_API_KEY=sk-... claude-code-acp
|
||||
ANTHROPIC_API_KEY=sk-... claude-agent-acp
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
26
package-lock.json
generated
26
package-lock.json
generated
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "@zed-industries/claude-code-acp",
|
||||
"version": "0.16.2",
|
||||
"name": "@zed-industries/claude-agent-acp",
|
||||
"version": "0.17.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@zed-industries/claude-code-acp",
|
||||
"version": "0.16.2",
|
||||
"name": "@zed-industries/claude-agent-acp",
|
||||
"version": "0.17.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "0.14.1",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.2.44",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.2.45",
|
||||
"@modelcontextprotocol/sdk": "1.26.0",
|
||||
"diff": "8.0.3",
|
||||
"minimatch": "10.2.1"
|
||||
},
|
||||
"bin": {
|
||||
"claude-code-acp": "dist/index.js"
|
||||
"claude-agent-acp": "dist/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anthropic-ai/sdk": "0.74.0",
|
||||
"@anthropic-ai/sdk": "0.75.0",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@types/node": "25.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "8.56.0",
|
||||
@@ -43,9 +43,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk": {
|
||||
"version": "0.2.44",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.44.tgz",
|
||||
"integrity": "sha512-bryUo6qq5dalO4MmhYLTPonTOAmdSVpMaVLJl8Y0qm6M7G+NZ3WS4cTMGrTbz97Uz5nah+FIOMA4hh8sKLm3YQ==",
|
||||
"version": "0.2.45",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.45.tgz",
|
||||
"integrity": "sha512-AKH2hKoJNyjLf9ThAttKqbmCjUFg7qs/8+LR/UTVX20fCLn359YH9WrQc6dAiAfi8RYNA+mWwrNYCAq+Sdo5Ag==",
|
||||
"license": "SEE LICENSE IN README.md",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
@@ -65,9 +65,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk": {
|
||||
"version": "0.74.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.74.0.tgz",
|
||||
"integrity": "sha512-srbJV7JKsc5cQ6eVuFzjZO7UR3xEPJqPamHFIe29bs38Ij2IripoAhC0S5NslNbaFUYqBKypmmpzMTpqfHEUDw==",
|
||||
"version": "0.75.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.75.0.tgz",
|
||||
"integrity": "sha512-Xr/BESTYMOnpyOK7Gxie2LWc+G5f9+xZEYVAuWtDdYDtINocoe046gszFMeRJZ2FfySyGxdF3OHKYwB6/+p4uQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
18
package.json
18
package.json
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "@zed-industries/claude-code-acp",
|
||||
"name": "@zed-industries/claude-agent-acp",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "0.16.2",
|
||||
"description": "An ACP-compatible coding agent powered by the Claude Code SDK (TypeScript)",
|
||||
"version": "0.17.1",
|
||||
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
||||
"main": "dist/lib.js",
|
||||
"types": "dist/lib.d.ts",
|
||||
"bin": {
|
||||
"claude-code-acp": "./dist/index.js"
|
||||
"claude-agent-acp": "dist/index.js"
|
||||
},
|
||||
"type": "module",
|
||||
"exports": {
|
||||
@@ -49,25 +49,25 @@
|
||||
"sdk",
|
||||
"code"
|
||||
],
|
||||
"homepage": "https://github.com/zed-industries/claude-code-acp#readme",
|
||||
"homepage": "https://github.com/zed-industries/claude-agent-acp#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/zed-industries/claude-code-acp/issues"
|
||||
"url": "https://github.com/zed-industries/claude-agent-acp/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zed-industries/claude-code-acp.git"
|
||||
"url": "git+https://github.com/zed-industries/claude-agent-acp.git"
|
||||
},
|
||||
"author": "Zed Industries",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "0.14.1",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.2.44",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.2.45",
|
||||
"@modelcontextprotocol/sdk": "1.26.0",
|
||||
"diff": "8.0.3",
|
||||
"minimatch": "10.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anthropic-ai/sdk": "0.74.0",
|
||||
"@anthropic-ai/sdk": "0.75.0",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@types/node": "25.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "8.56.0",
|
||||
|
||||
@@ -44,8 +44,23 @@ import {
|
||||
PermissionMode,
|
||||
Query,
|
||||
query,
|
||||
SDKAssistantMessage,
|
||||
SDKAuthStatusMessage,
|
||||
SDKCompactBoundaryMessage,
|
||||
SDKFilesPersistedEvent,
|
||||
SDKHookProgressMessage,
|
||||
SDKHookResponseMessage,
|
||||
SDKHookStartedMessage,
|
||||
SDKPartialAssistantMessage,
|
||||
SDKResultMessage,
|
||||
SDKStatusMessage,
|
||||
SDKSystemMessage,
|
||||
SDKTaskNotificationMessage,
|
||||
SDKTaskStartedMessage,
|
||||
SDKToolProgressMessage,
|
||||
SDKToolUseSummaryMessage,
|
||||
SDKUserMessage,
|
||||
SDKUserMessageReplay,
|
||||
SlashCommand,
|
||||
} from "@anthropic-ai/claude-agent-sdk";
|
||||
import * as fs from "node:fs";
|
||||
@@ -76,6 +91,26 @@ import packageJson from "../package.json" with { type: "json" };
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
// SDK has an unresolved rate limit type, reconstructing with the rest for now
|
||||
type SDKMessageTemp =
|
||||
| SDKAssistantMessage
|
||||
| SDKUserMessage
|
||||
| SDKUserMessageReplay
|
||||
| SDKResultMessage
|
||||
| SDKSystemMessage
|
||||
| SDKPartialAssistantMessage
|
||||
| SDKCompactBoundaryMessage
|
||||
| SDKStatusMessage
|
||||
| SDKHookStartedMessage
|
||||
| SDKHookProgressMessage
|
||||
| SDKHookResponseMessage
|
||||
| SDKToolProgressMessage
|
||||
| SDKAuthStatusMessage
|
||||
| SDKTaskNotificationMessage
|
||||
| SDKTaskStartedMessage
|
||||
| SDKFilesPersistedEvent
|
||||
| SDKToolUseSummaryMessage;
|
||||
|
||||
export const CLAUDE_CONFIG_DIR =
|
||||
process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
|
||||
|
||||
@@ -136,7 +171,7 @@ type BackgroundTerminal =
|
||||
};
|
||||
|
||||
/**
|
||||
* Extra metadata that can be given to Claude Code when creating a new session.
|
||||
* Extra metadata that can be given when creating a new session.
|
||||
*/
|
||||
export type NewSessionMeta = {
|
||||
claudeCode?: {
|
||||
@@ -207,7 +242,7 @@ export class ClaudeAcpAgent implements Agent {
|
||||
// Default authMethod
|
||||
const authMethod: any = {
|
||||
description: "Run `claude /login` in the terminal",
|
||||
name: "Log in with Claude Code",
|
||||
name: "Log in with Claude",
|
||||
id: "claude-login",
|
||||
};
|
||||
|
||||
@@ -219,7 +254,7 @@ export class ClaudeAcpAgent implements Agent {
|
||||
"terminal-auth": {
|
||||
command: "node",
|
||||
args: [cliPath],
|
||||
label: "Claude Code Login",
|
||||
label: "Claude Login",
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -244,7 +279,7 @@ export class ClaudeAcpAgent implements Agent {
|
||||
},
|
||||
agentInfo: {
|
||||
name: packageJson.name,
|
||||
title: "Claude Code",
|
||||
title: "Claude Agent",
|
||||
version: packageJson.version,
|
||||
},
|
||||
authMethods: [authMethod],
|
||||
@@ -555,7 +590,8 @@ export class ClaudeAcpAgent implements Agent {
|
||||
|
||||
input.push(promptToClaude(params));
|
||||
while (true) {
|
||||
const { value: message, done } = await query.next();
|
||||
const { value: message, done } = await (query as AsyncGenerator<SDKMessageTemp, void>).next();
|
||||
|
||||
if (done || !message) {
|
||||
if (this.sessions[params.sessionId].cancelled) {
|
||||
return { stopReason: "cancelled" };
|
||||
@@ -575,6 +611,7 @@ export class ClaudeAcpAgent implements Agent {
|
||||
case "hook_response":
|
||||
case "status":
|
||||
case "files_persisted":
|
||||
case "task_started":
|
||||
// Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
|
||||
break;
|
||||
default:
|
||||
@@ -1511,7 +1548,7 @@ export function toAcpNotifications(
|
||||
});
|
||||
} else {
|
||||
logger.error(
|
||||
`[claude-code-acp] Got a tool response for tool use that wasn't tracked: ${toolUseId}`,
|
||||
`[claude-agent-acp] Got a tool response for tool use that wasn't tracked: ${toolUseId}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -1551,7 +1588,7 @@ export function toAcpNotifications(
|
||||
const toolUse = toolUseCache[chunk.tool_use_id];
|
||||
if (!toolUse) {
|
||||
logger.error(
|
||||
`[claude-code-acp] Got a tool result for tool use that wasn't tracked: ${chunk.tool_use_id}`,
|
||||
`[claude-agent-acp] Got a tool result for tool use that wasn't tracked: ${chunk.tool_use_id}`,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -325,13 +325,13 @@ describe("tool conversions", () => {
|
||||
id: "toolu_01EEqsX7Eb9hpx87KAHVPTey",
|
||||
name: "LS",
|
||||
input: {
|
||||
path: "/Users/test/github/claude-code-acp",
|
||||
path: "/Users/test/github/claude-agent-acp",
|
||||
},
|
||||
};
|
||||
|
||||
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
||||
kind: "search",
|
||||
title: "List the `/Users/test/github/claude-code-acp` directory's contents",
|
||||
title: "List the `/Users/test/github/claude-agent-acp` directory's contents",
|
||||
content: [],
|
||||
locations: [],
|
||||
});
|
||||
|
||||
@@ -241,7 +241,7 @@ describe("unstable_listSessions", () => {
|
||||
});
|
||||
|
||||
it("returns the true cwd for paths containing hyphens", async () => {
|
||||
const cwd = "/Users/test/claude-code-acp";
|
||||
const cwd = "/Users/test/claude-agent-acp";
|
||||
writeSessionFile(cwd, "hyphen-session", { userMessage: "Hyphen test" });
|
||||
|
||||
const result = await agent.unstable_listSessions({});
|
||||
@@ -252,14 +252,14 @@ describe("unstable_listSessions", () => {
|
||||
});
|
||||
|
||||
it("filters hyphenated paths by cwd correctly", async () => {
|
||||
writeSessionFile("/Users/test/claude-code-acp", "hyphen-a", { userMessage: "A" });
|
||||
writeSessionFile("/Users/test/claude-agent-acp", "hyphen-a", { userMessage: "A" });
|
||||
writeSessionFile("/Users/test/other-project", "hyphen-b", { userMessage: "B" });
|
||||
|
||||
const result = await agent.unstable_listSessions({ cwd: "/Users/test/claude-code-acp" });
|
||||
const result = await agent.unstable_listSessions({ cwd: "/Users/test/claude-agent-acp" });
|
||||
|
||||
expect(result.sessions).toHaveLength(1);
|
||||
expect(result.sessions[0]!.sessionId).toBe("hyphen-a");
|
||||
expect(result.sessions[0]!.cwd).toBe("/Users/test/claude-code-acp");
|
||||
expect(result.sessions[0]!.cwd).toBe("/Users/test/claude-agent-acp");
|
||||
});
|
||||
|
||||
it("returns all sessions when cwd is not specified", async () => {
|
||||
|
||||
@@ -180,7 +180,7 @@ import {
|
||||
toolUpdateFromToolResult,
|
||||
createPreToolUseHook,
|
||||
toolNames,
|
||||
} from "@zed-industries/claude-code-acp";
|
||||
} from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// Type-only imports
|
||||
import type {
|
||||
@@ -192,7 +192,7 @@ import type {
|
||||
PermissionCheckResult,
|
||||
SettingsManagerOptions,
|
||||
ClaudePlanEntry,
|
||||
} from "@zed-industries/claude-code-acp";
|
||||
} from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// Verify exports exist and have expected types
|
||||
const _runAcp: typeof runAcp = runAcp;
|
||||
@@ -222,13 +222,13 @@ import {
|
||||
ACP_TOOL_NAME_PREFIX,
|
||||
toolInfoFromToolUse,
|
||||
planEntries,
|
||||
} from "@zed-industries/claude-code-acp/dist/tools.js";
|
||||
} from "@zed-industries/claude-agent-acp/dist/tools.js";
|
||||
|
||||
// Deep import from dist/settings.js
|
||||
import {
|
||||
SettingsManager,
|
||||
getManagedSettingsPath,
|
||||
} from "@zed-industries/claude-code-acp/dist/settings.js";
|
||||
} from "@zed-industries/claude-agent-acp/dist/settings.js";
|
||||
|
||||
// Deep import from dist/utils.js
|
||||
import {
|
||||
@@ -236,7 +236,7 @@ import {
|
||||
nodeToWebReadable,
|
||||
nodeToWebWritable,
|
||||
loadManagedSettings,
|
||||
} from "@zed-industries/claude-code-acp/dist/utils.js";
|
||||
} from "@zed-industries/claude-agent-acp/dist/utils.js";
|
||||
|
||||
// Verify types work
|
||||
const prefix: string = ACP_TOOL_NAME_PREFIX;
|
||||
@@ -263,7 +263,7 @@ import {
|
||||
ClaudeCodeSettings,
|
||||
PermissionCheckResult,
|
||||
SettingsManagerOptions
|
||||
} from "@zed-industries/claude-code-acp";
|
||||
} from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// Test constructor signature
|
||||
const options: SettingsManagerOptions = {
|
||||
@@ -318,7 +318,7 @@ async function testMethods() {
|
||||
await writeTestFile(
|
||||
"test-claude-acp-agent.ts",
|
||||
`
|
||||
import { ClaudeAcpAgent } from "@zed-industries/claude-code-acp";
|
||||
import { ClaudeAcpAgent } from "@zed-industries/claude-agent-acp";
|
||||
import type { AgentSideConnection } from "@agentclientprotocol/sdk";
|
||||
|
||||
// ClaudeAcpAgent should be a class that can be instantiated
|
||||
@@ -362,7 +362,7 @@ import type {
|
||||
ClaudePlanEntry,
|
||||
ToolUpdateMeta,
|
||||
NewSessionMeta,
|
||||
} from "@zed-industries/claude-code-acp";
|
||||
} from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// Test ClaudeCodeSettings shape
|
||||
const settings: ClaudeCodeSettings = {
|
||||
@@ -441,9 +441,9 @@ import {
|
||||
loadManagedSettings,
|
||||
applyEnvironmentSettings,
|
||||
SettingsManager,
|
||||
} from "@zed-industries/claude-code-acp";
|
||||
} from "@zed-industries/claude-agent-acp";
|
||||
|
||||
import type { ClaudeCodeSettings } from "@zed-industries/claude-code-acp";
|
||||
import type { ClaudeCodeSettings } from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// runAcp should be a function with no parameters that returns void
|
||||
const runAcpType: () => void = runAcp;
|
||||
@@ -488,7 +488,7 @@ const applyResult: void = applyEnvironmentSettings({ permissions: {} });
|
||||
await writeTestFile(
|
||||
"test-pushable.ts",
|
||||
`
|
||||
import { Pushable } from "@zed-industries/claude-code-acp";
|
||||
import { Pushable } from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// Pushable should be a generic class
|
||||
const pushable = new Pushable<string>();
|
||||
@@ -530,7 +530,7 @@ customPushable.push({ id: 1, name: "test" });
|
||||
await writeTestFile(
|
||||
"test-invalid-types.ts",
|
||||
`
|
||||
import { SettingsManager, ClaudeCodeSettings } from "@zed-industries/claude-code-acp";
|
||||
import { SettingsManager, ClaudeCodeSettings } from "@zed-industries/claude-agent-acp";
|
||||
|
||||
// This should fail - SettingsManager constructor requires string cwd
|
||||
// @ts-expect-error - Testing that wrong argument type fails
|
||||
|
||||
Reference in New Issue
Block a user