Compare commits

...

4 Commits

Author SHA1 Message Date
acp-release-bot[bot]
c27e6aec90 chore(main): release 0.46.0 (#778)
🤖 I have created a release *beep* *boop*
---


##
[0.46.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.1...v0.46.0)
(2026-06-16)


### Features

* Update to claude-agent-sdk 0.3.178
([#777](https://github.com/agentclientprotocol/claude-agent-acp/issues/777))
([58549ff](58549ffe6a))


### Bug Fixes

* Better handle out of turn events
([#780](https://github.com/agentclientprotocol/claude-agent-acp/issues/780))
([4f273a2](4f273a20d8))
* Forward option details in elicitation meta
([#779](https://github.com/agentclientprotocol/claude-agent-acp/issues/779))
([b364059](b3640599ae)),
closes
[#764](https://github.com/agentclientprotocol/claude-agent-acp/issues/764)

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
2026-06-16 21:36:40 +02:00
Ben Brandt
4f273a20d8 fix: Better handle out of turn events (#780)
Claude has a lot of background tasks. If we wait for "idle", some people
experience turns that never end.
If we stop iterating the query after result, people end up with events
that never show up.

Given we already often have session_updates outside of the prompt (and
clients need to handle it for v2 if they aren't already) this moves the
setup to better handle how the SDK gives us this information.

I've been test-driving this build all day and it seems to be working
great.

Closes #773
Closes #679
Closes #435
Closes #497
Closes #688
Closes #630

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:33:54 +02:00
Ben Brandt
b3640599ae fix: Forward option details in elicitation meta (#779)
Closes #764
2026-06-16 12:32:54 +00:00
Ben Brandt
58549ffe6a feat: Update to claude-agent-sdk 0.3.178 (#777) 2026-06-16 14:25:08 +02:00
9 changed files with 1702 additions and 617 deletions

View File

@@ -1,3 +1,3 @@
{
".": "0.45.1"
".": "0.46.0"
}

View File

@@ -1,5 +1,18 @@
# Changelog
## [0.46.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.1...v0.46.0) (2026-06-16)
### Features
* Update to claude-agent-sdk 0.3.178 ([#777](https://github.com/agentclientprotocol/claude-agent-acp/issues/777)) ([58549ff](https://github.com/agentclientprotocol/claude-agent-acp/commit/58549ffe6a8b02ce59894e567407bd4299c11428))
### Bug Fixes
* Better handle out of turn events ([#780](https://github.com/agentclientprotocol/claude-agent-acp/issues/780)) ([4f273a2](https://github.com/agentclientprotocol/claude-agent-acp/commit/4f273a20d870c9c69f71556b8e0519f1de30f285))
* Forward option details in elicitation meta ([#779](https://github.com/agentclientprotocol/claude-agent-acp/issues/779)) ([b364059](https://github.com/agentclientprotocol/claude-agent-acp/commit/b3640599ae685beecacd93e012d5bbc9dac716f7)), closes [#764](https://github.com/agentclientprotocol/claude-agent-acp/issues/764)
## [0.45.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.0...v0.45.1) (2026-06-16)

246
package-lock.json generated
View File

@@ -1,27 +1,27 @@
{
"name": "@agentclientprotocol/claude-agent-acp",
"version": "0.45.1",
"version": "0.46.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@agentclientprotocol/claude-agent-acp",
"version": "0.45.1",
"version": "0.46.0",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "0.25.1",
"@anthropic-ai/claude-agent-sdk": "0.3.177",
"@agentclientprotocol/sdk": "0.26.0",
"@anthropic-ai/claude-agent-sdk": "0.3.178",
"zod": "^3.25.0 || ^4.0.0"
},
"bin": {
"claude-agent-acp": "dist/index.js"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.104.1",
"@anthropic-ai/sdk": "0.104.2",
"@eslint/js": "10.0.1",
"@types/node": "25.9.3",
"@typescript-eslint/eslint-plugin": "8.61.0",
"@typescript-eslint/parser": "8.61.0",
"@typescript-eslint/eslint-plugin": "8.61.1",
"@typescript-eslint/parser": "8.61.1",
"eslint": "10.5.0",
"eslint-config-prettier": "10.1.8",
"globals": "17.6.0",
@@ -32,31 +32,31 @@
}
},
"node_modules/@agentclientprotocol/sdk": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.25.1.tgz",
"integrity": "sha512-jx2rF3bdpGwZ75Q/meyEDLLbYmbtxk82Uh9hDCdxDvcEedBnNSF5hZAnL/kJR5VNz56JqwOmqnAqasC84MwwkQ==",
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.26.0.tgz",
"integrity": "sha512-ialrcI+RzKOYe+fw+TfpyTdRmEoqIkXLlwbTi6XgaXXfdhNcdod7TmE1VsTnG3yTlox8TMTSMQgWbLLbz3r86Q==",
"license": "Apache-2.0",
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
},
"node_modules/@anthropic-ai/claude-agent-sdk": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.177.tgz",
"integrity": "sha512-CBzXnzR661q3AlfZzBjmIFQx0cxr36iJV3PExTYmPyGQX32qxtiFQgnxTcF8wB4hcSVf2hnoy/gprVJdkNx7cw==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.178.tgz",
"integrity": "sha512-PNsz20jWuahDWq7OU+pjrgYzr2TnpC1oj5yCZDxGWJ8OvucXIdD2AYlf/vUo7oE2JJwGbMTBFqXErNrfPi6Ffw==",
"license": "SEE LICENSE IN README.md",
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.177",
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.177",
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.177",
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.177",
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.177",
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.177",
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.177",
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.177"
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.178",
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.178",
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.178",
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.178",
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.178",
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.178",
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.178",
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.178"
},
"peerDependencies": {
"@anthropic-ai/sdk": ">=0.93.0",
@@ -65,9 +65,9 @@
}
},
"node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.177.tgz",
"integrity": "sha512-u9Ty+KPllm2nw0RatdPF0zcPRquNZjVptmyLG0DqduGbgZDLQpfPFMF5hffFIRnVaXhx7+jkUmEdw0jrda0UcA==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.178.tgz",
"integrity": "sha512-RmIJRoZfjwcrd7cHR3fJOL1d4L8SN7oB0REcQPbIuPM1vav2Ft3g5hBX7I86u52A4LLFKBc3SMom3+E6lR1YtQ==",
"cpu": [
"arm64"
],
@@ -78,9 +78,9 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.177.tgz",
"integrity": "sha512-ona6Jv54XFwBTqOj3MzLWfKtc2m7Rdh58wOAX9Hnue/6FcWfyeuz/UDcidVTXQ7Xytz//Tb0JJgFtiQjO7FbIA==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.178.tgz",
"integrity": "sha512-wfNl7JoaUk9IzKWQPr+hyEOX8qnkM+e4GBZnKISh60xVhW9wOOp5RdfnYj5MoJzaLYivMSCbo5rb4ThWguhOMw==",
"cpu": [
"x64"
],
@@ -91,12 +91,15 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.177.tgz",
"integrity": "sha512-wBCbklkaDb483Ab4DUFfmJjZJKXz58YXPv+CiGsyjq1St19mbKEma5KKz3Ya9mlV8aLyh4zmLK2mEHPnF//Ipg==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.178.tgz",
"integrity": "sha512-ktBU6EdJoZivf67AxRXe2uSwj0g5tCe20So9QvWVKuEEtRA4sXW5EpgxSWT6LXkgfwUoeNsJK7VAOuVjZumKmg==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
@@ -104,12 +107,15 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.177.tgz",
"integrity": "sha512-v6PMDD3h2erLuTK5S2ZvExqdL3v44OyC70XpKhyqIUnyPaGR9YAMjh//EKdWC+mNvt6mIbRZpaDcHtbASVW8Rw==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.178.tgz",
"integrity": "sha512-Z3U0fNatVK3vkki3e5sjlLJMjros+cT6uq//tdohB2kjNK1CugUuPQFQxd6GU1Lq1DokmdSEPL4OGdKiHckNdQ==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
@@ -117,12 +123,15 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.177.tgz",
"integrity": "sha512-WDP6puwPHscggNAfvIxyUSHSAjfUEkGRfnMXEPBHOqO+qjX2KGxeE13/ih3EVioeBVOUIqPui6VB05vXLa6T9Q==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.178.tgz",
"integrity": "sha512-CPTivDz27LMn5m9iQnJSoWkztLo41e8QTbuYKlAC+CTr98gaYy3Mao0M2tirEK/nGno0xRJw/EpZ1G61yEM3yw==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
@@ -130,12 +139,15 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.177.tgz",
"integrity": "sha512-1cdEO06WoEsl1JnnLCPIlg/8x37GtBsTuj65gIpSjdrImNBjgIuMWVyceP4qaXhFjtQgYK1nx3TpaxEFVDOrDg==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.178.tgz",
"integrity": "sha512-K84Ybyr0Olsslg2I1Tzd7KIcSkZgFqqDHn7q1Dfqi7bXVxjMjJ4SaV+LnEAeHSM2es7H8A7ejoTEl89xMZde4Q==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
@@ -143,9 +155,9 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.177.tgz",
"integrity": "sha512-xLgDWnZaYohtFrkgEIkGZdP+rp4sXxAMbbpEvEp0LK1vAYmJam/ztT2yoK6gfI58IbToJq1WGUEX2HVnE65yOg==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.178.tgz",
"integrity": "sha512-uKH3vgv7cQV3d9BPU4lrUKrFgoU/flmy/1QI62j9JzgE6uWVQKWC+BI4V7iceJ36tYVneRhjjuux+l+Q8egTHA==",
"cpu": [
"arm64"
],
@@ -156,9 +168,9 @@
]
},
"node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": {
"version": "0.3.177",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.177.tgz",
"integrity": "sha512-SIdQLbtF//rYK4KDBNpUPyjyui7NwCFPZ2/3vyW3TR8R8xynkNq3cLis90FnPSgxaSshi38vkJYWh+9kGDB7zg==",
"version": "0.3.178",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.178.tgz",
"integrity": "sha512-wSC5qG6UA1laWGylOU7axuC4NQxZJtibGQ79sYeOQCc05G7CfkUKSzszLOzsPP3eK63cKi/bX5PA6dd4nA5Wow==",
"cpu": [
"x64"
],
@@ -169,9 +181,9 @@
]
},
"node_modules/@anthropic-ai/sdk": {
"version": "0.104.1",
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.104.1.tgz",
"integrity": "sha512-gGACa/+IaiXzRRmF96aOhamoBgapKRBiFWbmmTFP8aMkpaEcuStF+Q61bjo4vPxBM7gqWJNZqsngslRdnLHv0Q==",
"version": "0.104.2",
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.104.2.tgz",
"integrity": "sha512-s1wEVDAtEwkS7Ajgep6PZKJLFqybRkmD3Byz+iVVsSpbDY0gjROXE9aOft6V3PMqynn3NTcycV5whga9tCzmKA==",
"license": "MIT",
"dependencies": {
"json-schema-to-ts": "^3.1.1",
@@ -630,6 +642,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -647,6 +662,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -664,6 +682,9 @@
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -681,6 +702,9 @@
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -698,6 +722,9 @@
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -715,6 +742,9 @@
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -903,17 +933,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz",
"integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz",
"integrity": "sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.61.0",
"@typescript-eslint/type-utils": "8.61.0",
"@typescript-eslint/utils": "8.61.0",
"@typescript-eslint/visitor-keys": "8.61.0",
"@typescript-eslint/scope-manager": "8.61.1",
"@typescript-eslint/type-utils": "8.61.1",
"@typescript-eslint/utils": "8.61.1",
"@typescript-eslint/visitor-keys": "8.61.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.5.0"
@@ -926,22 +956,22 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.61.0",
"@typescript-eslint/parser": "^8.61.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz",
"integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz",
"integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.61.0",
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/typescript-estree": "8.61.0",
"@typescript-eslint/visitor-keys": "8.61.0",
"@typescript-eslint/scope-manager": "8.61.1",
"@typescript-eslint/types": "8.61.1",
"@typescript-eslint/typescript-estree": "8.61.1",
"@typescript-eslint/visitor-keys": "8.61.1",
"debug": "^4.4.3"
},
"engines": {
@@ -957,14 +987,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz",
"integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz",
"integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.61.0",
"@typescript-eslint/types": "^8.61.0",
"@typescript-eslint/tsconfig-utils": "^8.61.1",
"@typescript-eslint/types": "^8.61.1",
"debug": "^4.4.3"
},
"engines": {
@@ -979,14 +1009,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz",
"integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz",
"integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/visitor-keys": "8.61.0"
"@typescript-eslint/types": "8.61.1",
"@typescript-eslint/visitor-keys": "8.61.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -997,9 +1027,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz",
"integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz",
"integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1014,15 +1044,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz",
"integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.1.tgz",
"integrity": "sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/typescript-estree": "8.61.0",
"@typescript-eslint/utils": "8.61.0",
"@typescript-eslint/types": "8.61.1",
"@typescript-eslint/typescript-estree": "8.61.1",
"@typescript-eslint/utils": "8.61.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
@@ -1039,9 +1069,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz",
"integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz",
"integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1053,16 +1083,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz",
"integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz",
"integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.61.0",
"@typescript-eslint/tsconfig-utils": "8.61.0",
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/visitor-keys": "8.61.0",
"@typescript-eslint/project-service": "8.61.1",
"@typescript-eslint/tsconfig-utils": "8.61.1",
"@typescript-eslint/types": "8.61.1",
"@typescript-eslint/visitor-keys": "8.61.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
@@ -1081,16 +1111,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz",
"integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.1.tgz",
"integrity": "sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.61.0",
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/typescript-estree": "8.61.0"
"@typescript-eslint/scope-manager": "8.61.1",
"@typescript-eslint/types": "8.61.1",
"@typescript-eslint/typescript-estree": "8.61.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1105,13 +1135,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz",
"integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==",
"version": "8.61.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz",
"integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.61.0",
"@typescript-eslint/types": "8.61.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@@ -2678,6 +2708,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2699,6 +2732,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2720,6 +2756,9 @@
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2741,6 +2780,9 @@
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [

View File

@@ -3,7 +3,7 @@
"publishConfig": {
"access": "public"
},
"version": "0.45.1",
"version": "0.46.0",
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
"main": "dist/lib.js",
"types": "dist/lib.d.ts",
@@ -60,16 +60,16 @@
"author": "Zed Industries",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "0.25.1",
"@anthropic-ai/claude-agent-sdk": "0.3.177",
"@agentclientprotocol/sdk": "0.26.0",
"@anthropic-ai/claude-agent-sdk": "0.3.178",
"zod": "^3.25.0 || ^4.0.0"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.104.1",
"@anthropic-ai/sdk": "0.104.2",
"@eslint/js": "10.0.1",
"@types/node": "25.9.3",
"@typescript-eslint/eslint-plugin": "8.61.0",
"@typescript-eslint/parser": "8.61.0",
"@typescript-eslint/eslint-plugin": "8.61.1",
"@typescript-eslint/parser": "8.61.1",
"eslint": "10.5.0",
"eslint-config-prettier": "10.1.8",
"globals": "17.6.0",

File diff suppressed because it is too large Load Diff

View File

@@ -125,6 +125,34 @@ function questionCustomFieldKey(index: number): string {
return `question_${index}_custom`;
}
/**
* `_meta` key under which a bridged enum option carries its structured
* `description`/`preview`, since ACP's `EnumOption` has no field for either.
* Namespaced like the agent's other `_meta` extensions (`_claude/...`).
*/
const OPTION_META_KEY = "_claude/askUserQuestionOption";
/** A single option as supplied by the AskUserQuestion tool. */
type AskUserQuestionOption = AskUserQuestion["options"][number];
/**
* Build the `_meta` payload that carries an option's structured `description`
* and optional `preview` for clients that can render them as distinct fields.
* Returns `undefined` when neither is present, so we don't emit an empty `_meta`.
*/
function askUserQuestionOptionMeta(
option: AskUserQuestionOption,
): NonNullable<EnumOption["_meta"]> | undefined {
const detail: { description?: string; preview?: string } = {};
if (option.description) {
detail.description = option.description;
}
if (option.preview) {
detail.preview = option.preview;
}
return Object.keys(detail).length > 0 ? { [OPTION_META_KEY]: detail } : undefined;
}
/**
* Render the AskUserQuestion tool's questions as an ACP form elicitation.
*
@@ -149,10 +177,25 @@ export function askUserQuestionsToCreateRequest(
const properties: Record<string, ElicitationPropertySchema> = {};
questions.forEach((question, index) => {
const options: EnumOption[] = question.options.map((option) => ({
const: option.label,
title: option.description ? `${option.label} — ${option.description}` : option.label,
}));
const options: EnumOption[] = question.options.map((option) => {
const enumOption: EnumOption = {
const: option.label,
// `title` stays a flattened "label — description" string so clients that
// only read `const`/`title` still surface the description. Clients that
// understand the `_meta` below should prefer its structured fields (and
// treat `const` as the clean label) rather than parsing this title.
title: option.description ? `${option.label} — ${option.description}` : option.label,
};
// The SDK option carries a `description` (secondary text) and an optional
// `preview` (mockups, code snippets, comparisons shown on focus). Neither
// has a structural slot in `EnumOption`, so forward them under ACP's
// reserved `_meta` extension point for clients that can render them.
const meta = askUserQuestionOptionMeta(option);
if (meta) {
enumOption._meta = meta;
}
return enumOption;
});
// For a single question the prompt is carried by `message`, so we don't
// repeat it in the field description. With multiple questions each field

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,9 @@
import { describe, it, expect } from "vitest";
import type { CreateElicitationRequest, CreateElicitationResponse } from "@agentclientprotocol/sdk";
import type {
CreateElicitationRequest,
CreateElicitationResponse,
EnumOption,
} from "@agentclientprotocol/sdk";
import type { ElicitationRequest } from "@anthropic-ai/claude-agent-sdk";
import {
applyAskElicitationResponse,
@@ -19,14 +23,18 @@ const SESSION_ID = "session-1";
*/
function mkQuestion(
question: string,
options: Array<{ label: string; description?: string }>,
options: Array<{ label: string; description?: string; preview?: string }>,
opts: { header?: string; multiSelect?: boolean } = {},
): AskUserQuestion {
return {
question,
header: opts.header ?? "",
multiSelect: opts.multiSelect ?? false,
options: options.map((o) => ({ label: o.label, description: o.description ?? "" })),
options: options.map((o) => ({
label: o.label,
description: o.description ?? "",
...(o.preview ? { preview: o.preview } : {}),
})),
} as AskUserQuestion;
}
@@ -179,7 +187,14 @@ describe("askUserQuestionsToCreateRequest", () => {
title: "Library",
description: undefined,
oneOf: [
{ const: "date-fns", title: "date-fns — Lightweight" },
{
const: "date-fns",
title: "date-fns — Lightweight",
// Structured description forwarded under `_meta` so clients can render
// it as secondary text instead of parsing it out of the title.
_meta: { "_claude/askUserQuestionOption": { description: "Lightweight" } },
},
// No description → no `_meta` emitted.
{ const: "luxon", title: "luxon" },
],
});
@@ -187,6 +202,47 @@ describe("askUserQuestionsToCreateRequest", () => {
expect(schema.properties?.["Which library?"]).toBeUndefined();
});
it("forwards option description and preview under _meta for rich clients", () => {
const questions = [
mkQuestion("Which layout?", [
{
label: "Grid",
description: "Cards in a responsive grid",
preview: "```\n[ ] [ ] [ ]\n[ ] [ ] [ ]\n```",
},
{ label: "List", description: "Stacked rows" },
{ label: "Plain" },
]),
];
const schema = (
askUserQuestionsToCreateRequest(questions, SESSION_ID, undefined) as Extract<
CreateElicitationRequest,
{ mode: "form" }
>
).requestedSchema;
const oneOf = (schema.properties?.["question_0"] as { oneOf: EnumOption[] }).oneOf;
// Both description and preview travel structurally; the title still flattens
// the description for clients that only read const/title.
expect(oneOf[0]).toEqual({
const: "Grid",
title: "Grid — Cards in a responsive grid",
_meta: {
"_claude/askUserQuestionOption": {
description: "Cards in a responsive grid",
preview: "```\n[ ] [ ] [ ]\n[ ] [ ] [ ]\n```",
},
},
});
// Description only → preview omitted from _meta.
expect(oneOf[1]._meta).toEqual({
"_claude/askUserQuestionOption": { description: "Stacked rows" },
});
// Neither → no _meta at all.
expect(oneOf[2]._meta).toBeUndefined();
});
it("includes a per-question optional free-text custom-answer field", () => {
const questions = [
mkQuestion("Which?", [{ label: "A" }, { label: "B" }]),
@@ -208,7 +264,6 @@ describe("askUserQuestionsToCreateRequest", () => {
type: "string",
title: "Other",
});
expect(schema.properties?.["customAnswer"]).toBeUndefined();
});
it("builds an array property for multi-select questions and includes per-field question text", () => {

View File

@@ -216,6 +216,31 @@ describe("session config options", () => {
).rejects.toThrow("Invalid value for config option mode: invalid-mode");
});
it("rejects mode and config changes once the query stream has closed (husk session)", async () => {
// After an unexpected stream death the session lingers as a husk
// (queryClosed=true) so prompt() can answer with a clear error. The
// config/mode handlers must do the same rather than calling setModel/
// setPermissionMode on the closed query.
const session = (agent as unknown as { sessions: Record<string, { queryClosed?: boolean }> })
.sessions[SESSION_ID];
session.queryClosed = true;
await expect(
agent.setSessionConfigOption({
sessionId: SESSION_ID,
configId: "model",
value: "claude-sonnet-4-6",
}),
).rejects.toThrow(/start a new session/);
await expect(agent.setSessionMode({ sessionId: SESSION_ID, modeId: "plan" })).rejects.toThrow(
/start a new session/,
);
// Short-circuited before touching the (closed) query.
expect(setModelSpy).not.toHaveBeenCalled();
expect(setPermissionModeSpy).not.toHaveBeenCalled();
});
it("changes mode, sends current_mode_update but not config_option_update", async () => {
await agent.setSessionConfigOption({
sessionId: SESSION_ID,