mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-11-13 21:02:08 +00:00
## Summary
Updates `@anthropic-ai/claude-agent-sdk` from 0.3.322 to 0.3.323, which
bundles Claude Code 2.1.323. The new version needs two adapter fixes,
both included here:
- the session index reads titles by the SDK's new rule;
- the heartbeat of a long-running hook no longer lands on a tool call.
Also bumps these dev dependencies: `@anthropic-ai/sdk` 1.7.0 → 1.8.0,
`@tsconfig/node22` 22.0.6 → 22.0.7 and `prettier` 3.9.10 → 3.10.1.
`npm update` brings the in-range lockfile bumps: `rolldown` 1.2.18 →
1.2.19, `vite` 8.3.7 → 8.3.8, `hono` 4.13.17 → 4.13.18,
`@hono/node-server` 2.1.6 → 2.1.8, and patch releases of
`@babel/runtime`, `brace-expansion`, `encodeurl`,
`@jridgewell/resolve-uri` and `@rolldown/pluginutils`. `rolldown` 1.2.19
lists its wasm32 binding as an optional dependency, so the lockfile
gains `@rolldown/binding-wasm32-wasi`, `@napi-rs/wasm-runtime`,
`@emnapi/core` and `@emnapi/runtime` (2.0.0-beta.2),
`@emnapi/wasi-threads`, `@tybys/wasm-util` and `tslib`. All are dev-only
and optional.
TypeScript stays at 6.0.3: 7.0.2 is out, but `@typescript-eslint/parser`
8.72.2 still requires `typescript <6.1.0`.
## Session titles
`getSessionInfo` and `listSessions` of SDK 0.3.323 read titles
differently, and neither changelog says so. The session index mirrors
the SDK's rule (`sdkTitles` in `src/session-index/transcript-scan.ts`),
so it has to follow.
- Before: the SDK took the last `"customTitle":"…"` text of the tail or
the head, wherever it stood.
- Now: it parses each line that names the field, from the last one back,
and takes the top-level string of the record. For `customTitle` and
`aiTitle` the record must be of type `custom-title` or `ai-title`.
`lastPrompt` and `summary` may be on a record of any type.
What changes for a client:
- A `customTitle` or `lastPrompt` inside a message is no title. A tool
result that shows a transcript no longer renames the session.
- A `custom-title` record that the start of the 64 KB tail window cuts
is not read. The old rule still found its title text.
- A `custom-title` record appended to a line whose write was cut off is
read.
Checked against the real SDK: a differential run of `sdkTitles` against
`getSessionInfo` over 1,800 generated transcripts gave no mismatch. The
old rule mismatched on 371 of 600. The run is not part of this PR; the
tests in `src/tests/v1/session-index.test.ts` compare each case above
with `getSessionInfo`.
## Hook heartbeats
Since Claude Code 2.1.323, a hook that runs long sends a `tool_progress`
beat every 30 seconds. Recorded from the real CLI:
```json
{
"type": "tool_progress",
"tool_use_id": "hook-PreToolUse-toolu_01X…-heartbeat-0",
"tool_name": "PreToolUse",
"parent_tool_use_id": "toolu_01X…",
"elapsed_time_seconds": 30,
"heartbeat": true
}
```
For a PreToolUse or PostToolUse hook, `parent_tool_use_id` is the tool
call. For a UserPromptSubmit or Stop hook it is an id that names no tool
call. The PostToolUse beats come before the tool result.
Both cores send a beat under an unknown id to the call that
`parent_tool_use_id` names. So without a change, a slow PreToolUse or
PostToolUse hook:
- marked the tool call `in_progress` before it ran, on v1 and v2;
- restarted its elapsed time with the hook's (30 → 1 → 2 → 3 → 30 in the
scenario);
- named the call `PreToolUse` in `_meta.claudeCode.toolName` for a plain
or Zed client.
The adapter now drops these beats. This matches how it already ignores
`hook_started`, `hook_progress` and `hook_response`: hooks have no ACP
surface. The rule that picks the tool call of a beat was written twice,
in `src/v1/acp-agent.ts` and `src/v2/stream.ts`. It is now one function,
`progressToolCallId` in `src/tool-calls/renderer.ts`, which holds the
new rule too.
The `tool-progress` scenario carries a PreToolUse and a PostToolUse
beat. Its recordings for the plain, Zed, AIR and v2 clients are
unchanged, and all four fail without the fix.
## Changelog review
Read the SDK changelog for 0.3.323 and the Claude Code changelog for
2.1.323. No other entry needs a code change:
- **Types.** Doc text and new optional members only, plus one new
`SDKStartupFailureReason` (`managed_settings_not_delivered`).
`startupFailureError` treats a reason it does not list as an internal
error with the CLI's message.
- **Context window of an unknown model id**, 200K → 1M. The adapter
reads the window from Claude Code (`getContextUsage`) at session
creation and at every model switch, so it reports the new value. Its own
200K is only the placeholder until that read lands.
- **`canUseTool` suggestions** no longer hold a Bash allow rule for a
write to `.git` or `.claude`. The adapter then offers no "always allow"
option.
- **`init.plugin_errors`** also lists load errors of plugins that
managed settings enable. The adapter only logs them.
- **`forkSession` with `upToMessageId`** and **`getSessionMessages`**
compaction fixes. Picked up as they are: the adapter has no workaround
for the old behavior.
- **A subagent's WebSearch result can carry `tool_use_result`.** The
code reads only fields that this result does not have. One comment in
`src/async-tasks.ts` said that no subagent result carries one; it now
says Bash results.
- **A permission check that fails after a PreToolUse hook allowed the
call** goes to `canUseTool`, which the adapter always provides.
## Not in this PR
Left for follow-ups, because each is its own change:
- The 200K placeholder for the context window. 1M is now the more likely
value, and with it the "1m" text heuristic has nothing left to do.
- `matchDeniedModels()` (alpha). The adapter's own `isDeniedModel`
disagrees with it on 23 of 875 model and entry pairs.
- `supersedes` on the retry of a response whose tool call could not be
parsed. The adapter does not act on `supersedes`.
- `machinePolicy.didNotLoad` (alpha) of `resolveSettings()`.
## Testing
- `npm run build`, `npm run check`, `npm run test:run` (4,121 tests
pass)
- Real CLI: one short session with slow hooks and
`CLAUDE_CODE_HOOK_HEARTBEAT_INTERVAL_MS=1000`, to record the heartbeat
frames and their order
- Real CLI: `getContextUsage` for unknown and known model ids, without a
prompt
93 lines
2.5 KiB
JSON
93 lines
2.5 KiB
JSON
{
|
|
"name": "@agentclientprotocol/claude-agent-acp",
|
|
"publishConfig": {
|
|
"access": "public"
|
|
},
|
|
"version": "0.106.0",
|
|
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
|
"main": "dist/lib.js",
|
|
"types": "dist/lib.d.ts",
|
|
"bin": {
|
|
"claude-agent-acp": "dist/index.js"
|
|
},
|
|
"type": "module",
|
|
"exports": {
|
|
".": {
|
|
"types": "./dist/lib.d.ts",
|
|
"import": "./dist/lib.js"
|
|
},
|
|
"./package.json": "./package.json"
|
|
},
|
|
"files": [
|
|
"dist/",
|
|
"!dist/tests/",
|
|
"!dist/binary-entry.*",
|
|
"README.md",
|
|
"LICENSE",
|
|
"package.json"
|
|
],
|
|
"scripts": {
|
|
"build": "tsc",
|
|
"build:binary": "node scripts/build-binary.mjs",
|
|
"smoke:binary": "node scripts/smoke-binary.mjs",
|
|
"start": "node dist/index.js",
|
|
"dev": "npm run build && npm run start",
|
|
"example:simple-client": "node --experimental-strip-types --disable-warning=ExperimentalWarning examples/simple-client.ts",
|
|
"lint": "eslint src --ext .ts",
|
|
"lint:fix": "eslint src --ext .ts --fix",
|
|
"format": "prettier --write .",
|
|
"format:check": "prettier --check .",
|
|
"check": "npm run lint && npm run format:check",
|
|
"release:preflight": "bash scripts/release-preflight.sh",
|
|
"test": "vitest",
|
|
"test:integration": "RUN_INTEGRATION_TESTS=true vitest run",
|
|
"test:run": "vitest run",
|
|
"test:coverage": "vitest run --coverage",
|
|
"prepublishOnly": "npm run build"
|
|
},
|
|
"keywords": [
|
|
"claude",
|
|
"acp",
|
|
"agent",
|
|
"anthropic",
|
|
"typescript",
|
|
"sdk",
|
|
"code"
|
|
],
|
|
"homepage": "https://github.com/agentclientprotocol/claude-agent-acp#readme",
|
|
"bugs": {
|
|
"url": "https://github.com/agentclientprotocol/claude-agent-acp/issues"
|
|
},
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+https://github.com/agentclientprotocol/claude-agent-acp.git"
|
|
},
|
|
"author": "Zed Industries",
|
|
"license": "Apache-2.0",
|
|
"engines": {
|
|
"node": ">=22"
|
|
},
|
|
"dependencies": {
|
|
"@agentclientprotocol/sdk": "2.6.0",
|
|
"@anthropic-ai/claude-agent-sdk": "0.3.323",
|
|
"diff": "9.0.0",
|
|
"zod": "4.6.7"
|
|
},
|
|
"devDependencies": {
|
|
"@anthropic-ai/sdk": "1.8.0",
|
|
"@eslint/js": "10.0.1",
|
|
"@tsconfig/node22": "22.0.7",
|
|
"@types/node": "26.6.6",
|
|
"@typescript-eslint/eslint-plugin": "8.72.2",
|
|
"@typescript-eslint/parser": "8.72.2",
|
|
"ajv": "8.20.0",
|
|
"ajv-formats": "3.0.1",
|
|
"eslint": "10.14.0",
|
|
"eslint-config-prettier": "10.1.8",
|
|
"globals": "17.14.0",
|
|
"prettier": "3.10.1",
|
|
"typescript": "6.0.3",
|
|
"vitest": "5.1.0"
|
|
}
|
|
}
|