Compare commits

...

77 Commits

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


##
[0.29.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.1...v0.29.2)
(2026-04-17)


### Bug Fixes

* Guard against null usage tokens
([#565](https://github.com/agentclientprotocol/claude-agent-acp/issues/565))
([f7dc300](f7dc300a16)),
closes
[#564](https://github.com/agentclientprotocol/claude-agent-acp/issues/564)

---
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-04-17 17:54:58 +02:00
Ben Brandt
f7dc300a16 fix: Guard against null usage tokens (#565)
Closes #564
2026-04-17 15:53:22 +00:00
acp-release-bot[bot]
ca1fe79e6f chore(main): release 0.29.1 (#559)
🤖 I have created a release *beep* *boop*
---


##
[0.29.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.0...v0.29.1)
(2026-04-17)


### Bug Fixes

* emit usage updates from Claude stream events
([#506](https://github.com/agentclientprotocol/claude-agent-acp/issues/506))
([dd67450](dd67450fd9))
* Remove dot from auto mode description
([#561](https://github.com/agentclientprotocol/claude-agent-acp/issues/561))
([2ecfa83](2ecfa83b26))
* Update to claude-agent-sdk 0.2.112 to fix Auto bug with Opus 4.7
([#562](https://github.com/agentclientprotocol/claude-agent-acp/issues/562))
([079614a](079614ab05))

---
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-04-17 14:49:29 +02:00
Ben Brandt
079614ab05 fix: Update to claude-agent-sdk 0.2.112 to fix Auto bug with Opus 4.7 (#562) 2026-04-17 11:39:24 +00:00
José Valim
2ecfa83b26 fix: Remove dot from auto mode description (#561)
The other descriptions do not end with dot.
2026-04-17 10:11:40 +00:00
Michael Gendy
dd67450fd9 fix: emit usage updates from Claude stream events (#506)
## Summary
- emit ACP `usage_update` notifications from top-level Claude
`stream_event` message usage
- keep tracking a usage snapshot across `message_start` and
`message_delta` so partial deltas still produce a complete total
- preserve the existing `result`-path update as the final
exact/cost-bearing usage event

## Why
Claude SDK stream events already carry incremental usage on
`message_delta`, but `claude-agent-acp` currently ignores that path and
only emits `usage_update` from the final `result`. This makes usage
appear stale until the turn ends in ACP clients that expect live context
usage updates.

## Verification
- built the repo with `npm run build`
- ran a direct ACP stdio client against the patched local build
- observed `usage_update` notifications emitted before the final
result-path usage update

Patched local smoke-test output included this sequence:
- `usage_update used=20973 size=200000`
- `agent_message_chunk text=TEST_OK`
- `usage_update used=20989 size=200000`
- `usage_update used=20989 size=1000000 cost=0.1314875`

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-16 18:55:28 +02:00
acp-release-bot[bot]
d6a069f9fe chore(main): release 0.29.0 (#558)
🤖 I have created a release *beep* *boop*
---


##
[0.29.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.28.0...v0.29.0)
(2026-04-16)


### Features

* Update to claude-agent-sdk 0.2.111 (Opus 4.7)
([#557](https://github.com/agentclientprotocol/claude-agent-acp/issues/557))
([85cd70c](85cd70c9f3))

---
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-04-16 17:59:54 +02:00
Ben Brandt
85cd70c9f3 feat: Update to claude-agent-sdk 0.2.111 (Opus 4.7) (#557) 2026-04-16 15:55:36 +00:00
Ben Brandt
860c0441c7 Update to claude-agent-sdk 0.2.111 (Opus 4.7) (#556) 2026-04-16 15:51:05 +00:00
acp-release-bot[bot]
3c98d76197 chore(main): release 0.28.0 (#550)
🤖 I have created a release *beep* *boop*
---


##
[0.28.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.27.0...v0.28.0)
(2026-04-15)


### Features

* Update to claude-agent-sdk 0.2.109
([#549](https://github.com/agentclientprotocol/claude-agent-acp/issues/549))
([07a0fbc](07a0fbc2f6))

---
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-04-15 11:48:43 +02:00
Ben Brandt
07a0fbc2f6 feat: Update to claude-agent-sdk 0.2.109 (#549) 2026-04-15 09:23:23 +00:00
Ben Brandt
a0da4277e3 test: Test coverage for reload failure cases (#545) 2026-04-13 21:35:05 +00:00
acp-release-bot[bot]
e3b7d1b9b3 chore(main): release 0.27.0 (#529)
🤖 I have created a release *beep* *boop*
---


##
[0.27.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.26.0...v0.27.0)
(2026-04-13)


### Features

* allow clients to opt into receiving raw SDK messages
([#527](https://github.com/agentclientprotocol/claude-agent-acp/issues/527))
([403a668](403a668078))
* Update to claude-agent-sdk 0.2.104
([#537](https://github.com/agentclientprotocol/claude-agent-acp/issues/537))
([6811943](6811943f57))


### Bug Fixes

* Allow auto mode after plan mode and send description for auto mode
([#528](https://github.com/agentclientprotocol/claude-agent-acp/issues/528))
([fb9aced](fb9aced315))
* Better remote check for auth methods
([#538](https://github.com/agentclientprotocol/claude-agent-acp/issues/538))
([93f58c0](93f58c0d2f))
* better shutdown logic
([#543](https://github.com/agentclientprotocol/claude-agent-acp/issues/543))
([9fb631f](9fb631f5d7))
* exit process when ACP connection closes
([#530](https://github.com/agentclientprotocol/claude-agent-acp/issues/530))
([5c81e99](5c81e99fe5))
* guard tool info rendering when tool_use input is undefined
([#536](https://github.com/agentclientprotocol/claude-agent-acp/issues/536))
([d627b8c](d627b8c5e9))
* Remove backup auth check from new session
([#544](https://github.com/agentclientprotocol/claude-agent-acp/issues/544))
([32b16c1](32b16c1ad9))

---
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-04-13 19:05:16 +02:00
Ben Brandt
32b16c1ad9 fix: Remove backup auth check from new session (#544)
This was an optimistic check, and causes issues when users are using
alternate logins. Just removing
2026-04-13 17:00:55 +00:00
Ben Brandt
9fb631f5d7 fix: better shutdown logic (#543)
Make cancellation a no-op for unknown sessions, close each
session query during disposal, and run the same cleanup path on
SIGINT and SIGTERM in CLI mode.

Follow up to #530
2026-04-13 18:52:44 +02:00
Sway Chan
5c81e99fe5 fix: exit process when ACP connection closes (#530)
## Summary

- Return `AgentSideConnection` from `runAcp()` instead of discarding it
- Listen for `connection.closed` and call `process.exit(0)` on
resolution
- Fixes orphan process accumulation in oneshot mode (e.g. via ACPX)

## Problem

When used in oneshot mode, `claude-agent-acp` does not exit after the
client closes the stdin pipe. `process.stdin.resume()` keeps the Node.js
event loop alive indefinitely. Over time, orphan processes accumulate on
the host (~97MB RSS each), eventually exhausting system resources.

## Root cause

`runAcp()` creates an `AgentSideConnection` but discards the reference.
The `Connection.#receive()` loop detects stdin EOF and fires
`abortController.abort()`, resolving `connection.closed` — but no code
listens for it to trigger `process.exit()`.

## Fix

1. **`acp-agent.ts`**: `runAcp()` now returns the `AgentSideConnection`
instance
2. **`index.ts`**: Awaits `connection.closed` and calls
`process.exit(0)`

## Impact

- **Oneshot sessions**: Process now exits cleanly when the client closes
stdin (EOF)
- **Persistent sessions**: Unaffected — the client keeps stdin open, so
`connection.closed` does not fire until explicit disconnect

## Test plan

- [x] Verified oneshot: process exits within 1s after stdin EOF
- [x] Verified persistent: process remains alive while stdin is open
- [x] Measured idle RSS: ~97MB → freed on exit
- [x] Tested with ACPX runtime (OpenClaw gateway) in production

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: WayChan <dove.h14@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-13 16:40:45 +00:00
dependabot[bot]
de37577eaf chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#539)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 7.0.0 to 7.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update the readme with direct upload details by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/795">actions/upload-artifact#795</a></li>
<li>Readme: bump all the example versions to v7 by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/796">actions/upload-artifact#796</a></li>
<li>Include changes in typespec/ts-http-runtime 0.3.5 by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/797">actions/upload-artifact#797</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v7...v7.0.1">https://github.com/actions/upload-artifact/compare/v7...v7.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="043fb46d1a"><code>043fb46</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/797">#797</a>
from actions/yacaovsnc/update-dependency</li>
<li><a
href="634250c138"><code>634250c</code></a>
Include changes in typespec/ts-http-runtime 0.3.5</li>
<li><a
href="e454baaac2"><code>e454baa</code></a>
Readme: bump all the example versions to v7 (<a
href="https://redirect.github.com/actions/upload-artifact/issues/796">#796</a>)</li>
<li><a
href="74fad66b98"><code>74fad66</code></a>
Update the readme with direct upload details (<a
href="https://redirect.github.com/actions/upload-artifact/issues/795">#795</a>)</li>
<li>See full diff in <a
href="bbbca2ddaa...043fb46d1a">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=7.0.0&new-version=7.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 17:54:22 +02:00
dependabot[bot]
3c570c7673 chore(deps): bump googleapis/release-please-action from 4.4.0 to 4.4.1 (#540)
Bumps
[googleapis/release-please-action](https://github.com/googleapis/release-please-action)
from 4.4.0 to 4.4.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/release-please-action/releases">googleapis/release-please-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.1</h2>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.4.0...v4.4.1">4.4.1</a>
(2026-02-20)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>bump release-please from 17.1.3 to 17.3.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1183">#1183</a>)
(<a
href="ef9c2745db">ef9c274</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/release-please-action/blob/main/CHANGELOG.md">googleapis/release-please-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.4.0...v4.4.1">4.4.1</a>
(2026-02-20)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>bump release-please from 17.1.3 to 17.3.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1183">#1183</a>)
(<a
href="ef9c2745db">ef9c274</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.3.0...v4.4.0">4.4.0</a>
(2025-10-09)</h2>
<h3>Features</h3>
<ul>
<li>add ability to select versioning-strategy and release-as (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1121">#1121</a>)
(<a
href="ee0f5bae45">ee0f5ba</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><code>changelog-host</code> parameter ignored when using manifest
configuration (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1151">#1151</a>)
(<a
href="535c4130c1">535c413</a>)</li>
<li>bump mocha from 11.7.1 to 11.7.2 in the npm_and_yarn group across 1
directory (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1149">#1149</a>)
(<a
href="3612a99d75">3612a99</a>)</li>
<li>bump release-please from 17.1.2 to 17.1.3 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1158">#1158</a>)
(<a
href="66fbfe9439">66fbfe9</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.2.0...v4.3.0">4.3.0</a>
(2025-08-20)</h2>
<h3>Features</h3>
<ul>
<li><strong>deps:</strong> update release-please to 17.1.2 (<a
href="f07192c046">f07192c</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.1.5...v4.2.0">4.2.0</a>
(2025-03-07)</h2>
<h3>Features</h3>
<ul>
<li>support for skip-labeling parameter for GitHub action (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1066">#1066</a>)
(<a
href="fb7f385da2">fb7f385</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.1.4...v4.1.5">4.1.5</a>
(2025-02-27)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> update release-please to 16.18.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1083">#1083</a>)
(<a
href="aeb7f8d384">aeb7f8d</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.1.3...v4.1.4">4.1.4</a>
(2024-10-02)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1015">#1015</a>)
(<a
href="5ec1cbd9cb">5ec1cbd</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5c625bfb5d"><code>5c625bf</code></a>
chore(main): release 4.4.1 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1187">#1187</a>)</li>
<li><a
href="8bb7a2ed0f"><code>8bb7a2e</code></a>
chore: build dist (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1186">#1186</a>)</li>
<li><a
href="ef9c2745db"><code>ef9c274</code></a>
fix: bump release-please from 17.1.3 to 17.3.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1183">#1183</a>)</li>
<li><a
href="64d83e95d8"><code>64d83e9</code></a>
docs(README): add missing action inputs + package options (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1176">#1176</a>)</li>
<li>See full diff in <a
href="16a9c90856...5c625bfb5d">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=googleapis/release-please-action&package-manager=github_actions&previous-version=4.4.0&new-version=4.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 17:53:38 +02:00
dependabot[bot]
96abf29334 chore(deps): bump actions/create-github-app-token from 3.0.0 to 3.1.1 (#541)
Bumps
[actions/create-github-app-token](https://github.com/actions/create-github-app-token)
from 3.0.0 to 3.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/create-github-app-token/releases">actions/create-github-app-token's
releases</a>.</em></p>
<blockquote>
<h2>v3.1.1</h2>
<h2><a
href="https://github.com/actions/create-github-app-token/compare/v3.1.0...v3.1.1">3.1.1</a>
(2026-04-11)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>improve error message when app identifier is empty (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/362">#362</a>)
(<a
href="07e2b76066">07e2b76</a>),
closes <a
href="https://redirect.github.com/actions/create-github-app-token/issues/249">#249</a></li>
</ul>
<h2>v3.1.0</h2>
<h1><a
href="https://github.com/actions/create-github-app-token/compare/v3.0.0...v3.1.0">3.1.0</a>
(2026-04-11)</h1>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> bump p-retry from 7.1.1 to 8.0.0 (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/357">#357</a>)
(<a
href="3bbe07d928">3bbe07d</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>add <code>client-id</code> input and deprecate <code>app-id</code>
(<a
href="https://redirect.github.com/actions/create-github-app-token/issues/353">#353</a>)
(<a
href="e6bd4e6970">e6bd4e6</a>)</li>
<li>update permission inputs (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/358">#358</a>)
(<a
href="076e9480ca">076e948</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1b10c78c78"><code>1b10c78</code></a>
build(release): 3.1.1 [skip ci]</li>
<li><a
href="07e2b76066"><code>07e2b76</code></a>
fix: improve error message when app identifier is empty (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/362">#362</a>)</li>
<li><a
href="ea0121618b"><code>ea01216</code></a>
ci: remove publish-immutable-action workflow (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/361">#361</a>)</li>
<li><a
href="7bd0371149"><code>7bd0371</code></a>
build(release): 3.1.0 [skip ci]</li>
<li><a
href="e6bd4e6970"><code>e6bd4e6</code></a>
feat: add <code>client-id</code> input and deprecate <code>app-id</code>
(<a
href="https://redirect.github.com/actions/create-github-app-token/issues/353">#353</a>)</li>
<li><a
href="076e9480ca"><code>076e948</code></a>
feat: update permission inputs (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/358">#358</a>)</li>
<li><a
href="3bbe07d928"><code>3bbe07d</code></a>
fix(deps): bump p-retry from 7.1.1 to 8.0.0 (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/357">#357</a>)</li>
<li><a
href="28a99e369c"><code>28a99e3</code></a>
build(deps-dev): bump c8 from 10.1.3 to 11.0.0</li>
<li><a
href="4df50600ef"><code>4df5060</code></a>
build(deps-dev): bump open-cli from 8.0.0 to 9.0.0</li>
<li><a
href="4843c538d9"><code>4843c53</code></a>
build(deps-dev): bump the development-dependencies group with 3
updates</li>
<li>See full diff in <a
href="f8d387b68d...1b10c78c78">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/create-github-app-token&package-manager=github_actions&previous-version=3.0.0&new-version=3.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 17:53:19 +02:00
Ben Brandt
93f58c0d2f fix: Better remote check for auth methods (#538)
The auth methods don't have interactive modes, which means they don't
work on remote machines when you need to paste a code in.

Our previous change might not have been enough, so added some heuristics
similar to what the SDK does for checking for remote.

It's not perfect because I think they are attempting to open the URL and
then falling back when it fails, but heopfully this is at least closer.
2026-04-13 17:34:27 +02:00
Ben Brandt
6811943f57 feat: Update to claude-agent-sdk 0.2.104 (#537) 2026-04-13 15:29:25 +00:00
zhangyc
d627b8c5e9 fix: guard tool info rendering when tool_use input is undefined (#536)
## Summary

- Guard `toolInfoFromToolUse()` against `undefined` input for Read,
Glob, Grep, WebSearch, and TodoWrite cases
- Make `planEntries()` resilient to `undefined` input (returns `[]`
instead of crashing)
- Guard TodoWrite plan updates in `streamEventToAcpNotifications()` with
optional chaining on `chunk.input?.todos`

## Why this change

Claude `tool_use` blocks can temporarily carry `input: undefined` during
streaming (before `input_json_delta` arrives), and historical `tool_use`
messages with incomplete input may be replayed when a JetBrains IDEA
session is resumed. Without these guards, ACP crashes with:

```
TypeError: Cannot read properties of undefined (reading 'limit')
TypeError: Cannot read properties of undefined (reading '-i')
TypeError: Cannot read properties of undefined (reading 'todos')
```

All three crashes share the same root cause: the ACP bridge assumes
`tool_use.input` is always defined, but it can be `undefined` during
streaming early chunks or session history replay.

## Test plan

- [x] Added regression tests for `toolInfoFromToolUse()` with `input:
undefined` (Read, Grep, Glob, WebSearch, TodoWrite)
- [x] Added regression test for `planEntries(undefined)` — returns `[]`
- [x] Added regression test for `planEntries({})` — graceful handling
- [x] Added regression test for `toAcpNotifications()` with TodoWrite +
undefined input — no crash, no spurious plan update
- [x] Added regression test verifying TodoWrite + valid input still
emits plan update
- [x] `npm run build` passes with no TypeScript errors
- [x] All 167 tests pass (10 new)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-13 17:03:01 +02:00
Steffen Deusch
403a668078 feat: allow clients to opt into receiving raw SDK messages (#527)
Relates to:
https://github.com/agentclientprotocol/claude-agent-acp/pull/508#discussion_r3050540393
2026-04-13 16:02:40 +02:00
Ben Brandt
fb9aced315 fix: Allow auto mode after plan mode and send description for auto mode (#528) 2026-04-08 11:51:24 +00:00
acp-release-bot[bot]
0a501434c0 chore(main): release 0.26.0 (#524)
🤖 I have created a release *beep* *boop*
---


##
[0.26.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.3...v0.26.0)
(2026-04-08)


### Features

* Update claude-agent-sdk to 0.2.96
([#526](https://github.com/agentclientprotocol/claude-agent-acp/issues/526))
([c073131](c073131488))


### Bug Fixes

* Remove bun builds from release
([#525](https://github.com/agentclientprotocol/claude-agent-acp/issues/525))
([fcf5aaf](fcf5aaf06d))
* Use TUI login for remote environments
([#523](https://github.com/agentclientprotocol/claude-agent-acp/issues/523))
([cc73e37](cc73e37b41))

---
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-04-08 12:51:09 +02:00
Ben Brandt
c073131488 feat: Update claude-agent-sdk to 0.2.96 (#526) 2026-04-08 12:48:54 +02:00
Ben Brandt
fcf5aaf06d fix: Remove bun builds from release (#525)
The SDK is broken for bun builds, and these had poor support for various
reasons anyway. Going to turn off these pipelines until we can fix.
2026-04-08 10:18:30 +00:00
Ben Brandt
cc73e37b41 fix: Use TUI login for remote environments (#523)
The auth subcommand goes through a flow that requires pasting in a code
on remote environments, but does not allow for pasting that code in.
Until they fix this in the CLI subcommand, we'll have to go to the old
flow of launching the full CLI.
2026-04-08 11:58:48 +02:00
dependabot[bot]
41f04ec31c chore(deps-dev): bump @anthropic-ai/sdk from 0.82.0 to 0.84.0 (#520)
Bumps
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
from 0.82.0 to 0.84.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/anthropic-sdk-typescript/releases"><code>@​anthropic-ai/sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>sdk: v0.84.0</h2>
<h2>0.84.0 (2026-04-07)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.83.0...sdk-v0.84.0">sdk-v0.83.0...sdk-v0.84.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> Add support for claude-mythos-preview (<a
href="d4057b0a95">d4057b0</a>)</li>
<li><strong>tools:</strong> add AbortSignal support for tool runner (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/848">#848</a>)
(<a
href="972d5918a4">972d591</a>)</li>
</ul>
<h2>sdk: v0.83.0</h2>
<h2>0.83.0 (2026-04-03)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.82.0...sdk-v0.83.0">sdk-v0.82.0...sdk-v0.83.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>vertex:</strong> add support for US multi-region endpoint
(<a
href="5e5aea72e8">5e5aea7</a>)</li>
<li><strong>vertex:</strong> add support for US multi-region endpoint
(<a
href="0de0e98aac">0de0e98</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>client:</strong> deprecate client-side compaction helpers
(<a
href="1926e87039">1926e87</a>)</li>
<li><strong>client:</strong> internal updates (<a
href="3d64763154">3d64763</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/anthropic-sdk-typescript/blob/main/CHANGELOG.md"><code>@​anthropic-ai/sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>0.84.0 (2026-04-07)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.83.0...sdk-v0.84.0">sdk-v0.83.0...sdk-v0.84.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> Add support for claude-mythos-preview (<a
href="d4057b0a95">d4057b0</a>)</li>
<li><strong>tools:</strong> add AbortSignal support for tool runner (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/848">#848</a>)
(<a
href="972d5918a4">972d591</a>)</li>
</ul>
<h2>0.83.0 (2026-04-03)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.82.0...sdk-v0.83.0">sdk-v0.82.0...sdk-v0.83.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>vertex:</strong> add support for US multi-region endpoint
(<a
href="5e5aea72e8">5e5aea7</a>)</li>
<li><strong>vertex:</strong> add support for US multi-region endpoint
(<a
href="0de0e98aac">0de0e98</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>client:</strong> dont upload aws artifact (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/844">#844</a>)
(<a
href="d1a31fcd59">d1a31fc</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>client:</strong> deprecate client-side compaction helpers
(<a
href="1926e87039">1926e87</a>)</li>
<li><strong>client:</strong> internal updates (<a
href="3d64763154">3d64763</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4105fd6cf6"><code>4105fd6</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/973">#973</a>)</li>
<li><a
href="0b536ae0e9"><code>0b536ae</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/970">#970</a>)</li>
<li>See full diff in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.82.0...sdk-v0.84.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@anthropic-ai/sdk&package-manager=npm_and_yarn&previous-version=0.82.0&new-version=0.84.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/agentclientprotocol/claude-agent-acp/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-08 08:04:37 +02:00
dependabot[bot]
8acd0bd27f chore(deps): bump @hono/node-server from 1.19.12 to 1.19.13 (#521)
Bumps [@hono/node-server](https://github.com/honojs/node-server) from
1.19.12 to 1.19.13.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/honojs/node-server/releases"><code>@​hono/node-server</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v1.19.13</h2>
<h2>Security Fix</h2>
<p>Fixed an issue in Serve Static Middleware where inconsistent handling
of repeated slashes (<code>//</code>) between the router and static file
resolution could allow middleware to be bypassed. Users of Serve Static
Middleware are encouraged to upgrade to this version.</p>
<p>See GHSA-92pp-h63x-v22m for details.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fd64e659a3"><code>fd64e65</code></a>
1.19.13</li>
<li><a
href="025c30f55d"><code>025c30f</code></a>
Merge commit from fork</li>
<li>See full diff in <a
href="https://github.com/honojs/node-server/compare/v1.19.12...v1.19.13">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@hono/node-server&package-manager=npm_and_yarn&previous-version=1.19.12&new-version=1.19.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/agentclientprotocol/claude-agent-acp/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-08 08:04:11 +02:00
dependabot[bot]
4b82236c1f chore(deps): bump hono from 4.12.11 to 4.12.12 (#522)
Bumps [hono](https://github.com/honojs/hono) from 4.12.11 to 4.12.12.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/honojs/hono/releases">hono's
releases</a>.</em></p>
<blockquote>
<h2>v4.12.12</h2>
<h2>Security fixes</h2>
<p>This release includes fixes for the following security issues:</p>
<h3>Middleware bypass via repeated slashes in serveStatic</h3>
<p>Affects: Serve Static middleware. Fixes a path normalization
inconsistency where repeated slashes (<code>//</code>) could bypass
route-based middleware protections and allow access to protected static
files. GHSA-wmmm-f939-6g9c</p>
<h3>Path traversal in toSSG() allows writing files outside the output
directory</h3>
<p>Affects: <code>toSSG()</code> for Static Site Generation. Fixes a
path traversal issue where crafted <code>ssgParams</code> values could
write files outside the configured output directory.
GHSA-xf4j-xp2r-rqqx</p>
<h3>Incorrect IP matching in ipRestriction() for IPv4-mapped IPv6
addresses</h3>
<p>Affects: IP Restriction Middleware. Fixes improper handling of
IPv4-mapped IPv6 addresses (e.g. <code>::ffff:127.0.0.1</code>) that
could cause allow/deny rules to be bypassed. GHSA-xpcf-pg52-r92g</p>
<h3>Missing validation of cookie name on write path in setCookie()</h3>
<p>Affects: <code>setCookie()</code>, <code>serialize()</code>, and
<code>serializeSigned()</code> from <code>hono/cookie</code>. Fixes
missing validation of cookie names on the write path, preventing
inconsistent handling between parsing and serialization.
GHSA-26pp-8wgv-hjvm</p>
<h3>Non-breaking space prefix bypass in cookie name handling in
getCookie()</h3>
<p>Affects: <code>getCookie()</code> from <code>hono/cookie</code>.
Fixes a discrepancy in cookie name handling that could allow
attacker-controlled cookies to override legitimate ones and bypass
prefix protections. GHSA-r5rp-j6wh-rvv4</p>
<hr />
<p>Users who use Serve Static, Static Site Generation, Cookie utilities,
or IP restriction middleware are strongly encouraged to upgrade to this
version.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c37ba26da9"><code>c37ba26</code></a>
4.12.12</li>
<li><a
href="cc067c8559"><code>cc067c8</code></a>
Merge commit from fork</li>
<li><a
href="a586cd72e3"><code>a586cd7</code></a>
Merge commit from fork</li>
<li><a
href="48fa2233bc"><code>48fa223</code></a>
Merge commit from fork</li>
<li><a
href="b470278920"><code>b470278</code></a>
Merge commit from fork</li>
<li><a
href="9aff14bd72"><code>9aff14b</code></a>
Merge commit from fork</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.12.11...v4.12.12">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=hono&package-manager=npm_and_yarn&previous-version=4.12.11&new-version=4.12.12)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/agentclientprotocol/claude-agent-acp/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-08 08:03:57 +02:00
acp-release-bot[bot]
0111786af2 chore(main): release 0.25.3 (#514)
🤖 I have created a release *beep* *boop*
---


##
[0.25.3](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.2...v0.25.3)
(2026-04-06)


### Bug Fixes

* Drop claude-agent-sdk back to 0.2.91 to fix broken import
([#513](https://github.com/agentclientprotocol/claude-agent-acp/issues/513))
([26f3e8a](26f3e8a521))
* Recreate resumed sessions when params change
([#515](https://github.com/agentclientprotocol/claude-agent-acp/issues/515))
([aa82193](aa82193330))

---
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-04-06 22:45:35 +02:00
Ben Brandt
aa82193330 fix: Recreate resumed sessions when params change (#515)
Closes #512

Fingerprint session-defining params to detect cwd or MCP server
changes, reuse sessions when unchanged, and ignore MCP server
ordering differences. Extract session teardown into a helper and add
tests covering reuse and recreation paths.
2026-04-06 22:44:14 +02:00
Ben Brandt
26f3e8a521 fix: Drop claude-agent-sdk back to 0.2.91 to fix broken import (#513)
Seems they released with a missing file that breaks the release builds.
2026-04-06 19:59:41 +00:00
acp-release-bot[bot]
769255c9a9 chore(main): release 0.25.2 (#511)
🤖 I have created a release *beep* *boop*
---


##
[0.25.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.1...v0.25.2)
(2026-04-06)


### Bug Fixes

* prioritize ANTHROPIC_MODEL env var over settings.model in model …
([#505](https://github.com/agentclientprotocol/claude-agent-acp/issues/505))
([bea1a40](bea1a40e9b))

---
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-04-06 21:50:32 +02:00
soddygo
bea1a40e9b fix: prioritize ANTHROPIC_MODEL env var over settings.model in model … (#505)
Title:
fix: ANTHROPIC_MODEL env var not respected in ACP agent model selection
                                                                  
Body:
   
## Summary
                                                                  
The `ANTHROPIC_MODEL` environment variable is not being respected when
using Claude Code via the ACP (Agent Client Protocol). This causes users
who set their preferred model via
environment variable to have their setting ignored, with the default
model (`claude-sonnet-4-6`) being used instead.
  ## Problem                                                      

When using Claude Code through ACP integrations (e.g., agent platforms),
users expect the `ANTHROPIC_MODEL` environment variable to control which
model is used for LLM requests.
However, the current implementation only checks `settings.model` (from
configuration files) and completely ignores `ANTHROPIC_MODEL`.
  ## Root Cause                                                   

In `src/acp-agent.ts`, the `getAvailableModels` function only checks
`settings.model`:

  ```typescript
  let currentModel = models[0];

if (settings.model) {
    const match = resolveModelPreference(models, settings.model);
if (match) {
      currentModel = match;                                       
    }
  }

The ANTHROPIC_MODEL environment variable is never read, so
environment-based model configuration is silently ignored.
   
Reproduction
                                                                  
1. Set ANTHROPIC_MODEL=glm-4.7 (or any custom model)
  2. Start Claude Code via ACP protocol
3. Send a prompt request
4. Capture network traffic - the actual model used is claude-sonnet-4-6
instead of glm-4.7
  Fix
Added priority-based model selection that respects the ANTHROPIC_MODEL
environment variable, aligning with the main Claude Code CLI behavior:
   
// Model priority (highest to lowest):
  // 1. ANTHROPIC_MODEL environment variable                      
  // 2. settings.model (user configuration)
// 3. models[0] (default first model)
  if (process.env.ANTHROPIC_MODEL) {
const match = resolveModelPreference(models,
process.env.ANTHROPIC_MODEL);
    if (match) {                                                  
      currentModel = match;
    }
  } else if (settings.model) {
const match = resolveModelPreference(models, settings.model);
    if (match) {
currentModel = match;
    }                                                             
  }

This matches the model selection priority used by the main Claude Code
CLI.
   
Testing
                                                                  
- Verified ANTHROPIC_MODEL is now respected when set
  - Verified settings.model still works when ANTHROPIC_MODEL is not set
- Verified default model (models[0]) is used when neither is set
  Breaking Change
None - this fix makes behavior more consistent with user expectations
and the main CLI.
2026-04-06 19:48:24 +00:00
dependabot[bot]
f9b15ba1c5 chore(deps): bump the minor group with 10 updates (#510)
Bumps the minor group with 10 updates:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.91` | `0.2.92` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.5.1` | `25.5.2` |
| [eslint](https://github.com/eslint/eslint) | `10.1.0` | `10.2.0` |
|
[@eslint/config-array](https://github.com/eslint/rewrite/tree/HEAD/packages/config-array)
| `0.23.3` | `0.23.4` |
|
[@eslint/config-helpers](https://github.com/eslint/rewrite/tree/HEAD/packages/config-helpers)
| `0.5.3` | `0.5.4` |
|
[@eslint/core](https://github.com/eslint/rewrite/tree/HEAD/packages/core)
| `1.1.1` | `1.2.0` |
|
[@eslint/object-schema](https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema)
| `3.0.3` | `3.0.4` |
|
[@eslint/plugin-kit](https://github.com/eslint/rewrite/tree/HEAD/packages/plugin-kit)
| `0.6.1` | `0.7.0` |
| [hono](https://github.com/honojs/hono) | `4.12.10` | `4.12.11` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.0.3` | `8.0.5` |

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.91 to 0.2.92
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases"><code>@​anthropic-ai/claude-agent-sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v0.2.92</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.92</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.92
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.92
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.92
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.92
</code></pre>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md"><code>@​anthropic-ai/claude-agent-sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>0.2.92</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.92</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4d9db79513"><code>4d9db79</code></a>
chore: Update CHANGELOG.md</li>
<li>See full diff in <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/compare/v0.2.91...v0.2.92">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.5.1 to 25.5.2
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Updates `eslint` from 10.1.0 to 10.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/eslint/releases">eslint's
releases</a>.</em></p>
<blockquote>
<h2>v10.2.0</h2>
<h2>Features</h2>
<ul>
<li><a
href="586ec2f430"><code>586ec2f</code></a>
feat: Add <code>meta.languages</code> support to rules (<a
href="https://redirect.github.com/eslint/eslint/issues/20571">#20571</a>)
(Copilot)</li>
<li><a
href="14207dee39"><code>14207de</code></a>
feat: add <code>Temporal</code> to <code>no-obj-calls</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20675">#20675</a>)
(Pixel998)</li>
<li><a
href="bbb2c93a2b"><code>bbb2c93</code></a>
feat: add Temporal to ES2026 globals (<a
href="https://redirect.github.com/eslint/eslint/issues/20672">#20672</a>)
(Pixel998)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li><a
href="542cb3e644"><code>542cb3e</code></a>
fix: update first-party dependencies (<a
href="https://redirect.github.com/eslint/eslint/issues/20714">#20714</a>)
(Francesco Trotta)</li>
</ul>
<h2>Documentation</h2>
<ul>
<li><a
href="a2af743ea6"><code>a2af743</code></a>
docs: add <code>language</code> to configuration objects (<a
href="https://redirect.github.com/eslint/eslint/issues/20712">#20712</a>)
(Francesco Trotta)</li>
<li><a
href="845f23f137"><code>845f23f</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="5fbcf5958b"><code>5fbcf59</code></a>
docs: remove <code>sourceType</code> from ts playground link (<a
href="https://redirect.github.com/eslint/eslint/issues/20477">#20477</a>)
(Tanuj Kanti)</li>
<li><a
href="8702a47465"><code>8702a47</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="ddeaded2ab"><code>ddeaded</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="2b44966912"><code>2b44966</code></a>
docs: add Major Releases section to Manage Releases (<a
href="https://redirect.github.com/eslint/eslint/issues/20269">#20269</a>)
(Milos Djermanovic)</li>
<li><a
href="eab65c700e"><code>eab65c7</code></a>
docs: update <code>eslint</code> versions in examples (<a
href="https://redirect.github.com/eslint/eslint/issues/20664">#20664</a>)
(루밀LuMir)</li>
<li><a
href="3e4a29903b"><code>3e4a299</code></a>
docs: update ESM Dependencies policies with note for own-usage packages
(<a
href="https://redirect.github.com/eslint/eslint/issues/20660">#20660</a>)
(Milos Djermanovic)</li>
</ul>
<h2>Chores</h2>
<ul>
<li><a
href="8120e30f83"><code>8120e30</code></a>
refactor: extract no unmodified loop condition (<a
href="https://redirect.github.com/eslint/eslint/issues/20679">#20679</a>)
(kuldeep kumar)</li>
<li><a
href="46e8469786"><code>46e8469</code></a>
chore: update dependency markdownlint-cli2 to ^0.22.0 (<a
href="https://redirect.github.com/eslint/eslint/issues/20697">#20697</a>)
(renovate[bot])</li>
<li><a
href="01ed3aa684"><code>01ed3aa</code></a>
test: add unit tests for unicode utilities (<a
href="https://redirect.github.com/eslint/eslint/issues/20622">#20622</a>)
(Manish chaudhary)</li>
<li><a
href="811f4930f8"><code>811f493</code></a>
ci: remove <code>--legacy-peer-deps</code> from types integration tests
(<a
href="https://redirect.github.com/eslint/eslint/issues/20667">#20667</a>)
(Milos Djermanovic)</li>
<li><a
href="6b86fcfc5c"><code>6b86fcf</code></a>
chore: update dependency npm-run-all2 to v8 (<a
href="https://redirect.github.com/eslint/eslint/issues/20663">#20663</a>)
(renovate[bot])</li>
<li><a
href="632c4f83bf"><code>632c4f8</code></a>
chore: add <code>prettier</code> update commit to
<code>.git-blame-ignore-revs</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20662">#20662</a>)
(루밀LuMir)</li>
<li><a
href="b0b0f21927"><code>b0b0f21</code></a>
chore: update dependency eslint-plugin-regexp to ^3.1.0 (<a
href="https://redirect.github.com/eslint/eslint/issues/20659">#20659</a>)
(Milos Djermanovic)</li>
<li><a
href="228a2dd4b2"><code>228a2dd</code></a>
chore: update dependency eslint-plugin-eslint-plugin to ^7.3.2 (<a
href="https://redirect.github.com/eslint/eslint/issues/20661">#20661</a>)
(Milos Djermanovic)</li>
<li><a
href="3ab4d7e244"><code>3ab4d7e</code></a>
test: Add tests for eslintrc-style keys (<a
href="https://redirect.github.com/eslint/eslint/issues/20645">#20645</a>)
(kuldeep kumar)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="000128c292"><code>000128c</code></a>
10.2.0</li>
<li><a
href="1988fad70e"><code>1988fad</code></a>
Build: changelog update for 10.2.0</li>
<li><a
href="542cb3e644"><code>542cb3e</code></a>
fix: update first-party dependencies (<a
href="https://redirect.github.com/eslint/eslint/issues/20714">#20714</a>)</li>
<li><a
href="a2af743ea6"><code>a2af743</code></a>
docs: add <code>language</code> to configuration objects (<a
href="https://redirect.github.com/eslint/eslint/issues/20712">#20712</a>)</li>
<li><a
href="845f23f137"><code>845f23f</code></a>
docs: Update README</li>
<li><a
href="5fbcf5958b"><code>5fbcf59</code></a>
docs: remove <code>sourceType</code> from ts playground link (<a
href="https://redirect.github.com/eslint/eslint/issues/20477">#20477</a>)</li>
<li><a
href="8702a47465"><code>8702a47</code></a>
docs: Update README</li>
<li><a
href="ddeaded2ab"><code>ddeaded</code></a>
docs: Update README</li>
<li><a
href="8120e30f83"><code>8120e30</code></a>
refactor: extract no unmodified loop condition (<a
href="https://redirect.github.com/eslint/eslint/issues/20679">#20679</a>)</li>
<li><a
href="46e8469786"><code>46e8469</code></a>
chore: update dependency markdownlint-cli2 to ^0.22.0 (<a
href="https://redirect.github.com/eslint/eslint/issues/20697">#20697</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/eslint/compare/v10.1.0...v10.2.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `@eslint/config-array` from 0.23.3 to 0.23.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@​eslint/config-array</code>'s
releases</a>.</em></p>
<blockquote>
<h2>config-array: v0.23.4</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-array-v0.23.3...config-array-v0.23.4">0.23.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/object-schema</code> bumped from ^3.0.3 to
^3.0.4</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/config-array/CHANGELOG.md"><code>@​eslint/config-array</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-array-v0.23.3...config-array-v0.23.4">0.23.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/object-schema</code> bumped from ^3.0.3 to
^3.0.4</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe114eed69"><code>fe114ee</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/config-array/issues/413">#413</a>)</li>
<li><a
href="8863791972"><code>8863791</code></a>
docs: Update README sponsors</li>
<li><a
href="ef16f80b92"><code>ef16f80</code></a>
fix: re-export ESM types in CommonJS (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/config-array/issues/416">#416</a>)</li>
<li><a
href="835ddf95b0"><code>835ddf9</code></a>
docs: Update README sponsors</li>
<li><a
href="8cd3676402"><code>8cd3676</code></a>
docs: Update README sponsors</li>
<li><a
href="4d734592f3"><code>4d73459</code></a>
docs: Update README sponsors</li>
<li>See full diff in <a
href="https://github.com/eslint/rewrite/commits/config-array-v0.23.4/packages/config-array">compare
view</a></li>
</ul>
</details>
<br />

Updates `@eslint/config-helpers` from 0.5.3 to 0.5.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@​eslint/config-helpers</code>'s
releases</a>.</em></p>
<blockquote>
<h2>config-helpers: v0.5.4</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-helpers-v0.5.3...config-helpers-v0.5.4">0.5.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/core</code> bumped from ^1.1.1 to ^1.2.0</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/config-helpers/CHANGELOG.md"><code>@​eslint/config-helpers</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-helpers-v0.5.3...config-helpers-v0.5.4">0.5.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/core</code> bumped from ^1.1.1 to ^1.2.0</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe114eed69"><code>fe114ee</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/config-helpers/issues/413">#413</a>)</li>
<li><a
href="8863791972"><code>8863791</code></a>
docs: Update README sponsors</li>
<li><a
href="ef16f80b92"><code>ef16f80</code></a>
fix: re-export ESM types in CommonJS (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/config-helpers/issues/416">#416</a>)</li>
<li><a
href="835ddf95b0"><code>835ddf9</code></a>
docs: Update README sponsors</li>
<li><a
href="8cd3676402"><code>8cd3676</code></a>
docs: Update README sponsors</li>
<li><a
href="4d734592f3"><code>4d73459</code></a>
docs: Update README sponsors</li>
<li><a
href="a6c7a26a85"><code>a6c7a26</code></a>
chore: update <code>eslint</code> and <code>eslint-config-eslint</code>
(<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/config-helpers/issues/401">#401</a>)</li>
<li>See full diff in <a
href="https://github.com/eslint/rewrite/commits/config-helpers-v0.5.4/packages/config-helpers">compare
view</a></li>
</ul>
</details>
<br />

Updates `@eslint/core` from 1.1.1 to 1.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@​eslint/core</code>'s
releases</a>.</em></p>
<blockquote>
<h2>core: v1.2.0</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/core-v1.1.1...core-v1.2.0">1.2.0</a>
(2026-04-03)</h2>
<h3>Features</h3>
<ul>
<li>add <code>languages</code> and <code>docs.dialects</code> to rule
<code>meta</code> types (<a
href="https://redirect.github.com/eslint/rewrite/issues/421">#421</a>)
(<a
href="7680f69211">7680f69</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
<li>type-check defaultLanguageOptions against LangOptions (<a
href="https://redirect.github.com/eslint/rewrite/issues/420">#420</a>)
(<a
href="7bf57046b8">7bf5704</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/core/CHANGELOG.md"><code>@​eslint/core</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/core-v1.1.1...core-v1.2.0">1.2.0</a>
(2026-04-03)</h2>
<h3>Features</h3>
<ul>
<li>add <code>languages</code> and <code>docs.dialects</code> to rule
<code>meta</code> types (<a
href="https://redirect.github.com/eslint/rewrite/issues/421">#421</a>)
(<a
href="7680f69211">7680f69</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
<li>type-check defaultLanguageOptions against LangOptions (<a
href="https://redirect.github.com/eslint/rewrite/issues/420">#420</a>)
(<a
href="7bf57046b8">7bf5704</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe114eed69"><code>fe114ee</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/core/issues/413">#413</a>)</li>
<li><a
href="7680f69211"><code>7680f69</code></a>
feat: add <code>languages</code> and <code>docs.dialects</code> to rule
<code>meta</code> types (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/core/issues/421">#421</a>)</li>
<li><a
href="8863791972"><code>8863791</code></a>
docs: Update README sponsors</li>
<li><a
href="ef16f80b92"><code>ef16f80</code></a>
fix: re-export ESM types in CommonJS (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/core/issues/416">#416</a>)</li>
<li><a
href="835ddf95b0"><code>835ddf9</code></a>
docs: Update README sponsors</li>
<li><a
href="8cd3676402"><code>8cd3676</code></a>
docs: Update README sponsors</li>
<li><a
href="7bf57046b8"><code>7bf5704</code></a>
fix: type-check defaultLanguageOptions against LangOptions (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/core/issues/420">#420</a>)</li>
<li><a
href="4d734592f3"><code>4d73459</code></a>
docs: Update README sponsors</li>
<li>See full diff in <a
href="https://github.com/eslint/rewrite/commits/core-v1.2.0/packages/core">compare
view</a></li>
</ul>
</details>
<br />

Updates `@eslint/object-schema` from 3.0.3 to 3.0.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@​eslint/object-schema</code>'s
releases</a>.</em></p>
<blockquote>
<h2>object-schema: v3.0.4</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/object-schema-v3.0.3...object-schema-v3.0.4">3.0.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>avoid mutating object schema definitions during construction (<a
href="https://redirect.github.com/eslint/rewrite/issues/412">#412</a>)
(<a
href="f0fd9a2ff7">f0fd9a2</a>)</li>
<li>correct ValidationStrategy parameter types (<a
href="https://redirect.github.com/eslint/rewrite/issues/406">#406</a>)
(<a
href="42a30eaae5">42a30ea</a>)</li>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/object-schema/CHANGELOG.md"><code>@​eslint/object-schema</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/object-schema-v3.0.3...object-schema-v3.0.4">3.0.4</a>
(2026-04-03)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>avoid mutating object schema definitions during construction (<a
href="https://redirect.github.com/eslint/rewrite/issues/412">#412</a>)
(<a
href="f0fd9a2ff7">f0fd9a2</a>)</li>
<li>correct ValidationStrategy parameter types (<a
href="https://redirect.github.com/eslint/rewrite/issues/406">#406</a>)
(<a
href="42a30eaae5">42a30ea</a>)</li>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe114eed69"><code>fe114ee</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/413">#413</a>)</li>
<li><a
href="8863791972"><code>8863791</code></a>
docs: Update README sponsors</li>
<li><a
href="ef16f80b92"><code>ef16f80</code></a>
fix: re-export ESM types in CommonJS (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/416">#416</a>)</li>
<li><a
href="835ddf95b0"><code>835ddf9</code></a>
docs: Update README sponsors</li>
<li><a
href="8cd3676402"><code>8cd3676</code></a>
docs: Update README sponsors</li>
<li><a
href="b281abb94e"><code>b281abb</code></a>
docs: clarify ValidationStrategy object behavior (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/415">#415</a>)</li>
<li><a
href="42a30eaae5"><code>42a30ea</code></a>
fix: correct ValidationStrategy parameter types (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/406">#406</a>)</li>
<li><a
href="f0fd9a2ff7"><code>f0fd9a2</code></a>
fix: avoid mutating object schema definitions during construction (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/412">#412</a>)</li>
<li><a
href="9189536016"><code>9189536</code></a>
refactor: use lowercase boolean in validation errors (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/object-schema/issues/405">#405</a>)</li>
<li><a
href="4d734592f3"><code>4d73459</code></a>
docs: Update README sponsors</li>
<li>See full diff in <a
href="https://github.com/eslint/rewrite/commits/object-schema-v3.0.4/packages/object-schema">compare
view</a></li>
</ul>
</details>
<br />

Updates `@eslint/plugin-kit` from 0.6.1 to 0.7.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@​eslint/plugin-kit</code>'s
releases</a>.</em></p>
<blockquote>
<h2>plugin-kit: v0.7.0</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/plugin-kit-v0.6.1...plugin-kit-v0.7.0">0.7.0</a>
(2026-04-03)</h2>
<h3>Features</h3>
<ul>
<li>add <code>languages</code> and <code>docs.dialects</code> to rule
<code>meta</code> types (<a
href="https://redirect.github.com/eslint/rewrite/issues/421">#421</a>)
(<a
href="7680f69211">7680f69</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/core</code> bumped from ^1.1.1 to ^1.2.0</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/plugin-kit/CHANGELOG.md"><code>@​eslint/plugin-kit</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/plugin-kit-v0.6.1...plugin-kit-v0.7.0">0.7.0</a>
(2026-04-03)</h2>
<h3>Features</h3>
<ul>
<li>add <code>languages</code> and <code>docs.dialects</code> to rule
<code>meta</code> types (<a
href="https://redirect.github.com/eslint/rewrite/issues/421">#421</a>)
(<a
href="7680f69211">7680f69</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>re-export ESM types in CommonJS (<a
href="https://redirect.github.com/eslint/rewrite/issues/416">#416</a>)
(<a
href="ef16f80b92">ef16f80</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​eslint/core</code> bumped from ^1.1.1 to ^1.2.0</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="80eb5455aa"><code>80eb545</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/plugin-kit/issues/124">#124</a>)</li>
<li><a
href="0008606415"><code>0008606</code></a>
docs: Use prerendered sponsors for README (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/plugin-kit/issues/122">#122</a>)</li>
<li><a
href="169d83bf82"><code>169d83b</code></a>
docs: Update README sponsors</li>
<li><a
href="8d2509a218"><code>8d2509a</code></a>
docs: Update README sponsors</li>
<li><a
href="dcacd03f4b"><code>dcacd03</code></a>
docs: Update README sponsors</li>
<li><a
href="002a6da6e3"><code>002a6da</code></a>
docs: Update README sponsors</li>
<li><a
href="5cb3dad034"><code>5cb3dad</code></a>
docs: Update README sponsors</li>
<li><a
href="dc69bd15a5"><code>dc69bd1</code></a>
docs: Update README sponsors</li>
<li><a
href="47db20bc82"><code>47db20b</code></a>
docs: Update README sponsors</li>
<li><a
href="9dbefdff4f"><code>9dbefdf</code></a>
docs: Update README sponsors</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/rewrite/commits/core-v0.7.0/packages/plugin-kit">compare
view</a></li>
</ul>
</details>
<br />

Updates `hono` from 4.12.10 to 4.12.11
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/honojs/hono/releases">hono's
releases</a>.</em></p>
<blockquote>
<h2>v4.12.11</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(css): add classNameSlug option to createCssContext by <a
href="https://github.com/flow-pie"><code>@​flow-pie</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4834">honojs/hono#4834</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/flow-pie"><code>@​flow-pie</code></a>
made their first contribution in <a
href="https://redirect.github.com/honojs/hono/pull/4834">honojs/hono#4834</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/honojs/hono/compare/v4.12.10...v4.12.11">https://github.com/honojs/hono/compare/v4.12.10...v4.12.11</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2c403c67eb"><code>2c403c6</code></a>
4.12.11</li>
<li><a
href="f82aba8e8e"><code>f82aba8</code></a>
feat(css): add classNameSlug option to createCssContext (<a
href="https://redirect.github.com/honojs/hono/issues/4834">#4834</a>)</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.12.10...v4.12.11">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.0.3 to 8.0.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v8.0.5</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.0.5/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.0.4</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.0.4/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.0.4...v8.0.5">8.0.5</a>
(2026-04-06)<!-- raw HTML omitted --></h2>
<h3>Bug Fixes</h3>
<ul>
<li>apply server.fs check to env transport (<a
href="https://redirect.github.com/vitejs/vite/issues/22159">#22159</a>)
(<a
href="f02d9fde0b">f02d9fd</a>)</li>
<li>avoid path traversal with optimize deps sourcemap handler (<a
href="https://redirect.github.com/vitejs/vite/issues/22161">#22161</a>)
(<a
href="79f002f228">79f002f</a>)</li>
<li>check <code>server.fs</code> after stripping query as well (<a
href="https://redirect.github.com/vitejs/vite/issues/22160">#22160</a>)
(<a
href="a9a3df2993">a9a3df2</a>)</li>
<li>disallow referencing files outside the package from sourcemap (<a
href="https://redirect.github.com/vitejs/vite/issues/22158">#22158</a>)
(<a
href="f05f501734">f05f501</a>)</li>
</ul>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.0.3...v8.0.4">8.0.4</a>
(2026-04-06)<!-- raw HTML omitted --></h2>
<h3>Features</h3>
<ul>
<li>allow esbuild 0.28 as peer deps (<a
href="https://redirect.github.com/vitejs/vite/issues/22155">#22155</a>)
(<a
href="b0da97372f">b0da973</a>)</li>
<li><strong>hmr:</strong> truncate list of files on hmr update (<a
href="https://redirect.github.com/vitejs/vite/issues/21535">#21535</a>)
(<a
href="d00e806d7b">d00e806</a>)</li>
<li><strong>optimizer:</strong> log when dependency scanning or bundling
takes over 1s (<a
href="https://redirect.github.com/vitejs/vite/issues/21797">#21797</a>)
(<a
href="f61a1ab33b">f61a1ab</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><code>hasBothRollupOptionsAndRolldownOptions</code> should return
<code>false</code> for proxy case (<a
href="https://redirect.github.com/vitejs/vite/issues/22043">#22043</a>)
(<a
href="99897d27b4">99897d2</a>)</li>
<li>add types for <code>vite/modulepreload-polyfill</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22126">#22126</a>)
(<a
href="17330d2b9e">17330d2</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22073">#22073</a>)
(<a
href="6daa10ff1e">6daa10f</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22143">#22143</a>)
(<a
href="22b0166127">22b0166</a>)</li>
<li><strong>resolve:</strong> resolve tsconfig paths starting with
<code>#</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22038">#22038</a>)
(<a
href="3460fc55aa">3460fc5</a>)</li>
<li><strong>ssr:</strong> use browser platform for webworker SSR builds
(fix <a
href="https://redirect.github.com/vitejs/vite/issues/21969">#21969</a>)
(<a
href="https://redirect.github.com/vitejs/vite/issues/21963">#21963</a>)
(<a
href="364c2273a1">364c227</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>add <code>environment.fetchModule</code> documentation (<a
href="https://redirect.github.com/vitejs/vite/issues/22035">#22035</a>)
(<a
href="54229e7863">54229e7</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li><strong>deps:</strong> update rolldown-related dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/21989">#21989</a>)
(<a
href="0ded627457">0ded627</a>)</li>
</ul>
<h3>Code Refactoring</h3>
<ul>
<li>upgrade to typescript 6 (<a
href="https://redirect.github.com/vitejs/vite/issues/22110">#22110</a>)
(<a
href="cc41398c2c">cc41398</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1a12d4ca4c"><code>1a12d4c</code></a>
release: v8.0.5</li>
<li><a
href="79f002f228"><code>79f002f</code></a>
fix: avoid path traversal with optimize deps sourcemap handler (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22161">#22161</a>)</li>
<li><a
href="a9a3df2993"><code>a9a3df2</code></a>
fix: check <code>server.fs</code> after stripping query as well (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22160">#22160</a>)</li>
<li><a
href="f02d9fde0b"><code>f02d9fd</code></a>
fix: apply server.fs check to env transport (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22159">#22159</a>)</li>
<li><a
href="f05f501734"><code>f05f501</code></a>
fix: disallow referencing files outside the package from sourcemap (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22158">#22158</a>)</li>
<li><a
href="7339bdc915"><code>7339bdc</code></a>
release: v8.0.4</li>
<li><a
href="54229e7863"><code>54229e7</code></a>
docs: add <code>environment.fetchModule</code> documentation (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22035">#22035</a>)</li>
<li><a
href="b0da97372f"><code>b0da973</code></a>
feat: allow esbuild 0.28 as peer deps (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22155">#22155</a>)</li>
<li><a
href="22b0166127"><code>22b0166</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22143">#22143</a>)</li>
<li><a
href="17330d2b9e"><code>17330d2</code></a>
fix: add types for <code>vite/modulepreload-polyfill</code> (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22126">#22126</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/v8.0.5/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-06 19:31:14 +02:00
acp-release-bot[bot]
0990a8e520 chore(main): release 0.25.1 (#509)
🤖 I have created a release *beep* *boop*
---


##
[0.25.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.0...v0.25.1)
(2026-04-06)


### Bug Fixes

* add `auto` to valid modes in applySessionMode to fix mode cycling
([#507](https://github.com/agentclientprotocol/claude-agent-acp/issues/507))
([15e91fb](15e91fb5c3))

---
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-04-06 09:01:18 +02:00
K4YT3X
15e91fb5c3 fix: add auto to valid modes in applySessionMode to fix mode cycling (#507)
ACP version is `v0.25.0`. Should be the newest.

I get this error when pressing Shift+Tab to cycle through the modes:

```
Caused by:
    RPC request LspQuery failed: unknown buffer id 12884902333
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: Error handling request {
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: jsonrpc: '2.0',
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: id: 48,
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: method: 'session/set_config_option',
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: params: {
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: sessionId: '$UUID_GOES_HERE',
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: configId: 'mode',
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: value: 'auto'
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: }
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: } {
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: code: -32603,
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: message: 'Internal error',
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: data: { details: 'Invalid Mode' }
2026-04-05T21:46:02+00:00 WARN  [agent_servers::acp] agent stderr: }
2026-04-05T21:46:02+00:00 ERROR [agent_ui::config_options] Failed to set config option: Internal error: {
  "details": "Invalid Mode"
}
```

I looked through the code on both sides and I think what might be
happening is, here are the modes:


f422c7c954/src/acp-agent.ts (L236-L244)

When a user gets to `bypassPermissions` and cycle again, the next
selected mode is `auto` but that option seems to be missing from here:


f422c7c954/src/acp-agent.ts (L1007-L1013)

Could the maintainers please help verify and test?

Signed-off-by: k4yt3x <i@k4yt3x.com>
2026-04-06 06:59:16 +00:00
acp-release-bot[bot]
f422c7c954 chore(main): release 0.25.0 (#489)
🤖 I have created a release *beep* *boop*
---


##
[0.25.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.2...v0.25.0)
(2026-04-03)


### Features

* Add auto permission mode support
([#501](https://github.com/agentclientprotocol/claude-agent-acp/issues/501))
([a161453](a16145396f))
* Add separate Claude and Console terminal logins
([#502](https://github.com/agentclientprotocol/claude-agent-acp/issues/502))
([063cd35](063cd35380))
* Update to claude-agent-sdk 0.2.91
([#500](https://github.com/agentclientprotocol/claude-agent-acp/issues/500))
([65a2230](65a2230385))


### Bug Fixes

* log warnings for malformed settings files instead of silent fallback
([#486](https://github.com/agentclientprotocol/claude-agent-acp/issues/486))
([ae6c388](ae6c388314))
* prevent race conditions in SettingsManager setCwd and debounce
([#485](https://github.com/agentclientprotocol/claude-agent-acp/issues/485))
([7506223](7506223cff))
* use current model's context window for usage_update size
([#412](https://github.com/agentclientprotocol/claude-agent-acp/issues/412))
([d07799d](d07799d7b3))

---
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-04-03 10:49:52 +00:00
Ben Brandt
063cd35380 feat: Add separate Claude and Console terminal logins (#502)
Expose distinct terminal auth methods for Claude subscription and
Anthropic Console, including terminal-auth metadata for both.
2026-04-03 12:48:57 +02:00
Ben Brandt
a16145396f feat: Add auto permission mode support (#501) 2026-04-03 12:34:06 +02:00
Ben Brandt
65a2230385 feat: Update to claude-agent-sdk 0.2.91 (#500) 2026-04-03 10:09:29 +00:00
dependabot[bot]
1d36b58cfb chore(deps): bump the minor group with 11 updates (#494)
Bumps the minor group with 11 updates:

| Package | From | To |
| --- | --- | --- |
|
[@agentclientprotocol/sdk](https://github.com/agentclientprotocol/typescript-sdk)
| `0.17.0` | `0.17.1` |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.84` | `0.2.87` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.1` | `4.1.2` |
|
[@napi-rs/wasm-runtime](https://github.com/napi-rs/napi-rs/tree/HEAD/wasi-runtime)
| `1.1.1` | `1.1.2` |
|
[@vitest/expect](https://github.com/vitest-dev/vitest/tree/HEAD/packages/expect)
| `4.1.1` | `4.1.2` |
|
[@vitest/mocker](https://github.com/vitest-dev/vitest/tree/HEAD/packages/mocker)
| `4.1.1` | `4.1.2` |
|
[@vitest/pretty-format](https://github.com/vitest-dev/vitest/tree/HEAD/packages/pretty-format)
| `4.1.1` | `4.1.2` |
|
[@vitest/runner](https://github.com/vitest-dev/vitest/tree/HEAD/packages/runner)
| `4.1.1` | `4.1.2` |
|
[@vitest/snapshot](https://github.com/vitest-dev/vitest/tree/HEAD/packages/snapshot)
| `4.1.1` | `4.1.2` |
|
[@vitest/spy](https://github.com/vitest-dev/vitest/tree/HEAD/packages/spy)
| `4.1.1` | `4.1.2` |
|
[@vitest/utils](https://github.com/vitest-dev/vitest/tree/HEAD/packages/utils)
| `4.1.1` | `4.1.2` |

Updates `@agentclientprotocol/sdk` from 0.17.0 to 0.17.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/typescript-sdk/releases"><code>@​agentclientprotocol/sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v0.17.1</h2>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.17.0...v0.17.1">0.17.1</a>
(2026-03-27)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Make sure we use zod/v4 path for imports (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/99">#99</a>)
(<a
href="e632d3be54">e632d3b</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/typescript-sdk/blob/main/CHANGELOG.md"><code>@​agentclientprotocol/sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.17.0...v0.17.1">0.17.1</a>
(2026-03-27)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Make sure we use zod/v4 path for imports (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/99">#99</a>)
(<a
href="e632d3be54">e632d3b</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="521078adcb"><code>521078a</code></a>
chore(main): release 0.17.1 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/100">#100</a>)</li>
<li><a
href="e632d3be54"><code>e632d3b</code></a>
fix: Make sure we use zod/v4 path for imports (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/99">#99</a>)</li>
<li><a
href="4eebf350c0"><code>4eebf35</code></a>
chore(deps): bump actions/deploy-pages from 4.0.5 to 5.0.0 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/95">#95</a>)</li>
<li><a
href="e63f49f416"><code>e63f49f</code></a>
chore(deps): bump picomatch in the npm_and_yarn group across 1 directory
(<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/93">#93</a>)</li>
<li><a
href="ed274cae24"><code>ed274ca</code></a>
chore(deps): bump the minor group with 48 updates (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/96">#96</a>)</li>
<li><a
href="cd701b29d8"><code>cd701b2</code></a>
chore: Use dependabot for NPM packages too (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/94">#94</a>)</li>
<li>See full diff in <a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.17.0...v0.17.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.84 to 0.2.87
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases"><code>@​anthropic-ai/claude-agent-sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v0.2.87</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.87</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.87
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.87
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.87
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.87
</code></pre>
<h2>v0.2.86</h2>
<h2>What's changed</h2>
<ul>
<li>Added <code>getContextUsage()</code> control method to retrieve a
breakdown of context window usage by category</li>
<li>Made <code>session_id</code> optional in <code>SDKUserMessage</code>
type — callers no longer need to provide a session ID when sending user
messages, as the SDK assigns one automatically</li>
<li>Fixed TypeScript types resolving to <code>any</code> by adding
<code>@anthropic-ai/sdk</code> and
<code>@modelcontextprotocol/sdk</code> as dependencies</li>
<li>Updated to parity with Claude Code v2.1.86</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.86
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.86
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.86
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.86
</code></pre>
<h2>v0.2.85</h2>
<h2>What's changed</h2>
<ul>
<li>Added <code>reloadPlugins()</code> SDK method to reload plugins and
receive refreshed commands, agents, and MCP server status</li>
<li>Fixed PreToolUse hooks with <code>permissionDecision:
&quot;ask&quot;</code> being ignored in SDK mode</li>
<li>Updated to parity with Claude Code v2.1.85</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.85
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.85
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md"><code>@​anthropic-ai/claude-agent-sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>0.2.87</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.87</li>
</ul>
<h2>0.2.86</h2>
<ul>
<li>Added <code>getContextUsage()</code> control method to retrieve a
breakdown of context window usage by category</li>
<li>Made <code>session_id</code> optional in <code>SDKUserMessage</code>
type — callers no longer need to provide a session ID when sending user
messages, as the SDK assigns one automatically</li>
<li>Fixed TypeScript types resolving to <code>any</code> by adding
<code>@anthropic-ai/sdk</code> and
<code>@modelcontextprotocol/sdk</code> as dependencies</li>
<li>Updated to parity with Claude Code v2.1.86</li>
</ul>
<h2>0.2.85</h2>
<ul>
<li>Added <code>reloadPlugins()</code> SDK method to reload plugins and
receive refreshed commands, agents, and MCP server status</li>
<li>Fixed PreToolUse hooks with <code>permissionDecision:
&quot;ask&quot;</code> being ignored in SDK mode</li>
<li>Updated to parity with Claude Code v2.1.85</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="af1bd5387b"><code>af1bd53</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="86b848bcf6"><code>86b848b</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="0f3a95b224"><code>0f3a95b</code></a>
chore: Update CHANGELOG.md</li>
<li>See full diff in <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/compare/v0.2.84...v0.2.87">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li><a
href="6f97b55ddc"><code>6f97b55</code></a>
feat: disable colors if agent is detected (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/9851">#9851</a>)</li>
<li><a
href="b3c992cb29"><code>b3c992c</code></a>
fix(coverage): correct <code>coverageConfigDefaults</code> values and
types (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/9940">#9940</a>)</li>
<li><a
href="7c06598dbb"><code>7c06598</code></a>
fix: ensure sequential mock/unmock resolution (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/9830">#9830</a>)</li>
<li><a
href="f54abad136"><code>f54abad</code></a>
chore: add typo-checker skill and fix typos (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/9963">#9963</a>)</li>
<li><a
href="7aa9377764"><code>7aa9377</code></a>
fix: don't resolve <code>setupFiles</code> from parent directory (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/9960">#9960</a>)</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Updates `@napi-rs/wasm-runtime` from 1.1.1 to 1.1.2
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/napi-rs/napi-rs/commits/@napi-rs/wasm-runtime@1.1.2/wasi-runtime">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/expect` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/expect</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li><a
href="faace1fbe0"><code>faace1f</code></a>
fix(browser): take failure screenshot if <code>toMatchScreenshot</code>
can't capture a ...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/expect">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/mocker` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/mocker</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/mocker">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/pretty-format` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/pretty-format</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li><a
href="d3b7a40fa8"><code>d3b7a40</code></a>
fix(pretty-format): fix output limit over counting (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/pretty-format/issues/9965">#9965</a>)</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/pretty-format">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/runner` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/runner</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/runner">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/snapshot` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/snapshot</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/snapshot">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/spy` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/spy</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/spy">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitest/utils` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases"><code>@​vitest/utils</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<p>This release bumps Vitest's <code>flatted</code> version and removes
version pinning to resolve <code>flatted</code>'s CVE related issues (<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9975">vitest-dev/vitest#9975</a>).</p>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Don't resolve <code>setupFiles</code> from parent directory  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9960">vitest-dev/vitest#9960</a>
<a href="https://github.com/vitest-dev/vitest/commit/7aa937776"><!-- raw
HTML omitted -->(7aa93)<!-- raw HTML omitted --></a></li>
<li>Ensure sequential mock/unmock resolution  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Claude Opus 4.6</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9830">vitest-dev/vitest#9830</a>
<a href="https://github.com/vitest-dev/vitest/commit/7c06598db"><!-- raw
HTML omitted -->(7c065)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Take failure screenshot if
<code>toMatchScreenshot</code> can't capture a stable screenshot  -  by
<a href="https://github.com/macarie"><code>@​macarie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9847">vitest-dev/vitest#9847</a>
<a href="https://github.com/vitest-dev/vitest/commit/faace1fbe"><!-- raw
HTML omitted -->(faace)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Correct
<code>coverageConfigDefaults</code> values and types  -  by <a
href="https://github.com/Arthie"><code>@​Arthie</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9940">vitest-dev/vitest#9940</a>
<a href="https://github.com/vitest-dev/vitest/commit/b3c992cb2"><!-- raw
HTML omitted -->(b3c99)<!-- raw HTML omitted --></a></li>
<li><strong>pretty-format</strong>: Fix output limit over counting  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9965">vitest-dev/vitest#9965</a>
<a href="https://github.com/vitest-dev/vitest/commit/d3b7a40fa"><!-- raw
HTML omitted -->(d3b7a)<!-- raw HTML omitted --></a></li>
<li>Disable colors if agent is detected  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/9851">vitest-dev/vitest#9851</a>
<a href="https://github.com/vitest-dev/vitest/commit/6f97b55dd"><!-- raw
HTML omitted -->(6f97b)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6f482f4c"><code>fc6f482</code></a>
chore: release v4.1.2</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/utils">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 11:58:51 +02:00
dependabot[bot]
ee324b54dd chore(deps-dev): bump @anthropic-ai/sdk from 0.80.0 to 0.81.0 (#499)
Bumps
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
from 0.80.0 to 0.81.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/anthropic-sdk-typescript/releases"><code>@​anthropic-ai/sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>sdk: v0.81.0</h2>
<h2>0.81.0 (2026-03-31)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.80.0...sdk-v0.81.0">sdk-v0.80.0...sdk-v0.81.0</a></p>
<h3>Features</h3>
<ul>
<li>add .type field to APIError for error kind identification (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/790">#790</a>)
(<a
href="4bf637d962">4bf637d</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> append path separator in validatePath
prefix check (<a
href="0ac69b3438">0ac69b3</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>ci:</strong> run builds on CI even if only spec metadata
changed (<a
href="70b657aac1">70b657a</a>)</li>
<li><strong>ci:</strong> skip lint on metadata-only changes (<a
href="69bdc94a16">69bdc94</a>)</li>
<li><strong>internal:</strong> codegen related update (<a
href="7ff7390029">7ff7390</a>)</li>
<li><strong>internal:</strong> update gitignore (<a
href="46d66675d5">46d6667</a>)</li>
<li><strong>internal:</strong> update multipart form array serialization
(<a
href="d55b07d4f7">d55b07d</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.4 (<a
href="4957a5e65b">4957a5e</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.5 (<a
href="c511ae0421">c511ae0</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.6 (<a
href="6d2b4b910a">6d2b4b9</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.7 (<a
href="d6cff9d2c8">d6cff9d</a>)</li>
<li><strong>tests:</strong> bump steady to v0.20.1 (<a
href="284561fe36">284561f</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/anthropic-sdk-typescript/blob/main/CHANGELOG.md"><code>@​anthropic-ai/sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>0.81.0 (2026-03-31)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.80.0...sdk-v0.81.0">sdk-v0.80.0...sdk-v0.81.0</a></p>
<h3>Features</h3>
<ul>
<li>add .type field to APIError for error kind identification (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/790">#790</a>)
(<a
href="4bf637d962">4bf637d</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> append path separator in validatePath
prefix check (<a
href="0ac69b3438">0ac69b3</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>ci:</strong> run builds on CI even if only spec metadata
changed (<a
href="70b657aac1">70b657a</a>)</li>
<li><strong>ci:</strong> skip lint on metadata-only changes (<a
href="69bdc94a16">69bdc94</a>)</li>
<li><strong>internal:</strong> codegen related update (<a
href="7ff7390029">7ff7390</a>)</li>
<li><strong>internal:</strong> update gitignore (<a
href="46d66675d5">46d6667</a>)</li>
<li><strong>internal:</strong> update multipart form array serialization
(<a
href="d55b07d4f7">d55b07d</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.4 (<a
href="4957a5e65b">4957a5e</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.5 (<a
href="c511ae0421">c511ae0</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.6 (<a
href="6d2b4b910a">6d2b4b9</a>)</li>
<li><strong>tests:</strong> bump steady to v0.19.7 (<a
href="d6cff9d2c8">d6cff9d</a>)</li>
<li><strong>tests:</strong> bump steady to v0.20.1 (<a
href="284561fe36">284561f</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bc1a2ff79c"><code>bc1a2ff</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/955">#955</a>)</li>
<li>See full diff in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.80.0...sdk-v0.81.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@anthropic-ai/sdk&package-manager=npm_and_yarn&previous-version=0.80.0&new-version=0.81.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/agentclientprotocol/claude-agent-acp/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-02 07:10:40 +02:00
Tim Visher
d07799d7b3 fix: use current model's context window for usage_update size (#412)
The `usage_update` notification reports `size: 200000` even when the
active model has a 1M context window (e.g. `opus[1m]`), causing clients
to display incorrect context utilization (e.g. `689k/200k (344.3%)`
instead of `689k/1000k (68.9%)`).

Four bugs fixed:

- **Min across all models**: The original code used `Math.min` across
all `modelUsage` entries, so subagent models (Sonnet/Haiku with 200k
windows) dragged down the reported size for the main Opus 1M model. Now
tracks the top-level assistant model and looks up its context window
specifically.
- **Model name mismatch**: The SDK's streaming path keys `modelUsage` by
the requested model alias (e.g. `claude-opus-4-6`) while
`BetaMessage.model` on assistant messages has the resolved API response
model (e.g. `claude-opus-4-6-20250514`). The exact-match lookup always
missed, falling back to the hardcoded 200k default. Now falls back to
prefix matching, preferring the longest/most-specific match.
- **Synthetic messages corrupt model tracking**: `/compact` and similar
commands emit assistant messages with `model: "<synthetic>"`. These were
updating `lastAssistantModel`, causing the next `usage_update` to miss
the `modelUsage` lookup and fall back to the 200k default. Now filters
out `<synthetic>` models.
- **Stale usage after compaction**: No `usage_update` was sent on
`compact_boundary`, so clients kept showing the pre-compaction context
size (e.g. `944k/1m`) right after "Compacting completed" until the next
full turn. Now sends `used: 0` immediately on compaction. This is a
deliberate approximation — the exact post-compaction size isn't known
until the SDK's next API call, which replaces it within seconds. The
alternative (no update) is worse UX: showing a full context bar right
after compaction.

Eight new tests cover: token sum correctness, current-model context
window lookup, model switching, subagent isolation, prefix matching in
both directions, and synthetic message filtering.

Note: `bin/test` (local CI validation script) is cherry-picked from
#353.

Would fix `agent-shell`'s usage indicator which currently has to defend
against this broken math:
https://github.com/xenodium/agent-shell/pull/364

## Testing

- [x] Manual riding with it for a bit.

---------

Co-authored-by: Tim Visher <194828183+timvisher-dd@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Steffen Deusch <steffen@deusch.me>
2026-03-30 14:09:30 +02:00
tbounsiar
7506223cff fix: prevent race conditions in SettingsManager setCwd and debounce (#485)
## Summary

- **Concurrent `setCwd()` calls** could produce duplicate file watchers
because both calls cleared `initialized` before either completed
`initialize()`. Added an `initPromise` guard so concurrent calls await
the same initialization.
- **Debounce timer callback** could fire after `dispose()`, reloading
stale settings and calling `onChange` on a disposed manager. Added a
`disposed` flag checked in the async callback before proceeding.

Follows up on #454 which fixed the missing `dispose()` calls — this PR
hardens the `SettingsManager` lifecycle against race conditions.

## Test plan

- [x] `npm run lint` passes
- [x] All settings tests pass
- [x] Verified `disposed` flag prevents stale callback execution
- [x] Verified `initPromise` deduplicates concurrent `initialize()`
calls
2026-03-27 12:12:19 +00:00
tbounsiar
ae6c388314 fix: log warnings for malformed settings files instead of silent fallback (#486)
## Summary

- `loadSettingsFile()` silently returned `{}` for **all** errors
including malformed JSON, permission errors, and unexpected file content
- Only `ENOENT` (file not found) should be silent since missing settings
files are expected
- Other errors now log a warning via the logger to help diagnose
misconfigured settings (e.g. a typo in `settings.json` was previously
completely invisible)

## Test plan

- [x] `npm run lint` passes
- [x] All settings tests pass
- [x] Missing files still return `{}` silently (ENOENT path unchanged)
- [x] Malformed JSON now produces a logged warning
2026-03-27 12:10:24 +00:00
acp-release-bot[bot]
320f4d70a1 chore(main): release 0.24.2 (#488)
🤖 I have created a release *beep* *boop*
---


##
[0.24.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.1...v0.24.2)
(2026-03-27)


### Bug Fixes

* Add explicit type checks for MCP servers (http/sse)
([#487](https://github.com/agentclientprotocol/claude-agent-acp/issues/487))
([e00a439](e00a43901f))

---
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-03-27 12:26:03 +01:00
czp
e00a43901f fix: Add explicit type checks for MCP servers (http/sse) (#487)
As mentioned in
https://github.com/agentclientprotocol/claude-agent-acp/issues/468#issuecomment-4141841845

IDEA always explicitly passes the MCP server type; for example, even if
the type is `stdio`, IDEA will still pass `type: 'stdio'`.

This causes the following code to enter the http or sse branch due to
the presence of the 'type' field

<img width="644" height="483" alt="Image"
src="https://github.com/user-attachments/assets/4919ae2a-456f-461a-93b8-d914489f444c"
/>

As part of defensive programming, change this line to a more robust
check:

`if ("type" in server && (server.type === "http" || server.type ===
"sse"))`
2026-03-27 11:24:47 +00:00
acp-release-bot[bot]
93d87c2e71 chore(main): release 0.24.1 (#483)
🤖 I have created a release *beep* *boop*
---


##
[0.24.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.0...v0.24.1)
(2026-03-26)


### Bug Fixes

* Cleanup based on new idle state
[#463](https://github.com/agentclientprotocol/claude-agent-acp/issues/463)
([#480](https://github.com/agentclientprotocol/claude-agent-acp/issues/480))
([23b3073](23b3073025))

---
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-03-26 15:08:33 +01:00
Ben Brandt
fe94156852 chore: Fix format issues for release-please (#484) 2026-03-26 14:02:56 +00:00
dependabot[bot]
3c6cb3208b Bump the minor group with 2 updates (#478)
Bumps the minor group with 2 updates:
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.83 to 0.2.84
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases"><code>@​anthropic-ai/claude-agent-sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v0.2.84</h2>
<h2>What's changed</h2>
<ul>
<li>Added <code>taskBudget</code> option for API-side token budget
awareness, allowing the model to pace tool use within a token limit</li>
<li>Added <code>enableChannel()</code> method and
<code>capabilities</code> field on <code>McpServerStatus</code> for
SDK-driven MCP channel activation</li>
<li>Exported <code>EffortLevel</code> type (<code>'low' | 'medium' |
'high' | 'max'</code>) for consumers to reference effort values
directly</li>
<li>Fixed showing &quot;[Request interrupted by user]&quot; for errors
that were not caused by user interruption</li>
<li>Updated to parity with Claude Code v2.1.84</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.84
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.84
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.84
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.84
</code></pre>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md"><code>@​anthropic-ai/claude-agent-sdk</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>0.2.84</h2>
<ul>
<li>Added <code>taskBudget</code> option for API-side token budget
awareness, allowing the model to pace tool use within a token limit</li>
<li>Added <code>enableChannel()</code> method and
<code>capabilities</code> field on <code>McpServerStatus</code> for
SDK-driven MCP channel activation</li>
<li>Exported <code>EffortLevel</code> type (<code>'low' | 'medium' |
'high' | 'max'</code>) for consumers to reference effort values
directly</li>
<li>Fixed showing &quot;[Request interrupted by user]&quot; for errors
that were not caused by user interruption</li>
<li>Updated to parity with Claude Code v2.1.84</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ba2688c1d4"><code>ba2688c</code></a>
chore: Update CHANGELOG.md</li>
<li>See full diff in <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/compare/v0.2.83...v0.2.84">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.0.2 to 8.0.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>create-vite@8.0.3</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/create-vite@8.0.3/packages/create-vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.0.3</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.0.3/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.0.2...v8.0.3">8.0.3</a>
(2026-03-26)<!-- raw HTML omitted --></h2>
<h3>Features</h3>
<ul>
<li>update rolldown to 1.0.0-rc.12 (<a
href="https://redirect.github.com/vitejs/vite/issues/22024">#22024</a>)
(<a
href="84164ef47b">84164ef</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>html:</strong> cache unfiltered CSS list to prevent missing
styles across entries (<a
href="https://redirect.github.com/vitejs/vite/issues/22017">#22017</a>)
(<a
href="5464190a3e">5464190</a>)</li>
<li><strong>module-runner:</strong> handle non-ascii characters in
base64 sourcemaps (<a
href="https://redirect.github.com/vitejs/vite/issues/21985">#21985</a>)
(<a
href="77c95bff83">77c95bf</a>)</li>
<li><strong>module-runner:</strong> skip re-import if the runner is
closed (<a
href="https://redirect.github.com/vitejs/vite/issues/22020">#22020</a>)
(<a
href="ee2c2cd2c2">ee2c2cd</a>)</li>
<li><strong>optimizer:</strong> scan is not resolving sub path import if
used in a glob import (<a
href="https://redirect.github.com/vitejs/vite/issues/22018">#22018</a>)
(<a
href="ddfe20d19e">ddfe20d</a>)</li>
<li><strong>ssr:</strong> ssrTransform incorrectly rewrites
<code>meta</code> identifier inside <code>import.meta</code> when a
binding named <code>meta</code> exists (<a
href="https://redirect.github.com/vitejs/vite/issues/22019">#22019</a>)
(<a
href="cff5f0cca5">cff5f0c</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li><strong>deps:</strong> bump picomatch from 4.0.3 to 4.0.4 (<a
href="https://redirect.github.com/vitejs/vite/issues/22027">#22027</a>)
(<a
href="7e56003fec">7e56003</a>)</li>
</ul>
<h3>Tests</h3>
<ul>
<li><strong>html:</strong> add tests for
<code>getCssFilesForChunk</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22016">#22016</a>)
(<a
href="43fbbf9a09">43fbbf9</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6a34ac3422"><code>6a34ac3</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21096">#21096</a>)</li>
<li><a
href="02ceaec45e"><code>02ceaec</code></a>
chore(deps): update dependency <code>@​rollup/plugin-commonjs</code> to
v29 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21099">#21099</a>)</li>
<li><a
href="572aaca459"><code>572aaca</code></a>
release: v7.2.2</li>
<li><a
href="728c8eeebc"><code>728c8ee</code></a>
fix: revert &quot;refactor: use fs.cpSync (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21019">#21019</a>)&quot;
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21081">#21081</a>)</li>
<li><a
href="a532e68c6b"><code>a532e68</code></a>
release: v7.2.1</li>
<li><a
href="82d2d6ccf5"><code>82d2d6c</code></a>
fix(worker): some worker asset was missing (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21074">#21074</a>)</li>
<li><a
href="f83264f5d9"><code>f83264f</code></a>
refactor(build): rename <code>indexOfMatchInSlice</code> to
<code>findPreloadMarker</code> (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21054">#21054</a>)</li>
<li><a
href="8293de0e17"><code>8293de0</code></a>
release: v7.2.0</li>
<li><a
href="2833c5576a"><code>2833c55</code></a>
fix(types): add undefined to optional properties for
exactOptionalProperties ...</li>
<li><a
href="e3a6a83406"><code>e3a6a83</code></a>
chore(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21047">#21047</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/create-vite@8.0.3/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 15:00:31 +01:00
Ben Brandt
cf16fabcc4 test: Fix incorrect vi.hoisted() placement in the authorization test module (#482) 2026-03-26 14:57:57 +01:00
Steffen Deusch
23b3073025 fix: Cleanup based on new idle state #463 (#480)
#463 introduced a problem with cancelling prompts. Because cancel exited
the loop early, the idle session state message was not consumed. Then,
in the next prompt, we'd immediately get the idle state and assume it's
done.

Instead, we always wait for the idle state (and still finish early when
detecting a queued prompt).

Note that this is based on my tests that showed Claude only sending the
idle state when all background agents are done.

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-26 13:57:40 +00:00
Ben Brandt
2bf75c1a9f Fix MCP command argument spacing (#481) 2026-03-26 12:51:44 +01:00
dependabot[bot]
27395a196d Bump oven-sh/setup-bun from 2.1.2 to 2.2.0 (#477)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [oven-sh/setup-bun](https://github.com/oven-sh/setup-bun) from
2.1.2 to 2.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oven-sh/setup-bun/releases">oven-sh/setup-bun's
releases</a>.</em></p>
<blockquote>
<h2>v2.2.0</h2>
<p><code>oven-sh/setup-bun</code> is the github action for setting up
Bun.</p>
<h2>What's Changed</h2>
<ul>
<li>build: update action runtime to Node.js 24 by <a
href="https://github.com/adam0white"><code>@​adam0white</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/176">oven-sh/setup-bun#176</a></li>
<li>ci: use <code>actions/checkout@v6.0.2</code> in the test workflow by
<a href="https://github.com/tcely"><code>@​tcely</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/173">oven-sh/setup-bun#173</a></li>
<li>ci: update actions for the <code>autofix.ci</code> workflow by <a
href="https://github.com/tcely"><code>@​tcely</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/174">oven-sh/setup-bun#174</a></li>
<li>ci: update actions for the <code>Release new action version</code>
workflow by <a href="https://github.com/tcely"><code>@​tcely</code></a>
in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/175">oven-sh/setup-bun#175</a></li>
<li>release: v2.2.0 by <a
href="https://github.com/xhyrom"><code>@​xhyrom</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/177">oven-sh/setup-bun#177</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/adam0white"><code>@​adam0white</code></a> made
their first contribution in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/176">oven-sh/setup-bun#176</a></li>
<li><a href="https://github.com/tcely"><code>@​tcely</code></a> made
their first contribution in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/173">oven-sh/setup-bun#173</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/oven-sh/setup-bun/compare/v2...v2.2.0">https://github.com/oven-sh/setup-bun/compare/v2...v2.2.0</a></p>
<h2>v2.1.3</h2>
<p><code>oven-sh/setup-bun</code> is the github action for setting up
Bun.</p>
<h2>What's Changed</h2>
<ul>
<li>perf: avoid unnecessary api calls by <a
href="https://github.com/xhyrom"><code>@​xhyrom</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/161">oven-sh/setup-bun#161</a></li>
<li>feat: add bun- prefix to cache keys by <a
href="https://github.com/maschwenk"><code>@​maschwenk</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/160">oven-sh/setup-bun#160</a></li>
<li>fix: use native Windows ARM64 binary for Bun &gt;= 1.3.10 by <a
href="https://github.com/oddrationale"><code>@​oddrationale</code></a>
in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/165">oven-sh/setup-bun#165</a></li>
<li>feat: add AVX2 support detection for x64 Linux systems by <a
href="https://github.com/GoForceX"><code>@​GoForceX</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/167">oven-sh/setup-bun#167</a></li>
<li>fix: validate cached binary version matches requested version (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/146">#146</a>)
by <a href="https://github.com/wyMinLwin"><code>@​wyMinLwin</code></a>
in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/169">oven-sh/setup-bun#169</a></li>
<li>release: v2.1.3 by <a
href="https://github.com/xhyrom"><code>@​xhyrom</code></a> in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/170">oven-sh/setup-bun#170</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/oddrationale"><code>@​oddrationale</code></a>
made their first contribution in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/165">oven-sh/setup-bun#165</a></li>
<li><a href="https://github.com/GoForceX"><code>@​GoForceX</code></a>
made their first contribution in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/167">oven-sh/setup-bun#167</a></li>
<li><a href="https://github.com/wyMinLwin"><code>@​wyMinLwin</code></a>
made their first contribution in <a
href="https://redirect.github.com/oven-sh/setup-bun/pull/169">oven-sh/setup-bun#169</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/oven-sh/setup-bun/compare/v2...v2.1.3">https://github.com/oven-sh/setup-bun/compare/v2...v2.1.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0c5077e514"><code>0c5077e</code></a>
release: v2.2.0 (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/177">#177</a>)</li>
<li><a
href="1255e43b02"><code>1255e43</code></a>
ci: update actions for the <code>Release new action version</code>
workflow (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/175">#175</a>)</li>
<li><a
href="61861d1f6a"><code>61861d1</code></a>
ci: update actions for the <code>autofix.ci</code> workflow (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/174">#174</a>)</li>
<li><a
href="6f5bd063f5"><code>6f5bd06</code></a>
ci: use <code>actions/checkout@v6.0.2</code> in the test workflow (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/173">#173</a>)</li>
<li><a
href="e3914758a4"><code>e391475</code></a>
build: update action runtime to Node.js 24 (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/176">#176</a>)</li>
<li><a
href="ecf28ddc73"><code>ecf28dd</code></a>
release: v2.1.3 (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/170">#170</a>)</li>
<li><a
href="95edc153a3"><code>95edc15</code></a>
fix: validate cached binary version matches requested version (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/146">#146</a>)
(<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/169">#169</a>)</li>
<li><a
href="4c32875876"><code>4c32875</code></a>
feat: add AVX2 support detection for x64 Linux systems (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/167">#167</a>)</li>
<li><a
href="0ff83bfc51"><code>0ff83bf</code></a>
fix: use native Windows ARM64 binary for Bun &gt;= 1.3.10 (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/165">#165</a>)</li>
<li><a
href="ab8cb4e8f8"><code>ab8cb4e</code></a>
feat: add bun- prefix to cache keys (<a
href="https://redirect.github.com/oven-sh/setup-bun/issues/160">#160</a>)</li>
<li>Additional commits viewable in <a
href="3d267786b1...0c5077e514">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=oven-sh/setup-bun&package-manager=github_actions&previous-version=2.1.2&new-version=2.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 12:23:18 +01:00
dependabot[bot]
a7b3e3c97d Bump actions/upload-artifact from 6.0.0 to 7.0.0 (#476)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 6.0.0 to 7.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>v7 What's new</h2>
<h3>Direct Uploads</h3>
<p>Adds support for uploading single files directly (unzipped). Callers
can set the new <code>archive</code> parameter to <code>false</code> to
skip zipping the file during upload. Right now, we only support single
files. The action will fail if the glob passed resolves to multiple
files. The <code>name</code> parameter is also ignored with this
setting. Instead, the name of the artifact will be the name of the
uploaded file.</p>
<h3>ESM</h3>
<p>To support new versions of the <code>@actions/*</code> packages,
we've upgraded the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Add proxy integration test by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
<li>Upgrade the module to ESM and bump dependencies by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/762">actions/upload-artifact#762</a></li>
<li>Support direct file uploads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/764">actions/upload-artifact#764</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Link"><code>@​Link</code></a>- made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v6...v7.0.0">https://github.com/actions/upload-artifact/compare/v6...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bbbca2ddaa"><code>bbbca2d</code></a>
Support direct file uploads (<a
href="https://redirect.github.com/actions/upload-artifact/issues/764">#764</a>)</li>
<li><a
href="589182c5a4"><code>589182c</code></a>
Upgrade the module to ESM and bump dependencies (<a
href="https://redirect.github.com/actions/upload-artifact/issues/762">#762</a>)</li>
<li><a
href="47309c993a"><code>47309c9</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/754">#754</a>
from actions/Link-/add-proxy-integration-tests</li>
<li><a
href="02a8460834"><code>02a8460</code></a>
Add proxy integration test</li>
<li>See full diff in <a
href="b7c566a772...bbbca2ddaa">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=6.0.0&new-version=7.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 12:23:03 +01:00
dependabot[bot]
886b9b3a75 Bump actions/checkout from 5.0.0 to 6.0.2 (#475)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0
to 6.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID
is set by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p>
<h2>v6.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update all references from v5 and v4 to v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
<li>Clarify v6 README by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>v6-beta by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li>
<li>update readme/changelog for v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2311">actions/checkout#2311</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5.0.0...v6.0.0">https://github.com/actions/checkout/compare/v5.0.0...v6.0.0</a></p>
<h2>v6-beta</h2>
<h2>What's Changed</h2>
<p>Updated persist-credentials to store the credentials under
<code>$RUNNER_TEMP</code> instead of directly in the local git
config.</p>
<p>This requires a minimum Actions Runner version of <a
href="https://github.com/actions/runner/releases/tag/v2.329.0">v2.329.0</a>
to access the persisted credentials for <a
href="https://docs.github.com/en/actions/tutorials/use-containerized-services/create-a-docker-container-action">Docker
container action</a> scenarios.</p>
<h2>v5.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5...v5.0.1">https://github.com/actions/checkout/compare/v5...v5.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="de0fac2e45"><code>de0fac2</code></a>
Fix tag handling: preserve annotations and explicit fetch-tags (<a
href="https://redirect.github.com/actions/checkout/issues/2356">#2356</a>)</li>
<li><a
href="064fe7f331"><code>064fe7f</code></a>
Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is
set (...</li>
<li><a
href="8e8c483db8"><code>8e8c483</code></a>
Clarify v6 README (<a
href="https://redirect.github.com/actions/checkout/issues/2328">#2328</a>)</li>
<li><a
href="033fa0dc0b"><code>033fa0d</code></a>
Add worktree support for persist-credentials includeIf (<a
href="https://redirect.github.com/actions/checkout/issues/2327">#2327</a>)</li>
<li><a
href="c2d88d3ecc"><code>c2d88d3</code></a>
Update all references from v5 and v4 to v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2314">#2314</a>)</li>
<li><a
href="1af3b93b68"><code>1af3b93</code></a>
update readme/changelog for v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2311">#2311</a>)</li>
<li><a
href="71cf2267d8"><code>71cf226</code></a>
v6-beta (<a
href="https://redirect.github.com/actions/checkout/issues/2298">#2298</a>)</li>
<li><a
href="069c695914"><code>069c695</code></a>
Persist creds to a separate file (<a
href="https://redirect.github.com/actions/checkout/issues/2286">#2286</a>)</li>
<li><a
href="ff7abcd0c3"><code>ff7abcd</code></a>
Update README to include Node.js 24 support details and requirements (<a
href="https://redirect.github.com/actions/checkout/issues/2248">#2248</a>)</li>
<li>See full diff in <a
href="08c6903cd8...de0fac2e45">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=5.0.0&new-version=6.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 12:22:53 +01:00
dependabot[bot]
f919d615eb Bump actions/setup-node from 4.4.0 to 6.3.0 (#474)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from
4.4.0 to 6.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-node/releases">actions/setup-node's
releases</a>.</em></p>
<blockquote>
<h2>v6.3.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Support parsing <code>devEngines</code> field by <a
href="https://github.com/susnux"><code>@​susnux</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1283">actions/setup-node#1283</a></li>
</ul>
<blockquote>
<p>When using node-version-file: package.json, setup-node now
prefers devEngines.runtime over engines.node.</p>
</blockquote>
<h3>Dependency updates:</h3>
<ul>
<li>Fix npm audit issues by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1491">actions/setup-node#1491</a></li>
<li>Replace uuid with crypto.randomUUID() by <a
href="https://github.com/trivikr"><code>@​trivikr</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1378">actions/setup-node#1378</a></li>
<li>Upgrade minimatch from 3.1.2 to 3.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1498">actions/setup-node#1498</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Remove hardcoded bearer for mirror-url <a
href="https://github.com/marco-ippolito"><code>@​marco-ippolito</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1467">actions/setup-node#1467</a></li>
<li>Scope test lockfiles by package manager and update cache tests by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1495">actions/setup-node#1495</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/susnux"><code>@​susnux</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1283">actions/setup-node#1283</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v6.3.0">https://github.com/actions/setup-node/compare/v6...v6.3.0</a></p>
<h2>v6.2.0</h2>
<h2>What's Changed</h2>
<h3>Documentation</h3>
<ul>
<li>Documentation update related to absence of Lockfile by <a
href="https://github.com/mahabaleshwars"><code>@​mahabaleshwars</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1454">actions/setup-node#1454</a></li>
<li>Correct mirror option typos by <a
href="https://github.com/MikeMcC399"><code>@​MikeMcC399</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1442">actions/setup-node#1442</a></li>
<li>Readme update on checkout version v6 by <a
href="https://github.com/deining"><code>@​deining</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1446">actions/setup-node#1446</a></li>
<li>Readme typo fixes <a
href="https://github.com/munyari"><code>@​munyari</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1226">actions/setup-node#1226</a></li>
<li>Advanced document update on checkout version v6 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1468">actions/setup-node#1468</a></li>
</ul>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade <code>@​actions/cache</code> to v5.0.1 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1449">actions/setup-node#1449</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/mahabaleshwars"><code>@​mahabaleshwars</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1454">actions/setup-node#1454</a></li>
<li><a
href="https://github.com/MikeMcC399"><code>@​MikeMcC399</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1442">actions/setup-node#1442</a></li>
<li><a href="https://github.com/deining"><code>@​deining</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1446">actions/setup-node#1446</a></li>
<li><a href="https://github.com/munyari"><code>@​munyari</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1226">actions/setup-node#1226</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v6.2.0">https://github.com/actions/setup-node/compare/v6...v6.2.0</a></p>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<h3>Enhancement:</h3>
<ul>
<li>Remove always-auth configuration handling by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1436">actions/setup-node#1436</a></li>
</ul>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade <code>@​actions/cache</code> from 4.0.3 to 4.1.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-node/pull/1384">actions/setup-node#1384</a></li>
<li>Upgrade actions/checkout from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-node/pull/1439">actions/setup-node#1439</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="53b83947a5"><code>53b8394</code></a>
Bump minimatch from 3.1.2 to 3.1.5 (<a
href="https://redirect.github.com/actions/setup-node/issues/1498">#1498</a>)</li>
<li><a
href="54045abd5d"><code>54045ab</code></a>
Scope test lockfiles by package manager and update cache tests (<a
href="https://redirect.github.com/actions/setup-node/issues/1495">#1495</a>)</li>
<li><a
href="c882bffdbd"><code>c882bff</code></a>
Replace uuid with crypto.randomUUID() (<a
href="https://redirect.github.com/actions/setup-node/issues/1378">#1378</a>)</li>
<li><a
href="774c1d6296"><code>774c1d6</code></a>
feat(node-version-file): support parsing <code>devEngines</code> field
(<a
href="https://redirect.github.com/actions/setup-node/issues/1283">#1283</a>)</li>
<li><a
href="efcb663fc6"><code>efcb663</code></a>
fix: remove hardcoded bearer (<a
href="https://redirect.github.com/actions/setup-node/issues/1467">#1467</a>)</li>
<li><a
href="d02c89dce7"><code>d02c89d</code></a>
Fix npm audit issues (<a
href="https://redirect.github.com/actions/setup-node/issues/1491">#1491</a>)</li>
<li><a
href="6044e13b5d"><code>6044e13</code></a>
Docs: bump actions/checkout from v5 to v6 (<a
href="https://redirect.github.com/actions/setup-node/issues/1468">#1468</a>)</li>
<li><a
href="8e494633d0"><code>8e49463</code></a>
Fix README typo (<a
href="https://redirect.github.com/actions/setup-node/issues/1226">#1226</a>)</li>
<li><a
href="621ac41091"><code>621ac41</code></a>
README.md: bump to latest released checkout version v6 (<a
href="https://redirect.github.com/actions/setup-node/issues/1446">#1446</a>)</li>
<li><a
href="2951748f4c"><code>2951748</code></a>
Bump <code>@​actions/cache</code> to v5.0.1 (<a
href="https://redirect.github.com/actions/setup-node/issues/1449">#1449</a>)</li>
<li>Additional commits viewable in <a
href="49933ea528...53b83947a5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-node&package-manager=github_actions&previous-version=4.4.0&new-version=6.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 12:22:43 +01:00
dependabot[bot]
f51f3a7937 Bump actions/download-artifact from 7.0.0 to 8.0.1 (#473)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 7.0.0 to 8.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v8.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Support for CJK characters in the artifact name by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/471">actions/download-artifact#471</a></li>
<li>Add a regression test for artifact name + content-type mismatches by
<a href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a>
in <a
href="https://redirect.github.com/actions/download-artifact/pull/472">actions/download-artifact#472</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v8...v8.0.1">https://github.com/actions/download-artifact/compare/v8...v8.0.1</a></p>
<h2>v8.0.0</h2>
<h2>v8 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/download-artifact@v8 has been migrated to an ESM module. This
should be transparent to the caller but forks might need to make
significant changes.</p>
</blockquote>
<blockquote>
<p>[!IMPORTANT]
Hash mismatches will now error by default. Users can override this
behavior with a setting change (see below).</p>
</blockquote>
<h3>Direct downloads</h3>
<p>To support direct uploads in <code>actions/upload-artifact</code>,
the action will no longer attempt to unzip all downloaded files.
Instead, the action checks the <code>Content-Type</code> header ahead of
unzipping and skips non-zipped files. Callers wishing to download a
zipped file as-is can also set the new <code>skip-decompress</code>
parameter to <code>true</code>.</p>
<h3>Enforced checks (breaking)</h3>
<p>A previous release introduced digest checks on the download. If a
download hash didn't match the expected hash from the server, the action
would log a warning. Callers can now configure the behavior on mismatch
with the <code>digest-mismatch</code> parameter. To be secure by
default, we are now defaulting the behavior to <code>error</code> which
will fail the workflow run.</p>
<h3>ESM</h3>
<p>To support new versions of the @actions/* packages, we've upgraded
the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Don't attempt to un-zip non-zipped downloads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/460">actions/download-artifact#460</a></li>
<li>Add a setting to specify what to do on hash mismatch and default it
to <code>error</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/461">actions/download-artifact#461</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v7...v8.0.0">https://github.com/actions/download-artifact/compare/v7...v8.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3e5f45b2cf"><code>3e5f45b</code></a>
Add regression tests for CJK characters (<a
href="https://redirect.github.com/actions/download-artifact/issues/471">#471</a>)</li>
<li><a
href="e6d03f6737"><code>e6d03f6</code></a>
Add a regression test for artifact name + content-type mismatches (<a
href="https://redirect.github.com/actions/download-artifact/issues/472">#472</a>)</li>
<li><a
href="70fc10c6e5"><code>70fc10c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/461">#461</a>
from actions/danwkennedy/digest-mismatch-behavior</li>
<li><a
href="f258da9a50"><code>f258da9</code></a>
Add change docs</li>
<li><a
href="ccc058e5fb"><code>ccc058e</code></a>
Fix linting issues</li>
<li><a
href="bd7976ba57"><code>bd7976b</code></a>
Add a setting to specify what to do on hash mismatch and default it to
<code>error</code></li>
<li><a
href="ac21fcf45e"><code>ac21fcf</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/460">#460</a>
from actions/danwkennedy/download-no-unzip</li>
<li><a
href="15999bff51"><code>15999bf</code></a>
Add note about package bumps</li>
<li><a
href="974686ed50"><code>974686e</code></a>
Bump the version to <code>v8</code> and add release notes</li>
<li><a
href="fbe48b1d27"><code>fbe48b1</code></a>
Update test names to make it clearer what they do</li>
<li>Additional commits viewable in <a
href="37930b1c2a...3e5f45b2cf">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=7.0.0&new-version=8.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 12:22:29 +01:00
Ben Brandt
b409782992 Update for ACP Org (#471) 2026-03-26 12:19:06 +01:00
Ben Brandt
ce4a67ae33 chore: bootstrap releases for path: . (#472)
Configuring release-please for path: .
2026-03-26 12:18:34 +01:00
Ben Brandt
5268661b7f Prep 0.23.1 release (#470) 2026-03-26 10:24:34 +00:00
Ben Brandt
9583f97536 Add back error_during_execution break point (#469)
Closes #468
2026-03-26 11:13:40 +01:00
Ben Brandt
95721e4e39 Prep 0.23.0 (#465) 2026-03-25 22:18:12 +00:00
Ben Brandt
7f1c6c2078 Use idle session state as end of turn (#463)
According to the type docs, this should be a more reliable indicator of
turn end:

> Mirrors notifySessionStateChanged. 'idle' fires after heldBackResult
  flushes and the bg-agent do-while exits — authoritative turn-over
  signal.
2026-03-25 22:50:01 +01:00
Ben Brandt
3500b6c16e Update claude-agent-sdk to 0.2.83 (#462) 2026-03-25 13:48:23 +00:00
qystishere
07db59ef0d Fix handling of local-only slash commands (#432)
Instead of parsing <local-command-stdout> tags from the message stream,
intercept these commands early and forward
the clean result from the success handler directly to the client.
Applies to /context, /heapdump, and /extra-usage.
2026-03-24 21:23:26 +00:00
tbounsiar
34c847a9e3 fix: correct null check for gatewayAuthMeta in subscription validation (#455)
## Summary

- `gatewayAuthMeta` is declared as an optional property (`undefined`
when unset), but the subscription validation compared it against `null`
- This made the condition always false, so `--hide-claude-auth` never
blocked claude.ai subscription users when no gateway was configured
- Changed `=== null` to `!this.gatewayAuthMeta` to match the actual
property semantics

## Test plan

- [x] `npm run build` compiles clean
- [x] `npm run lint` passes
- [x] All 6 authorization tests pass
2026-03-24 21:22:02 +00:00
tbounsiar
d2428a49ef fix: include both stdout and stderr in Bash tool output (#456)
## Summary

- When a Bash tool execution produced both stdout and stderr, only
stdout was shown due to the `||` operator short-circuiting
- Changed to concatenate both streams with `[stdout,
stderr].filter(Boolean).join("\n")` so error output is no longer
silently dropped

## Test plan

- [x] `npm run build` compiles clean
- [x] `npm run lint` passes
- [x] All 34 tools tests pass
2026-03-24 21:21:30 +00:00
tbounsiar
91d629d6c6 fix: prevent prompt loop hang when cancel races with first result (#458)
Fixes #442

## Summary

- When `cancel()` was called immediately after a prompt, the result
message arrived before `promptReplayed` was set to `true`
- The `!promptReplayed` check consumed it as a "background task result",
making the `session.cancelled` check unreachable
- The loop then blocked forever on `query.next()` since no further
messages would arrive
- Fix: move the `session.cancelled` check **before** the
`!promptReplayed` check so cancellation is always detected

## Test plan

- [x] `npm run build` compiles clean
- [x] `npm run lint` passes
- [x] All unit tests pass
- [x] Logic verified against the race condition sequence described in
#442
2026-03-24 21:19:35 +00:00
tbounsiar
5fd7873c7c fix: dispose SettingsManager on session close to prevent resource leaks (#454)
## Summary

- `SettingsManager.dispose()` was never called when a session was closed
via `unstable_closeSession` or when the Claude Agent process died
unexpectedly
- Each leaked session left up to 4 active `fs.watch()` file descriptors
and a pending debounce timer
- Added `session.settingsManager.dispose()` in both cleanup paths and
updated test mocks to assert the call

## Test plan

- [x] `npm run build` compiles clean
- [x] `npm run lint` passes
- [x] Existing `session/close` tests updated to verify `dispose()` is
called
- [x] All 4 session/close tests pass
2026-03-24 21:19:02 +00:00
Cengiz Han
83496544b2 fix: restore plan content in ExitPlanMode tool call (#451)
## Summary

The plan text was accidentally dropped from the `ExitPlanMode` content
array during the switch to built-in Claude Code tools (#316, commit
`be618f5`). This meant ACP clients could not display the plan when
asking the user for approval — they only saw the title "Ready to code?"
with no plan body.

We noticed this in the Fabriqa app where our plan approval UI was
rendering an empty card.

## What changed

Restored the original `input.plan` → `content` mapping in
`toolInfoFromToolUse()` so the plan markdown is included in the
`tool_call` and `request_permission` events.

**Before (broken):**
```typescript
case "ExitPlanMode": {
  return {
    title: "Ready to code?",
    kind: "switch_mode",
    content: [],
  };
}
```

**After (fixed):**
```typescript
case "ExitPlanMode": {
  const planInput = toolUse.input as { plan?: string };
  return {
    title: "Ready to code?",
    kind: "switch_mode",
    content:
      planInput?.plan
        ? [{ type: "content" as const, content: { type: "text" as const, text: planInput.plan } }]
        : [],
  };
}
```

## Where does `input.plan` come from?

The Claude Agent SDK passes tool inputs to the `canUseTool` callback as
`Record<string, unknown>` (see `Options.canUseTool` in
`@anthropic-ai/claude-agent-sdk/sdk.d.ts`). When Claude calls
`ExitPlanMode`, the model includes the plan text in the input.

The formal `ExitPlanModeInput` type (in
`@anthropic-ai/claude-agent-sdk/sdk-tools.d.ts`) only declares
`allowedPrompts`, but it has a `[k: string]: unknown` index signature
that allows additional properties. The model consistently sends `plan`
(string) and `planFilePath` (string). SDK v0.2.76 explicitly added
`planFilePath` to the tool input for hooks and SDK consumers, confirming
these fields are intentional.

The original implementation (commit `0289dd9`, "Support plan mode and
all other permission modes" #40) relied on `input.plan` and worked
correctly until the refactor in #316 dropped it.

### SDK history confirms `input.plan` is reliable

The Claude Agent SDK itself had a regression where `ExitPlanMode` input
was empty
([anthropics/claude-code#12288](https://github.com/anthropics/claude-code/issues/12288)):

| Version | Status |
|---------|--------|
| Claude Code 2.0.34 | `input.plan` populated |
| Claude Code 2.0.51 | Regression — `input: {}` empty |
| Agent SDK 0.1.54 | Fixed — `input.plan` restored |
| Agent SDK 0.2.76 (current) | Working — also added `planFilePath` |

The SDK team treated the empty input as a critical bug and fixed it
promptly. The current SDK (0.2.76) reliably sends `input.plan`, so this
adapter fix is safe to depend on.

## Test plan

- [x] Added test: plan text is included in content when `input.plan` is
provided
- [x] Added test: content is empty when `input.plan` is not provided
- [x] All existing tests pass

Fixes #450
2026-03-24 22:16:16 +01:00
dependabot[bot]
c5d5c11f40 Bump flatted from 3.4.1 to 3.4.2 in the npm_and_yarn group across 1 directory (#445)
Bumps the npm_and_yarn group with 1 update in the / directory:
[flatted](https://github.com/WebReflection/flatted).

Updates `flatted` from 3.4.1 to 3.4.2
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3bf09091c3"><code>3bf0909</code></a>
3.4.2</li>
<li><a
href="885ddcc33c"><code>885ddcc</code></a>
fix CWE-1321</li>
<li><a
href="0bdba705d1"><code>0bdba70</code></a>
added flatted-view to the benchmark</li>
<li>See full diff in <a
href="https://github.com/WebReflection/flatted/compare/v3.4.1...v3.4.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flatted&package-manager=npm_and_yarn&previous-version=3.4.1&new-version=3.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/zed-industries/claude-agent-acp/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 10:28:16 +01:00
Ben Brandt
521d1f766d Prep 0.22.2 release (#440) 2026-03-18 14:26:49 +00:00
Egor Baranov
f11435df13 Support additional skill directories via additionalRoots meta parameter (#406)
Add support for `_meta.additionalRoots` in `claude-agent-acp`.

This change introduces a top-level `additionalRoots` field in session
metadata and forwards it to Claude by merging it into
`additionalDirectories` when creating a session.

Behavior:
- reads `_meta.additionalRoots` from the ACP session request
- treats it as a `string[]`
- merges it with any user-provided
`claudeCode.options.additionalDirectories`
- passes the combined list through to Claude unchanged

This keeps `additionalRoots` as an ACP-level extension rather than a
Claude-specific option, while mapping it onto Claude's existing
`additionalDirectories` support.
2026-03-18 14:20:30 +00:00
22 changed files with 4077 additions and 662 deletions

18
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
allow:
- dependency-type: "all"
groups:
minor:
update-types:
- "minor"
- "patch"

View File

@@ -21,12 +21,12 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Use Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
with:
node-version: latest
node-version: "lts/*"
cache: "npm"
- name: Install dependencies

View File

@@ -1,14 +1,45 @@
name: Publish and Release
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
branches:
- main
jobs:
release-please:
runs-on: ubuntu-latest
environment: release # Optional: for enhanced security
permissions:
contents: write
issues: write
pull-requests: write
steps:
# Generating a GitHub token, so that PRs and tags created by
# the release-please-action can trigger actions workflows.
- name: Generate GitHub token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3
id: generate-token
with:
# GitHub App ID secret name
app-id: ${{ secrets.RELEASE_PLZ_APP_ID }}
# GitHub App private key secret name
private-key: ${{ secrets.RELEASE_PLZ_APP_PRIVATE_KEY }}
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071
id: release
with:
token: ${{ steps.generate-token.outputs.token }}
release-type: node
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
build-binaries:
name: Build (${{ matrix.target }})
runs-on: ubuntu-latest
needs: [release-please]
# TODO: Re-enable once Bun SDK compatibility is fixed
if: false
permissions:
contents: read
timeout-minutes: 15
@@ -43,9 +74,9 @@ jobs:
archive: claude-agent-acp-windows-arm64.zip
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest
@@ -69,7 +100,7 @@ jobs:
fi
- name: Upload artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: ${{ matrix.archive }}
path: ${{ matrix.archive }}
@@ -77,16 +108,16 @@ jobs:
publish-npm:
name: Publish to npm
runs-on: ubuntu-latest
needs: [build-binaries]
if: startsWith(github.ref, 'refs/tags/')
needs: [release-please]
if: ${{ needs.release-please.outputs.release_created }}
environment: release # Optional: for enhanced security
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
@@ -99,22 +130,27 @@ jobs:
release:
name: Create Release
runs-on: ubuntu-latest
needs: [build-binaries, publish-npm]
if: startsWith(github.ref, 'refs/tags/')
needs: [publish-npm, release-please]
# TODO: Re-enable once Bun SDK compatibility is fixed
if: false
permissions:
contents: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Download all artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
with:
path: artifacts
merge-multiple: true
- name: Create Release
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090
with:
generate_release_notes: true
files: artifacts/*
- name: Upload artifacts
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload \
"${{ needs.release-please.outputs.tag_name }}" \
artifacts/* \
--clobber

View File

@@ -1,3 +1,7 @@
node_modules
dist
.agent-shell
.release-please-manifest.json
release-please-config.json
CHANGELOG.md

View File

@@ -0,0 +1,3 @@
{
".": "0.29.2"
}

View File

@@ -1,5 +1,143 @@
# Changelog
## [0.29.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.1...v0.29.2) (2026-04-17)
### Bug Fixes
* Guard against null usage tokens ([#565](https://github.com/agentclientprotocol/claude-agent-acp/issues/565)) ([f7dc300](https://github.com/agentclientprotocol/claude-agent-acp/commit/f7dc300a165e70f6426f53920f12e24c04033cdc)), closes [#564](https://github.com/agentclientprotocol/claude-agent-acp/issues/564)
## [0.29.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.0...v0.29.1) (2026-04-17)
### Bug Fixes
* emit usage updates from Claude stream events ([#506](https://github.com/agentclientprotocol/claude-agent-acp/issues/506)) ([dd67450](https://github.com/agentclientprotocol/claude-agent-acp/commit/dd67450fd9bddc82db3e71273b535e07b2672804))
* Remove dot from auto mode description ([#561](https://github.com/agentclientprotocol/claude-agent-acp/issues/561)) ([2ecfa83](https://github.com/agentclientprotocol/claude-agent-acp/commit/2ecfa83b26db58deaded210463fa6ff21d0dff70))
* Update to claude-agent-sdk 0.2.112 to fix Auto bug with Opus 4.7 ([#562](https://github.com/agentclientprotocol/claude-agent-acp/issues/562)) ([079614a](https://github.com/agentclientprotocol/claude-agent-acp/commit/079614ab05afba17e2cce0d3d238df7b90e17389))
## [0.29.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.28.0...v0.29.0) (2026-04-16)
### Features
* Update to claude-agent-sdk 0.2.111 (Opus 4.7) ([#557](https://github.com/agentclientprotocol/claude-agent-acp/issues/557)) ([85cd70c](https://github.com/agentclientprotocol/claude-agent-acp/commit/85cd70c9f3be47c9c404958547c4046d866db1c9))
## [0.28.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.27.0...v0.28.0) (2026-04-15)
### Features
* Update to claude-agent-sdk 0.2.109 ([#549](https://github.com/agentclientprotocol/claude-agent-acp/issues/549)) ([07a0fbc](https://github.com/agentclientprotocol/claude-agent-acp/commit/07a0fbc2f6bc388541d064a436412bdd850772cb))
## [0.27.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.26.0...v0.27.0) (2026-04-13)
### Features
* allow clients to opt into receiving raw SDK messages ([#527](https://github.com/agentclientprotocol/claude-agent-acp/issues/527)) ([403a668](https://github.com/agentclientprotocol/claude-agent-acp/commit/403a668078c067868062ed26cd4d3e36665b66b6))
* Update to claude-agent-sdk 0.2.104 ([#537](https://github.com/agentclientprotocol/claude-agent-acp/issues/537)) ([6811943](https://github.com/agentclientprotocol/claude-agent-acp/commit/6811943f57ef08616be633a8197223d4072663cf))
### Bug Fixes
* Allow auto mode after plan mode and send description for auto mode ([#528](https://github.com/agentclientprotocol/claude-agent-acp/issues/528)) ([fb9aced](https://github.com/agentclientprotocol/claude-agent-acp/commit/fb9aced3151c40694f1f01fd95665c4f5d90eb67))
* Better remote check for auth methods ([#538](https://github.com/agentclientprotocol/claude-agent-acp/issues/538)) ([93f58c0](https://github.com/agentclientprotocol/claude-agent-acp/commit/93f58c0d2fcf7365c7ca5a6e52f56663e2065ddb))
* better shutdown logic ([#543](https://github.com/agentclientprotocol/claude-agent-acp/issues/543)) ([9fb631f](https://github.com/agentclientprotocol/claude-agent-acp/commit/9fb631f5d76a5c5f6f0a1b61bdef05fe368c754c))
* exit process when ACP connection closes ([#530](https://github.com/agentclientprotocol/claude-agent-acp/issues/530)) ([5c81e99](https://github.com/agentclientprotocol/claude-agent-acp/commit/5c81e99fe5ccdf774819b7ff3a2bc78a6519d730))
* guard tool info rendering when tool_use input is undefined ([#536](https://github.com/agentclientprotocol/claude-agent-acp/issues/536)) ([d627b8c](https://github.com/agentclientprotocol/claude-agent-acp/commit/d627b8c5e95be31ac03923ef67d91748ec8564c5))
* Remove backup auth check from new session ([#544](https://github.com/agentclientprotocol/claude-agent-acp/issues/544)) ([32b16c1](https://github.com/agentclientprotocol/claude-agent-acp/commit/32b16c1ad99394238b0e5cd6c2f761c12debe142))
## [0.26.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.3...v0.26.0) (2026-04-08)
### Features
* Update claude-agent-sdk to 0.2.96 ([#526](https://github.com/agentclientprotocol/claude-agent-acp/issues/526)) ([c073131](https://github.com/agentclientprotocol/claude-agent-acp/commit/c07313148808a55f27f385c10babbaf7511a7f12))
### Bug Fixes
* Remove bun builds from release ([#525](https://github.com/agentclientprotocol/claude-agent-acp/issues/525)) ([fcf5aaf](https://github.com/agentclientprotocol/claude-agent-acp/commit/fcf5aaf06dfe9f7d1b285b976eeb2d1e20ea8dec))
* Use TUI login for remote environments ([#523](https://github.com/agentclientprotocol/claude-agent-acp/issues/523)) ([cc73e37](https://github.com/agentclientprotocol/claude-agent-acp/commit/cc73e37b41678aa67813c4fbef66ba33ca538743))
## [0.25.3](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.2...v0.25.3) (2026-04-06)
### Bug Fixes
* Drop claude-agent-sdk back to 0.2.91 to fix broken import ([#513](https://github.com/agentclientprotocol/claude-agent-acp/issues/513)) ([26f3e8a](https://github.com/agentclientprotocol/claude-agent-acp/commit/26f3e8a5216295985fadb80fb3b977045c0c1b2c))
* Recreate resumed sessions when params change ([#515](https://github.com/agentclientprotocol/claude-agent-acp/issues/515)) ([aa82193](https://github.com/agentclientprotocol/claude-agent-acp/commit/aa82193330026bae132fed8391c47dde777dcf5a))
## [0.25.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.1...v0.25.2) (2026-04-06)
### Bug Fixes
* prioritize ANTHROPIC_MODEL env var over settings.model in model … ([#505](https://github.com/agentclientprotocol/claude-agent-acp/issues/505)) ([bea1a40](https://github.com/agentclientprotocol/claude-agent-acp/commit/bea1a40e9bfe1e06672b118a727f9339def3be23))
## [0.25.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.25.0...v0.25.1) (2026-04-06)
### Bug Fixes
* add `auto` to valid modes in applySessionMode to fix mode cycling ([#507](https://github.com/agentclientprotocol/claude-agent-acp/issues/507)) ([15e91fb](https://github.com/agentclientprotocol/claude-agent-acp/commit/15e91fb5c3449de2600b583cb7a8d36b5b510443))
## [0.25.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.2...v0.25.0) (2026-04-03)
### Features
* Add auto permission mode support ([#501](https://github.com/agentclientprotocol/claude-agent-acp/issues/501)) ([a161453](https://github.com/agentclientprotocol/claude-agent-acp/commit/a16145396fe2e6ead8734478961b2de65707e335))
* Add separate Claude and Console terminal logins ([#502](https://github.com/agentclientprotocol/claude-agent-acp/issues/502)) ([063cd35](https://github.com/agentclientprotocol/claude-agent-acp/commit/063cd353809df8f3dda9e57d8ea848c0a6d44257))
* Update to claude-agent-sdk 0.2.91 ([#500](https://github.com/agentclientprotocol/claude-agent-acp/issues/500)) ([65a2230](https://github.com/agentclientprotocol/claude-agent-acp/commit/65a223038576d72b74e1483fed10e982a1f842bd))
### Bug Fixes
* log warnings for malformed settings files instead of silent fallback ([#486](https://github.com/agentclientprotocol/claude-agent-acp/issues/486)) ([ae6c388](https://github.com/agentclientprotocol/claude-agent-acp/commit/ae6c38831415f9fc1de2d3dd1d4a247becbbd32f))
* prevent race conditions in SettingsManager setCwd and debounce ([#485](https://github.com/agentclientprotocol/claude-agent-acp/issues/485)) ([7506223](https://github.com/agentclientprotocol/claude-agent-acp/commit/7506223cffb1aba4b4560feda11f69a1395a8c9d))
* use current model's context window for usage_update size ([#412](https://github.com/agentclientprotocol/claude-agent-acp/issues/412)) ([d07799d](https://github.com/agentclientprotocol/claude-agent-acp/commit/d07799d7b3b4e438c8b158266c79723a0b592c07))
## [0.24.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.1...v0.24.2) (2026-03-27)
### Bug Fixes
* Add explicit type checks for MCP servers (http/sse) ([#487](https://github.com/agentclientprotocol/claude-agent-acp/issues/487)) ([e00a439](https://github.com/agentclientprotocol/claude-agent-acp/commit/e00a43901fa2b4fd7d582e1de57277be88233007))
## [0.24.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.24.0...v0.24.1) (2026-03-26)
### Bug Fixes
* Cleanup based on new idle state [#463](https://github.com/agentclientprotocol/claude-agent-acp/issues/463) ([#480](https://github.com/agentclientprotocol/claude-agent-acp/issues/480)) ([23b3073](https://github.com/agentclientprotocol/claude-agent-acp/commit/23b30730253752f0bc4e30b619a6236f16fafdb9))
## 0.24.0
Rename from `@zed-industries/claude-agent-acp` to `@agentclientprotocol/claude-agent-acp`.
We are moving this to the main ACP org to better allow multiple teams to contribute and maintain this adapter.
## 0.23.1
- Add back error_during_execution break point (#469)
## 0.23.0
- Use idle session state as end of turn (#463)
- Update claude-agent-sdk to 0.2.83 (#462)
- Fix handling of local-only slash commands (#432)
- fix: correct null check for gatewayAuthMeta in subscription validation (#455)
- fix: include both stdout and stderr in Bash tool output (#456)
- fix: prevent prompt loop hang when cancel races with first result (#458)
- fix: dispose SettingsManager on session close to prevent resource leaks (#454)
- fix: restore plan content in ExitPlanMode tool call (#451)
## 0.22.2
- Add experimental meta param for testing additional directories
## 0.22.1
- Fix: invalid auth required state in gateway mode

61
LICENSE
View File

@@ -1,42 +1,18 @@
Copyright 2022 - 2025 Zed Industries, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
@@ -45,28 +21,23 @@ Apache License
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
@@ -75,7 +46,6 @@ Apache License
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
@@ -90,12 +60,10 @@ Apache License
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
@@ -103,7 +71,6 @@ Apache License
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
@@ -120,28 +87,23 @@ Apache License
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
@@ -159,7 +121,6 @@ Apache License
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
@@ -167,7 +128,6 @@ Apache License
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
@@ -176,13 +136,11 @@ Apache License
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
@@ -193,7 +151,6 @@ Apache License
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
@@ -206,7 +163,6 @@ Apache License
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
@@ -218,5 +174,18 @@ Apache License
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2025 Zed Industries, Inc. and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,8 +1,8 @@
# ACP adapter for the Claude Agent SDK
[![npm](https://img.shields.io/npm/v/%40zed-industries%2Fclaude-agent-acp)](https://www.npmjs.com/package/@zed-industries/claude-agent-acp)
[![npm](https://img.shields.io/npm/v/%40agentclientprotocol%2Fclaude-agent-acp)](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp)
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)!
Use [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines) from [ACP-compatible](https://agentclientprotocol.com) clients!
This tool implements an ACP agent by using the official [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), supporting:
@@ -18,41 +18,8 @@ This tool implements an ACP agent by using the official [Claude Agent SDK](https
Learn more about the [Agent Client Protocol](https://agentclientprotocol.com/).
## How to use
## Contribution Policy
### Zed
This project does not require a Contributor License Agreement (CLA). Instead, contributions are accepted under the following terms:
The latest version of Zed can already use this adapter out of the box.
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
Read the docs on [External Agent](https://zed.dev/docs/ai/external-agents) support.
### Other clients
Or try it with any of the other [ACP compatible clients](https://agentclientprotocol.com/overview/clients)!
#### Installation
Install the adapter from `npm`:
```bash
npm install -g @zed-industries/claude-agent-acp
```
You can then use `claude-agent-acp` as a regular ACP agent:
```
ANTHROPIC_API_KEY=sk-... claude-agent-acp
```
#### Single-file executable
Pre-built single-file binaries are available on the [Releases](https://github.com/zed-industries/claude-agent-acp/releases) page for Linux, macOS, and Windows.
These binaries bundle everything needed and don't require Node.js.
## License
Apache-2.0
> By contributing to this project, you agree that your contributions will be licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). You affirm that you have the legal right to submit your work, that you are not including code you do not have rights to, and that you understand contributions are made without requiring a Contributor License Agreement (CLA).

1773
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
{
"name": "@zed-industries/claude-agent-acp",
"name": "@agentclientprotocol/claude-agent-acp",
"publishConfig": {
"access": "public"
},
"version": "0.22.1",
"version": "0.29.2",
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
"main": "dist/lib.js",
"types": "dist/lib.d.ts",
@@ -49,33 +49,33 @@
"sdk",
"code"
],
"homepage": "https://github.com/zed-industries/claude-agent-acp#readme",
"homepage": "https://github.com/agentclientprotocol/claude-agent-acp#readme",
"bugs": {
"url": "https://github.com/zed-industries/claude-agent-acp/issues"
"url": "https://github.com/agentclientprotocol/claude-agent-acp/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zed-industries/claude-agent-acp.git"
"url": "git+https://github.com/agentclientprotocol/claude-agent-acp.git"
},
"author": "Zed Industries",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "0.16.1",
"@anthropic-ai/claude-agent-sdk": "0.2.76",
"@agentclientprotocol/sdk": "0.19.0",
"@anthropic-ai/claude-agent-sdk": "0.2.112",
"zod": "^3.25.0 || ^4.0.0"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.78.0",
"@anthropic-ai/sdk": "0.89.0",
"@eslint/js": "10.0.1",
"@types/node": "25.5.0",
"@typescript-eslint/eslint-plugin": "8.57.0",
"@typescript-eslint/parser": "8.57.0",
"eslint": "10.0.3",
"@types/node": "25.6.0",
"@typescript-eslint/eslint-plugin": "8.58.2",
"@typescript-eslint/parser": "8.58.2",
"eslint": "10.2.0",
"eslint-config-prettier": "10.1.8",
"globals": "17.4.0",
"prettier": "3.8.1",
"globals": "17.5.0",
"prettier": "3.8.3",
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vitest": "4.1.0"
"typescript": "6.0.3",
"vitest": "4.1.4"
}
}

View File

@@ -0,0 +1,13 @@
{
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"packages": {
".": {
"changelog-path": "CHANGELOG.md",
"release-type": "node",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

View File

@@ -40,6 +40,7 @@ import {
TerminalOutputResponse,
WriteTextFileRequest,
WriteTextFileResponse,
StopReason,
} from "@agentclientprotocol/sdk";
import {
CanUseTool,
@@ -47,19 +48,18 @@ import {
listSessions,
McpServerConfig,
ModelInfo,
ModelUsage,
Options,
PermissionMode,
Query,
query,
SDKPartialAssistantMessage,
SDKResultMessage,
SDKUserMessage,
SlashCommand,
} from "@anthropic-ai/claude-agent-sdk";
import { ContentBlockParam } from "@anthropic-ai/sdk/resources";
import { BetaContentBlock, BetaRawContentBlockDelta } from "@anthropic-ai/sdk/resources/beta.mjs";
import { randomUUID } from "node:crypto";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import packageJson from "../package.json" with { type: "json" };
@@ -107,11 +107,30 @@ type AccumulatedUsage = {
cachedWriteTokens: number;
};
type UsageSnapshot = {
input_tokens: number;
output_tokens: number;
cache_read_input_tokens: number;
cache_creation_input_tokens: number;
};
const ZERO_USAGE = Object.freeze({
input_tokens: 0,
output_tokens: 0,
cache_read_input_tokens: 0,
cache_creation_input_tokens: 0,
});
const DEFAULT_CONTEXT_WINDOW = 200000;
type Session = {
query: Query;
input: Pushable<SDKUserMessage>;
cancelled: boolean;
cwd: string;
/** Serialized snapshot of session-defining params (cwd, mcpServers) used to
* detect when loadSession/resumeSession is called with changed values. */
sessionFingerprint: string;
settingsManager: SettingsManager;
accumulatedUsage: AccumulatedUsage;
modes: SessionModeState;
@@ -121,8 +140,27 @@ type Session = {
pendingMessages: Map<string, { resolve: (cancelled: boolean) => void; order: number }>;
nextPendingOrder: number;
abortController: AbortController;
emitRawSDKMessages: boolean | SDKMessageFilter[];
/** Context window size of the last top-level assistant model, carried across
* prompts so mid-stream usage_update notifications report a correct `size`
* before the turn's first result message arrives. Defaults to
* DEFAULT_CONTEXT_WINDOW, refreshed from each result's modelUsage, and
* invalidated when the user switches the session's model. */
contextWindowSize: number;
};
/** Compute a stable fingerprint of the session-defining params so we can
* detect when a loadSession/resumeSession call requires tearing down and
* recreating the underlying Query process. MCP servers are sorted by name
* so that ordering differences don't trigger unnecessary recreations. */
function computeSessionFingerprint(params: {
cwd: string;
mcpServers?: NewSessionRequest["mcpServers"];
}): string {
const servers = [...(params.mcpServers ?? [])].sort((a, b) => a.name.localeCompare(b.name));
return JSON.stringify({ cwd: params.cwd, mcpServers: servers });
}
type BackgroundTerminal =
| {
handle: TerminalHandle;
@@ -134,6 +172,11 @@ type BackgroundTerminal =
pendingOutput: TerminalOutputResponse;
};
export type SDKMessageFilter = {
type: string;
subtype?: string;
};
/**
* Extra metadata that can be given when creating a new session.
*/
@@ -155,7 +198,16 @@ export type NewSessionMeta = {
* - tools (passed through; defaults to claude_code preset if not provided)
*/
options?: Options;
/**
* When set, raw SDK messages are emitted as extNotification("_claude/sdkMessage", message)
* in addition to normal processing.
* - true: emit all messages
* - false/undefined: emit nothing (default)
* - SDKMessageFilter[]: emit only messages matching at least one filter
*/
emitRawSDKMessages?: boolean | SDKMessageFilter[];
};
additionalRoots?: string[];
};
/**
@@ -226,7 +278,12 @@ function shouldHideClaudeAuth(): boolean {
const IS_ROOT = (process.geteuid?.() ?? process.getuid?.()) === 0;
const ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
// Slash commands that the SDK handles locally without replaying the user
// message and without invoking the model.
const LOCAL_ONLY_COMMANDS = new Set(["/context", "/heapdump", "/extra-usage"]);
const PERMISSION_MODE_ALIASES: Record<string, PermissionMode> = {
auto: "auto",
default: "default",
acceptedits: "acceptEdits",
dontask: "dontAsk",
@@ -300,25 +357,85 @@ export class ClaudeAcpAgent implements Agent {
},
};
const terminalAuthMethod: any = {
description: "Run `claude /login` in the terminal",
name: "Log in with Claude",
id: "claude-login",
type: "terminal",
args: ["--cli"],
};
const supportsTerminalAuth = request.clientCapabilities?.auth?.terminal === true;
// If client supports terminal-auth capability, use that instead.
const supportsMetaTerminalAuth = request.clientCapabilities?._meta?.["terminal-auth"] === true;
if (supportsMetaTerminalAuth) {
terminalAuthMethod._meta = {
"terminal-auth": {
command: process.execPath,
args: [...process.argv.slice(1), "--cli"],
label: "Claude Login",
},
// Detect remote environments where the OAuth browser redirect to localhost
// won't work. This matches the SDK's internal isRemote check. In these cases,
// the `auth login` subcommand would fall back to a device-code-like manual
// flow, which doesn't work well over ACP, so we offer the TUI login instead.
const isRemote = !!(
process.env.NO_BROWSER ||
process.env.SSH_CONNECTION ||
process.env.SSH_CLIENT ||
process.env.SSH_TTY ||
process.env.CLAUDE_CODE_REMOTE
);
const terminalAuthMethods: AuthMethod[] = [];
if (isRemote) {
const remoteLoginMethod: AuthMethod = {
description: "Run `claude /login` in the terminal",
name: "Log in with Claude",
id: "claude-login",
type: "terminal",
args: ["--cli"],
};
if (supportsMetaTerminalAuth) {
remoteLoginMethod._meta = {
"terminal-auth": {
command: process.execPath,
args: [...process.argv.slice(1), "--cli"],
label: "Claude Login",
},
};
}
if (!shouldHideClaudeAuth() && (supportsTerminalAuth || supportsMetaTerminalAuth)) {
terminalAuthMethods.push(remoteLoginMethod);
}
} else {
const claudeLoginMethod: AuthMethod = {
description: "Use Claude subscription ",
name: "Claude Subscription",
id: "claude-ai-login",
type: "terminal",
args: ["--cli", "auth", "login", "--claudeai"],
};
const consoleLoginMethod: AuthMethod = {
description: "Use Anthropic Console (API usage billing)",
name: "Anthropic Console",
id: "console-login",
type: "terminal",
args: ["--cli", "auth", "login", "--console"],
};
if (supportsMetaTerminalAuth) {
const baseArgs = process.argv.slice(1);
claudeLoginMethod._meta = {
"terminal-auth": {
command: process.execPath,
args: [...baseArgs, "--cli", "auth", "login", "--claudeai"],
label: "Claude Login",
},
};
consoleLoginMethod._meta = {
"terminal-auth": {
command: process.execPath,
args: [...baseArgs, "--cli", "auth", "login", "--console"],
label: "Anthropic Console Login",
},
};
}
if (!shouldHideClaudeAuth() && (supportsTerminalAuth || supportsMetaTerminalAuth)) {
terminalAuthMethods.push(claudeLoginMethod);
}
if (supportsTerminalAuth || supportsMetaTerminalAuth) {
terminalAuthMethods.push(consoleLoginMethod);
}
}
return {
@@ -350,24 +467,11 @@ export class ClaudeAcpAgent implements Agent {
title: "Claude Agent",
version: packageJson.version,
},
authMethods: [
...(!shouldHideClaudeAuth() && (supportsTerminalAuth || supportsMetaTerminalAuth)
? [terminalAuthMethod]
: []),
...(supportsGatewayAuth ? [gatewayAuthMethod] : []),
],
authMethods: [...terminalAuthMethods, ...(supportsGatewayAuth ? [gatewayAuthMethod] : [])],
};
}
async newSession(params: NewSessionRequest): Promise<NewSessionResponse> {
if (
!this.gatewayAuthMeta &&
fs.existsSync(path.resolve(os.homedir(), ".claude.json.backup")) &&
!fs.existsSync(path.resolve(os.homedir(), ".claude.json"))
) {
throw RequestError.authRequired();
}
const response = await this.createSession(params, {
// Revisit these meta values once we support resume
resume: (params._meta as NewSessionMeta | undefined)?.claudeCode?.options?.resume,
@@ -462,13 +566,20 @@ export class ClaudeAcpAgent implements Agent {
};
let lastAssistantTotalUsage: number | null = null;
let lastAssistantUsage: UsageSnapshot | null = null;
let lastAssistantModel: string | null = null;
const userMessage = promptToClaude(params);
const promptUuid = randomUUID();
userMessage.uuid = promptUuid;
let promptReplayed = false;
// These local-only commands return a result without replaying the user
// message. Mark promptReplayed=true so their result isn't consumed as a
// background task result.
const firstText = params.prompt[0]?.type === "text" ? params.prompt[0].text : "";
const isLocalOnlyCommand =
firstText.startsWith("/") && LOCAL_ONLY_COMMANDS.has(firstText.split(" ", 1)[0]);
if (session.promptRunning) {
session.input.push(userMessage);
@@ -479,15 +590,13 @@ export class ClaudeAcpAgent implements Agent {
if (cancelled) {
return { stopReason: "cancelled" };
}
// The replay resolved the promise, mark in this loop too,
// so we don't treat the next result as a background task's result.
promptReplayed = true;
} else {
session.input.push(userMessage);
}
session.promptRunning = true;
let handedOff = false;
let stopReason: StopReason = "end_turn";
try {
while (true) {
@@ -500,6 +609,16 @@ export class ClaudeAcpAgent implements Agent {
break;
}
if (
session.emitRawSDKMessages &&
shouldEmitRawMessage(session.emitRawSDKMessages, message)
) {
await this.client.extNotification("_claude/sdkMessage", {
sessionId: params.sessionId,
message: message as Record<string, unknown>,
});
}
switch (message.type) {
case "system":
switch (message.subtype) {
@@ -518,9 +637,27 @@ export class ClaudeAcpAgent implements Agent {
break;
}
case "compact_boundary": {
// We don't know the exact size, but since we compacted,
// we set it to zero. The client gets the exact size on the next message.
// Send used:0 immediately so the client doesn't keep showing
// the stale pre-compaction context size until the next turn.
//
// This is a deliberate approximation: we don't know the exact
// post-compaction token count (only the SDK's next API call
// reveals that). But used:0 is directionally correct — context
// just dropped dramatically — and the real value replaces it
// within seconds when the next result message arrives.
// The alternative (no update) leaves the client showing e.g.
// "944k/1m" right after the user sees "Compacting completed",
// which is confusing and wrong.
lastAssistantTotalUsage = 0;
lastAssistantUsage = null;
await this.client.sessionUpdate({
sessionId: message.session_id,
update: {
sessionUpdate: "usage_update",
used: 0,
size: session.contextWindowSize,
},
});
await this.client.sessionUpdate({
sessionId: message.session_id,
update: {
@@ -528,7 +665,6 @@ export class ClaudeAcpAgent implements Agent {
content: { type: "text", text: "\n\nCompacting completed." },
},
});
promptReplayed = true;
break;
}
case "local_command_output": {
@@ -539,7 +675,12 @@ export class ClaudeAcpAgent implements Agent {
content: { type: "text", text: message.content },
},
});
promptReplayed = true;
break;
}
case "session_state_changed": {
if (message.state === "idle") {
return { stopReason, usage: sessionUsage(session) };
}
break;
}
case "hook_started":
@@ -549,7 +690,12 @@ export class ClaudeAcpAgent implements Agent {
case "task_started":
case "task_notification":
case "task_progress":
case "task_updated":
case "elicitation_complete":
case "plugin_install":
case "memory_recall":
case "notification":
case "api_retry":
// Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
break;
default:
@@ -564,10 +710,16 @@ export class ClaudeAcpAgent implements Agent {
session.accumulatedUsage.cachedReadTokens += message.usage.cache_read_input_tokens;
session.accumulatedUsage.cachedWriteTokens += message.usage.cache_creation_input_tokens;
// Calculate context window size from modelUsage (minimum across all models used)
const contextWindows = Object.values(message.modelUsage).map((m) => m.contextWindow);
const contextWindowSize =
contextWindows.length > 0 ? Math.min(...contextWindows) : 200000;
const matchingModelUsage = lastAssistantModel
? getMatchingModelUsage(message.modelUsage, lastAssistantModel)
: null;
// Only overwrite when we have an authoritative value — a miss
// (e.g. a turn with no top-level assistant message) would
// otherwise discard the window learned on a prior turn and
// leave the next prompt's mid-stream updates reporting 200k.
if (matchingModelUsage) {
session.contextWindowSize = matchingModelUsage.contextWindow;
}
// Send usage_update notification
if (lastAssistantTotalUsage !== null) {
@@ -576,7 +728,7 @@ export class ClaudeAcpAgent implements Agent {
update: {
sessionUpdate: "usage_update",
used: lastAssistantTotalUsage,
size: contextWindowSize,
size: session.contextWindowSize,
cost: {
amount: message.total_cost_usd,
currency: "USD",
@@ -585,47 +737,43 @@ export class ClaudeAcpAgent implements Agent {
});
}
if (!promptReplayed) {
// This result is from a background task that finished after
// the previous prompt loop ended. Consume it and continue
// waiting for our own prompt's result.
this.logger.log(`Session ${params.sessionId}: consuming background task result`);
if (session.cancelled) {
stopReason = "cancelled";
break;
}
if (session.cancelled) {
return { stopReason: "cancelled" };
}
// Build the usage response
const usage: PromptResponse["usage"] = {
inputTokens: session.accumulatedUsage.inputTokens,
outputTokens: session.accumulatedUsage.outputTokens,
cachedReadTokens: session.accumulatedUsage.cachedReadTokens,
cachedWriteTokens: session.accumulatedUsage.cachedWriteTokens,
totalTokens:
session.accumulatedUsage.inputTokens +
session.accumulatedUsage.outputTokens +
session.accumulatedUsage.cachedReadTokens +
session.accumulatedUsage.cachedWriteTokens,
};
switch (message.subtype) {
case "success": {
if (message.result.includes("Please run /login")) {
throw RequestError.authRequired();
}
if (message.stop_reason === "max_tokens") {
return { stopReason: "max_tokens", usage };
stopReason = "max_tokens";
break;
}
if (message.is_error) {
throw RequestError.internalError(undefined, message.result);
}
return { stopReason: "end_turn", usage };
// For local-only commands (no model invocation), the result
// text is the command output — forward it to the client.
if (isLocalOnlyCommand) {
for (const notification of toAcpNotifications(
message.result,
"assistant",
params.sessionId,
this.toolUseCache,
this.client,
this.logger,
)) {
await this.client.sessionUpdate(notification);
}
}
break;
}
case "error_during_execution":
case "error_during_execution": {
if (message.stop_reason === "max_tokens") {
return { stopReason: "max_tokens", usage };
stopReason = "max_tokens";
break;
}
if (message.is_error) {
throw RequestError.internalError(
@@ -633,7 +781,9 @@ export class ClaudeAcpAgent implements Agent {
message.errors.join(", ") || message.subtype,
);
}
return { stopReason: "end_turn", usage };
stopReason = "end_turn";
break;
}
case "error_max_budget_usd":
case "error_max_turns":
case "error_max_structured_output_retries":
@@ -643,7 +793,8 @@ export class ClaudeAcpAgent implements Agent {
message.errors.join(", ") || message.subtype,
);
}
return { stopReason: "max_turn_requests", usage };
stopReason = "max_turn_requests";
break;
default:
unreachable(message, this.logger);
break;
@@ -651,6 +802,57 @@ export class ClaudeAcpAgent implements Agent {
break;
}
case "stream_event": {
if (
message.parent_tool_use_id === null &&
(message.event.type === "message_start" || message.event.type === "message_delta")
) {
if (message.event.type === "message_start") {
lastAssistantUsage = snapshotFromUsage(message.event.message.usage);
const model = message.event.message.model;
if (model && model !== "<synthetic>") {
lastAssistantModel = model;
// Only upgrade from the default — once a `result` has given
// us an authoritative window, trust it over the heuristic.
// Model switches invalidate the cached window via
// `syncSessionConfigState`, which resets us back to the
// default so this branch runs again for the new model.
if (session.contextWindowSize === DEFAULT_CONTEXT_WINDOW) {
const inferred = inferContextWindowFromModel(model);
if (inferred !== null) {
session.contextWindowSize = inferred;
}
}
}
} else {
const usage = message.event.usage;
const prev: Readonly<UsageSnapshot> = lastAssistantUsage ?? ZERO_USAGE;
// Per Anthropic API, message_delta usage fields are *cumulative*;
// nullable fields (input_tokens and the cache fields) fall back
// to the prior snapshot when the server omits them from this
// delta. Only output_tokens is guaranteed non-null.
lastAssistantUsage = {
input_tokens: usage.input_tokens ?? prev.input_tokens,
output_tokens: usage.output_tokens,
cache_read_input_tokens:
usage.cache_read_input_tokens ?? prev.cache_read_input_tokens,
cache_creation_input_tokens:
usage.cache_creation_input_tokens ?? prev.cache_creation_input_tokens,
};
}
const nextUsage = totalTokens(lastAssistantUsage);
if (nextUsage !== lastAssistantTotalUsage) {
lastAssistantTotalUsage = nextUsage;
await this.client.sessionUpdate({
sessionId: params.sessionId,
update: {
sessionUpdate: "usage_update",
used: nextUsage,
size: session.contextWindowSize,
},
});
}
}
for (const notification of streamEventToAcpNotifications(
message,
params.sessionId,
@@ -675,11 +877,9 @@ export class ClaudeAcpAgent implements Agent {
// Check for prompt replay
if (message.type === "user" && "uuid" in message && message.uuid) {
if (message.uuid === promptUuid) {
// Our own prompt was replayed back — we're now processing
// our prompt's response (not a background task's).
promptReplayed = true;
break;
}
const pending = session.pendingMessages.get(message.uuid as string);
if (pending) {
pending.resolve(false);
@@ -687,7 +887,7 @@ export class ClaudeAcpAgent implements Agent {
handedOff = true;
// the current loop stops with end_turn,
// the loop of the next prompt continues running
return { stopReason: "end_turn" };
return { stopReason: "end_turn", usage: sessionUsage(session) };
}
if ("isReplay" in message && message.isReplay) {
// not pending or unrelated replay message
@@ -695,14 +895,16 @@ export class ClaudeAcpAgent implements Agent {
}
}
// Store latest assistant usage (excluding subagents)
if ((message.message as any).usage && message.parent_tool_use_id === null) {
const messageWithUsage = message.message as unknown as SDKResultMessage;
lastAssistantTotalUsage =
messageWithUsage.usage.input_tokens +
messageWithUsage.usage.output_tokens +
messageWithUsage.usage.cache_read_input_tokens +
messageWithUsage.usage.cache_creation_input_tokens;
// Snapshot the latest top-level assistant usage and model so the
// next `result` can emit a usage_update tied to the right context
// window. Subagent messages are excluded to keep the snapshot
// aligned with what the user's current selection is producing.
if (message.type === "assistant" && message.parent_tool_use_id === null) {
lastAssistantUsage = snapshotFromUsage(message.message.usage);
lastAssistantTotalUsage = totalTokens(lastAssistantUsage);
if (message.message.model && message.message.model !== "<synthetic>") {
lastAssistantModel = message.message.model;
}
}
// Slash commands like /compact can generate invalid output... doesn't match
@@ -711,22 +913,6 @@ export class ClaudeAcpAgent implements Agent {
typeof message.message.content === "string" &&
message.message.content.includes("<local-command-stdout>")
) {
// Handle /context by sending its reply as regular agent message.
if (message.message.content.includes("Context Usage")) {
for (const notification of toAcpNotifications(
message.message.content
.replace("<local-command-stdout>", "")
.replace("</local-command-stdout>", ""),
"assistant",
params.sessionId,
this.toolUseCache,
this.client,
this.logger,
{ clientCapabilities: this.clientCapabilities },
)) {
await this.client.sessionUpdate(notification);
}
}
this.logger.log(message.message.content);
break;
}
@@ -810,6 +996,7 @@ export class ClaudeAcpAgent implements Agent {
message.includes("Failed to write to process stdin")
) {
this.logger.error(`Session ${params.sessionId}: Claude Agent process died: ${message}`);
session.settingsManager.dispose();
session.input.end();
delete this.sessions[params.sessionId];
throw RequestError.internalError(
@@ -840,7 +1027,7 @@ export class ClaudeAcpAgent implements Agent {
async cancel(params: CancelNotification): Promise<void> {
const session = this.sessions[params.sessionId];
if (!session) {
throw new Error("Session not found");
return;
}
session.cancelled = true;
for (const [, pending] of session.pendingMessages) {
@@ -850,16 +1037,30 @@ export class ClaudeAcpAgent implements Agent {
await session.query.interrupt();
}
async unstable_closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse> {
const session = this.sessions[params.sessionId];
/** Cleanly tear down a session: cancel in-flight work, dispose resources,
* and remove it from the session map. */
private async teardownSession(sessionId: string): Promise<void> {
const session = this.sessions[sessionId];
if (!session) {
return;
}
await this.cancel({ sessionId });
session.settingsManager.dispose();
session.abortController.abort();
session.query.close();
delete this.sessions[sessionId];
}
/** Tear down all active sessions. Called when the ACP connection closes. */
async dispose(): Promise<void> {
await Promise.all(Object.keys(this.sessions).map((id) => this.teardownSession(id)));
}
async unstable_closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse> {
if (!this.sessions[params.sessionId]) {
throw new Error("Session not found");
}
await this.cancel({ sessionId: params.sessionId });
session.abortController.abort();
delete this.sessions[params.sessionId];
await this.teardownSession(params.sessionId);
return {};
}
@@ -954,6 +1155,7 @@ export class ClaudeAcpAgent implements Agent {
private async applySessionMode(sessionId: string, modeId: string): Promise<void> {
switch (modeId) {
case "auto":
case "default":
case "acceptEdits":
case "bypassPermissions":
@@ -1026,6 +1228,7 @@ export class ClaudeAcpAgent implements Agent {
if (toolName === "ExitPlanMode") {
const options = [
{ kind: "allow_always", name: 'Yes, and use "auto" mode', optionId: "auto" },
{
kind: "allow_always",
name: "Yes, and auto-accept edits",
@@ -1063,6 +1266,7 @@ export class ClaudeAcpAgent implements Agent {
response.outcome?.outcome === "selected" &&
(response.outcome.optionId === "default" ||
response.outcome.optionId === "acceptEdits" ||
response.outcome.optionId === "auto" ||
response.outcome.optionId === "bypassPermissions")
) {
await this.client.sessionUpdate({
@@ -1195,6 +1399,13 @@ export class ClaudeAcpAgent implements Agent {
if (configId === "mode") {
session.modes = { ...session.modes, currentModeId: value };
} else if (configId === "model") {
if (session.models.currentModelId !== value) {
// The cached context window was learned for the previous model; reset
// to the new model's heuristic so mid-stream updates between now and
// the next `result` reflect the user's selection instead of the old
// model's window.
session.contextWindowSize = inferContextWindowFromModel(value) ?? DEFAULT_CONTEXT_WINDOW;
}
session.models = { ...session.models, currentModelId: value };
}
}
@@ -1207,12 +1418,20 @@ export class ClaudeAcpAgent implements Agent {
}): Promise<NewSessionResponse> {
const existingSession = this.sessions[params.sessionId];
if (existingSession) {
return {
sessionId: params.sessionId,
modes: existingSession.modes,
models: existingSession.models,
configOptions: existingSession.configOptions,
};
const fingerprint = computeSessionFingerprint(params);
if (fingerprint === existingSession.sessionFingerprint) {
return {
sessionId: params.sessionId,
modes: existingSession.modes,
models: existingSession.models,
configOptions: existingSession.configOptions,
};
}
// Session-defining params changed (e.g. cwd pointed at a git worktree,
// or MCP servers reconfigured). Tear down the existing session and
// recreate it so the underlying Query process picks up the new values.
await this.teardownSession(params.sessionId);
}
const response = await this.createSession(
@@ -1259,7 +1478,8 @@ export class ClaudeAcpAgent implements Agent {
const mcpServers: Record<string, McpServerConfig> = {};
if (Array.isArray(params.mcpServers)) {
for (const server of params.mcpServers) {
if ("type" in server) {
if ("type" in server && (server.type === "http" || server.type === "sse")) {
// HTTP or SSE type MCP server
mcpServers[server.name] = {
type: server.type,
url: server.url,
@@ -1268,6 +1488,7 @@ export class ClaudeAcpAgent implements Agent {
: undefined,
};
} else {
// Stdio type MCP server (with or without explicit type field)
mcpServers[server.name] = {
type: "stdio",
command: server.command,
@@ -1299,7 +1520,8 @@ export class ClaudeAcpAgent implements Agent {
);
// Extract options from _meta if provided
const userProvidedOptions = (params._meta as NewSessionMeta | undefined)?.claudeCode?.options;
const sessionMeta = params._meta as NewSessionMeta | undefined;
const userProvidedOptions = sessionMeta?.claudeCode?.options;
// Configure thinking tokens from environment variable
const maxThinkingTokens = process.env.MAX_THINKING_TOKENS
@@ -1328,6 +1550,8 @@ export class ClaudeAcpAgent implements Agent {
...process.env,
...userProvidedOptions?.env,
...createEnvForGateway(this.gatewayAuthMeta),
// Opt-in to session state events like when the agent is idle
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1",
},
// Override certain fields that must be controlled by ACP
cwd: params.cwd,
@@ -1378,6 +1602,11 @@ export class ClaudeAcpAgent implements Agent {
abortController,
};
options.additionalDirectories = [
...(userProvidedOptions?.additionalDirectories ?? []),
...(sessionMeta?.additionalRoots ?? []),
];
if (creationOpts?.resume === undefined || creationOpts?.forkSession) {
// Set our own session id if not resuming an existing session.
options.sessionId = sessionId;
@@ -1400,7 +1629,8 @@ export class ClaudeAcpAgent implements Agent {
if (
creationOpts.resume &&
error instanceof Error &&
error.message === "Query closed before response received"
(error.message === "Query closed before response received" ||
error.message.includes("No conversation found with session ID"))
) {
throw RequestError.resourceNotFound(sessionId);
}
@@ -1410,7 +1640,7 @@ export class ClaudeAcpAgent implements Agent {
if (
shouldHideClaudeAuth() &&
initializationResult.account.subscriptionType &&
this.gatewayAuthMeta === null
!this.gatewayAuthMeta
) {
throw RequestError.authRequired(
undefined,
@@ -1421,6 +1651,11 @@ export class ClaudeAcpAgent implements Agent {
const models = await getAvailableModels(q, initializationResult.models, settingsManager);
const availableModes = [
{
id: "auto",
name: "Auto",
description: "Use a model classifier to approve/deny permission prompts",
},
{
id: "default",
name: "Default",
@@ -1463,6 +1698,7 @@ export class ClaudeAcpAgent implements Agent {
input: input,
cancelled: false,
cwd: params.cwd,
sessionFingerprint: computeSessionFingerprint(params),
settingsManager,
accumulatedUsage: {
inputTokens: 0,
@@ -1477,6 +1713,9 @@ export class ClaudeAcpAgent implements Agent {
pendingMessages: new Map(),
nextPendingOrder: 0,
abortController,
emitRawSDKMessages: sessionMeta?.claudeCode?.emitRawSDKMessages ?? false,
contextWindowSize:
inferContextWindowFromModel(models.currentModelId) ?? DEFAULT_CONTEXT_WINDOW,
};
return {
@@ -1488,6 +1727,66 @@ export class ClaudeAcpAgent implements Agent {
}
}
function shouldEmitRawMessage(
config: boolean | SDKMessageFilter[],
message: { type: string; subtype?: string },
): boolean {
if (config === true) return true;
if (config === false) return false;
return config.some(
(f) => f.type === message.type && (f.subtype === undefined || f.subtype === message.subtype),
);
}
function sessionUsage(session: Session) {
return {
inputTokens: session.accumulatedUsage.inputTokens,
outputTokens: session.accumulatedUsage.outputTokens,
cachedReadTokens: session.accumulatedUsage.cachedReadTokens,
cachedWriteTokens: session.accumulatedUsage.cachedWriteTokens,
totalTokens:
session.accumulatedUsage.inputTokens +
session.accumulatedUsage.outputTokens +
session.accumulatedUsage.cachedReadTokens +
session.accumulatedUsage.cachedWriteTokens,
};
}
/** Sum all four fields as a proxy for post-turn context occupancy: the current
* turn's output becomes next turn's input. Per the Anthropic API, input_tokens
* excludes cache tokens — cache_read and cache_creation are reported
* separately — so summing all four is not double-counting. */
function totalTokens(usage: UsageSnapshot): number {
return (
usage.input_tokens +
usage.output_tokens +
usage.cache_read_input_tokens +
usage.cache_creation_input_tokens
);
}
/** Project a nullable API usage object into our non-null snapshot shape.
* Both SDK message_start and assistant message `usage` have `number | null`
* cache fields; we coerce absent values to 0 so `totalTokens` never hits
* NaN. `input_tokens`/`output_tokens` are typed `number` by the SDK but
* synthetic or third-party-backend stream events have been observed emitting
* them as null/undefined — coerce those too so a malformed upstream event
* can't leak NaN into the wire `used` field. Delta events have different
* semantics (cumulative + prev fallback) and are handled inline. */
function snapshotFromUsage(usage: {
input_tokens?: number | null;
output_tokens?: number | null;
cache_read_input_tokens?: number | null;
cache_creation_input_tokens?: number | null;
}): UsageSnapshot {
return {
input_tokens: usage.input_tokens ?? 0,
output_tokens: usage.output_tokens ?? 0,
cache_read_input_tokens: usage.cache_read_input_tokens ?? 0,
cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0,
};
}
function createEnvForGateway(gatewayMeta?: GatewayAuthMeta) {
if (!gatewayMeta) {
return {};
@@ -1617,7 +1916,16 @@ async function getAvailableModels(
let currentModel = models[0];
if (settings.model) {
// Model priority (highest to lowest):
// 1. ANTHROPIC_MODEL environment variable
// 2. settings.model (user configuration)
// 3. models[0] (default first model)
if (process.env.ANTHROPIC_MODEL) {
const match = resolveModelPreference(models, process.env.ANTHROPIC_MODEL);
if (match) {
currentModel = match;
}
} else if (settings.model) {
const match = resolveModelPreference(models, settings.model);
if (match) {
currentModel = match;
@@ -1695,10 +2003,10 @@ export function promptToClaude(prompt: PromptRequest): SDKUserMessage {
case "text": {
let text = chunk.text;
// change /mcp:server:command args -> /server:command (MCP) args
const mcpMatch = text.match(/^\/mcp:([^:\s]+):(\S+)(\s+.*)?$/);
const mcpMatch = text.match(/^\/mcp:([^:\s]+):(\S+)(?:\s(.*))?$/);
if (mcpMatch) {
const [, server, command, args] = mcpMatch;
text = `/${server}:${command} (MCP)${args || ""}`;
text = `/${server}:${command} (MCP)${args ? ` ${args}` : ""}`;
}
content.push({ type: "text", text });
break;
@@ -1849,8 +2157,8 @@ export function toAcpNotifications(
const alreadyCached = chunk.id in toolUseCache;
toolUseCache[chunk.id] = chunk;
if (chunk.name === "TodoWrite") {
// @ts-expect-error - sometimes input is empty object
if (Array.isArray(chunk.input.todos)) {
// @ts-expect-error - sometimes input is empty object or undefined
if (Array.isArray(chunk.input?.todos)) {
update = {
sessionUpdate: "plan",
entries: planEntries(chunk.input as { todos: ClaudePlanEntry[] }),
@@ -2004,6 +2312,7 @@ export function toAcpNotifications(
case "container_upload":
case "compaction":
case "compaction_delta":
case "advisor_tool_result":
break;
default:
@@ -2086,5 +2395,45 @@ export function runAcp() {
const output = nodeToWebReadable(process.stdin);
const stream = ndJsonStream(input, output);
new AgentSideConnection((client) => new ClaudeAcpAgent(client), stream);
let agent!: ClaudeAcpAgent;
const connection = new AgentSideConnection((client) => {
agent = new ClaudeAcpAgent(client);
return agent;
}, stream);
return { connection, agent };
}
function commonPrefixLength(a: string, b: string) {
let i = 0;
while (i < a.length && i < b.length && a[i] === b[i]) {
i++;
}
return i;
}
/** Best-effort first guess of a model's context window from its ID, used only
* until a `result` message arrives with the authoritative `modelUsage` value.
* Anthropic 1M-context variants encode "1m" as a distinct token in the SDK
* model ID (e.g., "claude-opus-4-6-1m"), which `\b1m\b` catches without also
* matching things like "10m" or embedded substrings. */
function inferContextWindowFromModel(model: string): number | null {
if (/\b1m\b/i.test(model)) return 1_000_000;
return null;
}
function getMatchingModelUsage(modelUsage: Record<string, ModelUsage>, currentModel: string) {
let bestKey: string | null = null;
let bestLen = 0;
for (const key of Object.keys(modelUsage)) {
const len = commonPrefixLength(key, currentModel);
if (len > bestLen) {
bestLen = len;
bestKey = key;
}
}
if (bestKey) {
return modelUsage[bestKey];
}
}

View File

@@ -24,8 +24,23 @@ if (process.argv.includes("--cli")) {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
});
runAcp();
const { connection, agent } = runAcp();
// Keep process alive
async function shutdown() {
await agent.dispose().catch((err) => {
console.error("Error during cleanup:", err);
});
process.exit(0);
}
// Exit cleanly when the ACP connection closes (e.g. stdin EOF, transport
// error). Without this, `process.stdin.resume()` keeps the event loop
// alive indefinitely, causing orphan process accumulation in oneshot mode.
connection.closed.then(shutdown);
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
// Keep process alive while connection is open
process.stdin.resume();
}

View File

@@ -6,6 +6,7 @@ export {
streamEventToAcpNotifications,
type ToolUpdateMeta,
type NewSessionMeta,
type SDKMessageFilter,
} from "./acp-agent.js";
export {
loadManagedSettings,

View File

@@ -25,9 +25,14 @@ export interface ClaudeCodeSettings {
}
/**
* Reads and parses a JSON settings file, returning an empty object if not found or invalid
* Reads and parses a JSON settings file, returning an empty object if not found or invalid.
* Silently ignores missing files (ENOENT) but logs warnings for other errors
* (malformed JSON, permission errors, etc.) to aid debugging.
*/
async function loadSettingsFile(filePath: string | null): Promise<ClaudeCodeSettings> {
async function loadSettingsFile(
filePath: string | null,
logger?: { error: (...args: any[]) => void },
): Promise<ClaudeCodeSettings> {
if (!filePath) {
return {};
}
@@ -35,7 +40,11 @@ async function loadSettingsFile(filePath: string | null): Promise<ClaudeCodeSett
try {
const content = await fs.promises.readFile(filePath, "utf-8");
return JSON.parse(content) as ClaudeCodeSettings;
} catch {
} catch (error) {
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
return {};
}
logger?.error(`Failed to load settings from ${filePath}:`, error);
return {};
}
}
@@ -83,7 +92,9 @@ export class SettingsManager {
private onChange?: () => void;
private logger: { log: (...args: any[]) => void; error: (...args: any[]) => void };
private initialized = false;
private disposed = false;
private debounceTimer: ReturnType<typeof setTimeout> | null = null;
private initPromise: Promise<void> | null = null;
constructor(cwd: string, options?: SettingsManagerOptions) {
this.cwd = cwd;
@@ -98,10 +109,19 @@ export class SettingsManager {
if (this.initialized) {
return;
}
if (this.initPromise) {
return this.initPromise;
}
await this.loadAllSettings();
this.setupWatchers();
this.initialized = true;
this.disposed = false;
this.initPromise = this.loadAllSettings().then(() => {
if (!this.disposed) {
this.setupWatchers();
this.initialized = true;
}
this.initPromise = null;
});
return this.initPromise;
}
/**
@@ -130,10 +150,10 @@ export class SettingsManager {
*/
private async loadAllSettings(): Promise<void> {
const [userSettings, projectSettings, localSettings, enterpriseSettings] = await Promise.all([
loadSettingsFile(this.getUserSettingsPath()),
loadSettingsFile(this.getProjectSettingsPath()),
loadSettingsFile(this.getLocalSettingsPath()),
loadSettingsFile(getManagedSettingsPath()),
loadSettingsFile(this.getUserSettingsPath(), this.logger),
loadSettingsFile(this.getProjectSettingsPath(), this.logger),
loadSettingsFile(this.getLocalSettingsPath(), this.logger),
loadSettingsFile(getManagedSettingsPath(), this.logger),
]);
this.userSettings = userSettings;
@@ -226,9 +246,14 @@ export class SettingsManager {
this.debounceTimer = setTimeout(async () => {
this.debounceTimer = null;
if (this.disposed) {
return;
}
try {
await this.loadAllSettings();
this.onChange?.();
if (!this.disposed) {
this.onChange?.();
}
} catch (error) {
this.logger.error("Failed to reload settings:", error);
}
@@ -259,7 +284,6 @@ export class SettingsManager {
this.dispose();
this.cwd = cwd;
this.initialized = false;
await this.initialize();
}
@@ -267,6 +291,10 @@ export class SettingsManager {
* Disposes of file watchers and cleans up resources
*/
dispose(): void {
this.disposed = true;
this.initialized = false;
this.initPromise = null;
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
@@ -276,6 +304,5 @@ export class SettingsManager {
watcher.close();
}
this.watchers = [];
this.initialized = false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
import { mkdtemp, rm } from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { AgentSideConnection, SessionNotification } from "@agentclientprotocol/sdk";
import type { Options } from "@anthropic-ai/claude-agent-sdk";
import type { ClaudeAcpAgent as ClaudeAcpAgentType } from "../acp-agent.js";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
let capturedOptions: Options | undefined;
vi.mock("@anthropic-ai/claude-agent-sdk", async () => ({
...(await vi.importActual<typeof import("@anthropic-ai/claude-agent-sdk")>(
"@anthropic-ai/claude-agent-sdk",
)),
query: ({ options }: { options: Options }) => {
capturedOptions = options;
return {
initializationResult: async () => ({
models: [{ value: "claude-sonnet-4-5", displayName: "Claude Sonnet", description: "Fast" }],
}),
setModel: async () => {},
supportedCommands: async () => [],
[Symbol.asyncIterator]: async function* () {},
};
},
}));
vi.mock("../tools.js", async () => ({
...(await vi.importActual<typeof import("../tools.js")>("../tools.js")),
registerHookCallback: vi.fn(),
}));
describe("additionalRoots", () => {
let agent: ClaudeAcpAgentType;
const tempDirs: string[] = [];
const newSession = (meta: Record<string, unknown>, cwd = "/test") =>
agent.newSession({ cwd, mcpServers: [], _meta: meta });
beforeEach(async () => {
capturedOptions = undefined;
tempDirs.length = 0;
vi.resetModules();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
agent = new ClaudeAcpAgent({
sessionUpdate: async (_notification: SessionNotification) => {},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection);
});
afterEach(
async () =>
void (await Promise.all(tempDirs.map((dir) => rm(dir, { recursive: true, force: true })))),
);
it("passes through relative roots as provided", async () => {
const projectRoot = await mkdtemp(path.join(os.tmpdir(), "claude-project-"));
tempDirs.push(projectRoot);
await newSession({ additionalRoots: ["."] }, projectRoot);
expect(capturedOptions!.additionalDirectories).toEqual(["."]);
});
it("merges additionalRoots with user additionalDirectories without normalization", async () => {
const root = await mkdtemp(path.join(os.tmpdir(), "claude-root-"));
tempDirs.push(root);
await newSession({
additionalRoots: ["", root],
claudeCode: { options: { additionalDirectories: ["/workspace/shared"] } },
});
expect(capturedOptions!.additionalDirectories).toEqual(["/workspace/shared", "", root]);
});
});

View File

@@ -2,6 +2,20 @@ import { describe, expect, it, Mock, vi, afterEach, beforeEach } from "vitest";
import { ClaudeAcpAgent } from "../acp-agent.js";
import { AgentSideConnection } from "@agentclientprotocol/sdk";
const mockQuery = vi.hoisted(() =>
vi.fn(() => ({
initializationResult: vi.fn().mockResolvedValue({
models: [{ value: "id", displayName: "name", description: "description" }],
}),
setModel: vi.fn(),
supportedCommands: vi.fn().mockResolvedValue([]),
})),
);
vi.mock("@anthropic-ai/claude-agent-sdk", () => ({
query: mockQuery,
}));
describe("authorization", () => {
beforeEach(() => {
vi.useFakeTimers();
@@ -17,20 +31,6 @@ describe("authorization", () => {
});
async function createAgentMock(): Promise<[ClaudeAcpAgent, Mock]> {
const mockQuery = vi.hoisted(() =>
vi.fn(() => ({
initializationResult: vi.fn().mockResolvedValue({
models: [{ value: "id", displayName: "name", description: "description" }],
}),
setModel: vi.fn(),
supportedCommands: vi.fn().mockResolvedValue([]),
})),
);
vi.mock("@anthropic-ai/claude-agent-sdk", () => ({
query: mockQuery,
}));
const connectionMock = {
sessionUpdate: async (_: any) => {},
} as AgentSideConnection;
@@ -123,14 +123,17 @@ describe("authorization", () => {
} as any,
});
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-login" }),
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "gateway" }),
);
});
it("hide terminal auth even when terminal-auth is set", async () => {
it("hide claude auth but still show console login when terminal-auth is set", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", { ...process, argv: ["--hide-claude-auth"] });
@@ -140,7 +143,88 @@ describe("authorization", () => {
_meta: { "terminal-auth": true },
},
});
expect(initializeResponse.authMethods).toStrictEqual([]);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
it("hide claude auth but still show console login with terminal capability", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", { ...process, argv: ["--hide-claude-auth"] });
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
auth: { terminal: true },
},
});
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
it("SSH session falls back to single legacy login method", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", { ...process, env: { ...process.env, SSH_TTY: "/dev/pts/0" } });
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: { auth: { terminal: true } },
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "claude-login" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
it("CLAUDE_CODE_REMOTE falls back to single legacy login method", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", { ...process, env: { ...process.env, CLAUDE_CODE_REMOTE: "1" } });
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: { auth: { terminal: true } },
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "claude-login" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
it("remote environment respects hide-claude-auth", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", {
...process,
argv: ["--hide-claude-auth"],
env: { ...process.env, SSH_CONNECTION: "192.168.1.1 12345 192.168.1.2 22" },
});
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: { auth: { terminal: true } },
});
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "claude-login" }),
);
});
it("show claude authentication", async () => {
@@ -152,7 +236,10 @@ describe("authorization", () => {
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "claude-login" }),
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
});

View File

@@ -93,7 +93,10 @@ describe("session config options", () => {
cancelled: false,
permissionMode: "default",
settingsManager: {},
modes: structuredClone(MOCK_MODES),
models: structuredClone(MOCK_MODELS),
configOptions: structuredClone(MOCK_CONFIG_OPTIONS),
contextWindowSize: 200000,
};
}

View File

@@ -0,0 +1,148 @@
import { describe, it, expect } from "vitest";
import { randomUUID } from "crypto";
import { AgentSideConnection, RequestError, SessionNotification } from "@agentclientprotocol/sdk";
import { query, getSessionMessages } from "@anthropic-ai/claude-agent-sdk";
import { ClaudeAcpAgent } from "../acp-agent.js";
import { Pushable } from "../utils.js";
import type { SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
function createMockClient(): AgentSideConnection {
return {
sessionUpdate: async (_notification: SessionNotification) => {},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection;
}
describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("session load/resume lifecycle", () => {
it("SDK: session created but never prompted has no messages and is not resumable", async () => {
// Create a session via the SDK, initialize it, but never send a prompt
const sessionId = randomUUID();
const input = new Pushable<SDKUserMessage>();
const q = query({
prompt: input,
options: {
systemPrompt: { type: "preset", preset: "claude_code" },
sessionId,
settingSources: ["user", "project", "local"],
includePartialMessages: true,
},
});
// initializationResult() works without needing a prompt pushed
const initResult = await q.initializationResult();
expect(initResult).toBeDefined();
// Close without ever prompting
input.end();
q.return(undefined);
// Verify no messages were stored
const messages = await getSessionMessages(sessionId);
expect(messages).toEqual([]);
// Verify the session is not resumable
const input2 = new Pushable<SDKUserMessage>();
const q2 = query({
prompt: input2,
options: {
systemPrompt: { type: "preset", preset: "claude_code" },
resume: sessionId,
settingSources: ["user", "project", "local"],
includePartialMessages: true,
},
});
await expect(q2.initializationResult()).rejects.toThrow(
/No conversation found with session ID/,
);
input2.end();
q2.return(undefined);
}, 30000);
it("ACP: loadSession throws resourceNotFound for a non-existent session", async () => {
const agent = new ClaudeAcpAgent(createMockClient());
const bogusSessionId = randomUUID();
try {
await expect(
agent.loadSession({
sessionId: bogusSessionId,
cwd: process.cwd(),
mcpServers: [],
}),
).rejects.toThrow(RequestError);
} finally {
await agent.dispose();
}
}, 30000);
it("ACP: resumeSession throws resourceNotFound for a non-existent session", async () => {
const agent = new ClaudeAcpAgent(createMockClient());
const bogusSessionId = randomUUID();
try {
await expect(
agent.unstable_resumeSession({
sessionId: bogusSessionId,
cwd: process.cwd(),
mcpServers: [],
}),
).rejects.toThrow(RequestError);
} finally {
await agent.dispose();
}
}, 30000);
it("ACP: newSession without prompt, then loadSession on fresh agent throws resourceNotFound", async () => {
// Step 1: Create a real session via ACP, never prompt, dispose
const agentA = new ClaudeAcpAgent(createMockClient());
const { sessionId } = await agentA.newSession({
cwd: process.cwd(),
mcpServers: [],
});
expect(sessionId).toBeDefined();
await agentA.dispose();
// Step 2: Fresh agent tries to load that session
const agentB = new ClaudeAcpAgent(createMockClient());
try {
await expect(
agentB.loadSession({
sessionId,
cwd: process.cwd(),
mcpServers: [],
}),
).rejects.toThrow(RequestError);
} finally {
await agentB.dispose();
}
}, 30000);
it("ACP: newSession without prompt, then resumeSession on fresh agent throws resourceNotFound", async () => {
const agentA = new ClaudeAcpAgent(createMockClient());
const { sessionId } = await agentA.newSession({
cwd: process.cwd(),
mcpServers: [],
});
await agentA.dispose();
const agentB = new ClaudeAcpAgent(createMockClient());
try {
await expect(
agentB.unstable_resumeSession({
sessionId,
cwd: process.cwd(),
mcpServers: [],
}),
).rejects.toThrow(RequestError);
} finally {
await agentB.dispose();
}
}, 30000);
});

View File

@@ -11,7 +11,12 @@ import {
BetaBashCodeExecutionToolResultBlockParam,
} from "@anthropic-ai/sdk/resources/beta.mjs";
import { toAcpNotifications, ToolUseCache, Logger } from "../acp-agent.js";
import { toolUpdateFromToolResult, createPostToolUseHook } from "../tools.js";
import {
toolUpdateFromToolResult,
createPostToolUseHook,
toolInfoFromToolUse,
planEntries,
} from "../tools.js";
describe("rawOutput in tool call updates", () => {
const mockClient = {} as AgentSideConnection;
@@ -1235,3 +1240,148 @@ describe("Bash terminal output", () => {
});
});
});
describe("toolInfoFromToolUse - ExitPlanMode", () => {
it("should include plan text in content when input.plan is provided", () => {
const toolUse = {
name: "ExitPlanMode",
id: "toolu_plan_1",
input: {
plan: "# My Plan\n\n## Step 1\nDo something",
planFilePath: "/tmp/plan.md",
},
};
const info = toolInfoFromToolUse(toolUse, false);
expect(info.kind).toBe("switch_mode");
expect(info.title).toBe("Ready to code?");
expect(info.content).toHaveLength(1);
expect(info.content![0]).toEqual({
type: "content",
content: { type: "text", text: "# My Plan\n\n## Step 1\nDo something" },
});
});
it("should return empty content when input.plan is not provided", () => {
const toolUse = {
name: "ExitPlanMode",
id: "toolu_plan_2",
input: {},
};
const info = toolInfoFromToolUse(toolUse, false);
expect(info.kind).toBe("switch_mode");
expect(info.content).toEqual([]);
});
});
describe("toolInfoFromToolUse - undefined input regression", () => {
it("Read with undefined input should not throw", () => {
const toolUse = { name: "Read", id: "toolu_read_undef", input: undefined };
const info = toolInfoFromToolUse(toolUse, false);
expect(info.title).toBe("Read File");
expect(info.locations).toEqual([]);
});
it("Grep with undefined input should not throw", () => {
const toolUse = { name: "Grep", id: "toolu_grep_undef", input: undefined };
const info = toolInfoFromToolUse(toolUse, false);
expect(info.title).toBe("grep");
});
it("Glob with undefined input should not throw", () => {
const toolUse = { name: "Glob", id: "toolu_glob_undef", input: undefined };
const info = toolInfoFromToolUse(toolUse, false);
expect(info.title).toBe("Find");
expect(info.locations).toEqual([]);
});
it("WebSearch with undefined input should not throw", () => {
const toolUse = { name: "WebSearch", id: "toolu_ws_undef", input: undefined };
const info = toolInfoFromToolUse(toolUse, false);
expect(info.title).toBe("Web search");
});
it("TodoWrite with undefined input should not throw", () => {
const toolUse = { name: "TodoWrite", id: "toolu_todo_undef", input: undefined };
const info = toolInfoFromToolUse(toolUse, false);
expect(info.title).toBe("Update TODOs");
});
});
describe("planEntries - undefined input regression", () => {
it("should return empty array when input is undefined", () => {
expect(planEntries(undefined)).toEqual([]);
});
it("should return empty array when input has no todos", () => {
expect(planEntries({} as any)).toEqual([]);
});
it("should still map valid todos correctly", () => {
const result = planEntries({
todos: [
{ content: "Task 1", status: "pending", activeForm: "" },
{ content: "Task 2", status: "completed", activeForm: "" },
],
});
expect(result).toEqual([
{ content: "Task 1", status: "pending", priority: "medium" },
{ content: "Task 2", status: "completed", priority: "medium" },
]);
});
});
describe("toAcpNotifications - TodoWrite with undefined input regression", () => {
const mockClient = {} as AgentSideConnection;
const mockLogger: Logger = { log: () => {}, error: () => {} };
it("should not throw when TodoWrite tool_use has undefined input", () => {
const toolUseCache: ToolUseCache = {};
const notifications = toAcpNotifications(
[
{
type: "tool_use" as const,
id: "toolu_todo_undef",
name: "TodoWrite",
input: undefined as any,
},
],
"assistant",
"test-session",
toolUseCache,
mockClient,
mockLogger,
);
// TodoWrite with undefined input should not crash, and should not emit plan update
const planUpdates = notifications.filter((n) => (n.update as any).sessionUpdate === "plan");
expect(planUpdates).toHaveLength(0);
});
it("should still emit plan update when TodoWrite has valid input", () => {
const toolUseCache: ToolUseCache = {};
const notifications = toAcpNotifications(
[
{
type: "tool_use" as const,
id: "toolu_todo_valid",
name: "TodoWrite",
input: { todos: [{ content: "Do X", status: "pending" }] },
},
],
"assistant",
"test-session",
toolUseCache,
mockClient,
mockLogger,
);
const planUpdates = notifications.filter((n) => (n.update as any).sessionUpdate === "plan");
expect(planUpdates).toHaveLength(1);
});
});

View File

@@ -128,7 +128,7 @@ export function toolInfoFromToolUse(
switch (name) {
case "Agent":
case "Task": {
const input = toolUse.input as AgentInput | BashInput;
const input = toolUse.input as AgentInput | BashInput | undefined;
return {
title: input?.description ? input.description : "Task",
kind: "think",
@@ -145,7 +145,7 @@ export function toolInfoFromToolUse(
}
case "Bash": {
const input = toolUse.input as BashInput;
const input = toolUse.input as BashInput | undefined;
return {
title: input?.command ? input.command : "Terminal",
kind: "execute",
@@ -163,18 +163,18 @@ export function toolInfoFromToolUse(
}
case "Read": {
const input = toolUse.input as FileReadInput;
const input = toolUse.input as FileReadInput | undefined;
let limit = "";
if (input.limit && input.limit > 0) {
if (input?.limit && input.limit > 0) {
limit = " (" + (input.offset ?? 1) + " - " + ((input.offset ?? 1) + input.limit - 1) + ")";
} else if (input.offset) {
} else if (input?.offset) {
limit = " (from line " + input.offset + ")";
}
const displayPath = input.file_path ? toDisplayPath(input.file_path, cwd) : "File";
const displayPath = input?.file_path ? toDisplayPath(input.file_path, cwd) : "File";
return {
title: "Read " + displayPath + limit,
kind: "read",
locations: input.file_path
locations: input?.file_path
? [
{
path: input.file_path,
@@ -187,7 +187,7 @@ export function toolInfoFromToolUse(
}
case "Write": {
const input = toolUse.input as FileWriteInput;
const input = toolUse.input as FileWriteInput | undefined;
let content: ToolCallContent[] = [];
if (input && input.file_path) {
content = [
@@ -216,7 +216,7 @@ export function toolInfoFromToolUse(
}
case "Edit": {
const input = toolUse.input as FileEditInput;
const input = toolUse.input as FileEditInput | undefined;
let content: ToolCallContent[] = [];
if (input && input.file_path && (input.old_string || input.new_string)) {
content = [
@@ -238,44 +238,44 @@ export function toolInfoFromToolUse(
}
case "Glob": {
const input = toolUse.input as GlobInput;
const input = toolUse.input as GlobInput | undefined;
let label = "Find";
if (input.path) {
if (input?.path) {
label += ` \`${input.path}\``;
}
if (input.pattern) {
if (input?.pattern) {
label += ` \`${input.pattern}\``;
}
return {
title: label,
kind: "search",
content: [],
locations: input.path ? [{ path: input.path }] : [],
locations: input?.path ? [{ path: input.path }] : [],
};
}
case "Grep": {
const input = toolUse.input as GrepInput;
const input = toolUse.input as GrepInput | undefined;
let label = "grep";
if (input["-i"]) {
if (input?.["-i"]) {
label += " -i";
}
if (input["-n"]) {
if (input?.["-n"]) {
label += " -n";
}
if (input["-A"] !== undefined) {
if (input?.["-A"] !== undefined) {
label += ` -A ${input["-A"]}`;
}
if (input["-B"] !== undefined) {
if (input?.["-B"] !== undefined) {
label += ` -B ${input["-B"]}`;
}
if (input["-C"] !== undefined) {
if (input?.["-C"] !== undefined) {
label += ` -C ${input["-C"]}`;
}
if (input.output_mode) {
if (input?.output_mode) {
switch (input.output_mode) {
case "files_with_matches":
label += " -l";
@@ -289,27 +289,27 @@ export function toolInfoFromToolUse(
}
}
if (input.head_limit !== undefined) {
if (input?.head_limit !== undefined) {
label += ` | head -${input.head_limit}`;
}
if (input.glob) {
if (input?.glob) {
label += ` --include="${input.glob}"`;
}
if (input.type) {
if (input?.type) {
label += ` --type=${input.type}`;
}
if (input.multiline) {
if (input?.multiline) {
label += " -P";
}
if (input.pattern) {
if (input?.pattern) {
label += ` "${input.pattern}"`;
}
if (input.path) {
if (input?.path) {
label += ` ${input.path}`;
}
@@ -338,14 +338,14 @@ export function toolInfoFromToolUse(
}
case "WebSearch": {
const input = toolUse.input as WebSearchInput;
let label = `"${input.query}"`;
const input = toolUse.input as WebSearchInput | undefined;
let label = input?.query ? `"${input.query}"` : "Web search";
if (input.allowed_domains && input.allowed_domains.length > 0) {
if (input?.allowed_domains && input.allowed_domains.length > 0) {
label += ` (allowed: ${input.allowed_domains.join(", ")})`;
}
if (input.blocked_domains && input.blocked_domains.length > 0) {
if (input?.blocked_domains && input.blocked_domains.length > 0) {
label += ` (blocked: ${input.blocked_domains.join(", ")})`;
}
@@ -357,7 +357,7 @@ export function toolInfoFromToolUse(
}
case "TodoWrite": {
const input = toolUse.input as TodoWriteInput;
const input = toolUse.input as TodoWriteInput | undefined;
return {
title: Array.isArray(input?.todos)
? `Update TODOs: ${input.todos.map((todo: any) => todo.content).join(", ")}`
@@ -368,10 +368,13 @@ export function toolInfoFromToolUse(
}
case "ExitPlanMode": {
const planInput = toolUse.input as { plan?: string } | undefined;
return {
title: "Ready to code?",
kind: "switch_mode",
content: [],
content: planInput?.plan
? [{ type: "content" as const, content: { type: "text" as const, text: planInput.plan } }]
: [],
};
}
@@ -481,7 +484,7 @@ export function toolUpdateFromToolResult(
result.type === "bash_code_execution_result"
) {
const bashResult = result as BetaBashCodeExecutionResultBlock;
output = bashResult.stdout || bashResult.stderr || "";
output = [bashResult.stdout, bashResult.stderr].filter(Boolean).join("\n");
exitCode = bashResult.return_code;
} else if (typeof result === "string") {
output = result;
@@ -658,10 +661,10 @@ export type ClaudePlanEntry = {
activeForm: string;
};
export function planEntries(input: { todos: ClaudePlanEntry[] }): PlanEntry[] {
return input.todos.map((input) => ({
content: input.content,
status: input.status,
export function planEntries(input: { todos: ClaudePlanEntry[] } | undefined): PlanEntry[] {
return (input?.todos ?? []).map((todo) => ({
content: todo.content,
status: todo.status,
priority: "medium",
}));
}