Compare commits

...

244 Commits

Author SHA1 Message Date
Ben Brandt
affc731e3a docs: clarify stream-id tracking and liveStreamed dedup assumptions
Add comments explaining (1) why the streamed-id tracking runs for every
stream_event rather than only parent_tool_use_id === null, and that the
single currentStreamingMessageId field is safe given serialized events,
and (2) that the liveStreamed drop is all-or-nothing per message id.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:03:50 +02:00
cuiyiming.leo95
63b708176e fix: dedup fallback text/thinking per content block, not per message id
The fallback added in dc640e2 keyed its dedup on the assistant message
id: once a message id emitted any text/thinking block, the id was added
to `textStreamedMessageIds` and every later block under that id was
filtered out. That breaks when an OpenAI-compatible gateway (observed
with gpt-5.4) splits a single assistant response into several `assistant`
messages that share one id but each carry a different block — typically
an empty `thinking` block first, then the real `text` block. The empty
thinking block flagged the id, so the actual answer arriving in a later
same-id message was dropped: the client saw the fallback log fire but
received an empty turn.

Track the assembled blocks the fallback already emitted this turn
(`fallbackEmittedBlockKeys`, keyed on id + block type + block content)
instead of flagging the whole message id. Distinct blocks that share an
id are all forwarded, while identical re-deliveries (an incremental block
followed by a consolidated message, or the same message delivered twice)
still dedup. `textStreamedMessageIds` returns to its original meaning —
"was this streamed live via deltas" — and is no longer written by the
fallback. The new set is turn-scoped and cleared alongside it.

Tests cover split-block delivery (empty thinking then text under one id),
multiple distinct text blocks sharing an id, and the
incremental-then-consolidated dedup case.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 23:57:26 -07:00
cuiyiming.leo95
dc640e2dcf fix: fall back to assembled assistant text when no stream deltas arrive
The `assistant` case in the prompt loop unconditionally filtered out
`text` and `thinking` content blocks on the assumption that those had
already been pushed to the client via `stream_event` →
`content_block_delta` notifications. That assumption holds when the
underlying SDK / model proxy emits Anthropic-style streaming deltas, but
it breaks when the model is fronted by a proxy that returns the second
model call (the one that consumes a tool_result) as a single non-
streamed assistant message. In that case `content_block_delta` for the
final text is never produced, the assembled `text` block is filtered
out, and the ACP client receives `stopReason: "end_turn"` with no
`agent_message_chunk` notifications — so the user sees the tool's
progress but an empty final answer.

Track which assistant message ids have actually produced streamed
text/thinking deltas (`textStreamedMessageIds` on `Session`, populated
from `message_start` + `content_block_delta` in the `stream_event`
case). In the `assistant` case, keep the existing filter when the id is
in that set and fall back to forwarding the assembled `text` / `thinking`
blocks as `agent_message_chunk` / `agent_thought_chunk` when it isn't.
The fallback emits exactly once per assistant message id, mirroring the
dedupe pattern already used by `toolUseCache` for tool_use blocks.

Tests cover both branches: a session whose assistant message arrives
with no preceding `content_block_delta` now produces exactly one text
chunk, and a session that did stream the same text via deltas does not
re-emit it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 18:51:35 -07:00
acp-release-bot[bot]
36822c2b75 chore(main): release 0.37.0 (#690)
🤖 I have created a release *beep* *boop*
---


##
[0.37.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.36.1...v0.37.0)
(2026-05-21)


### Features

* add 'Default' option to effort level config
([#701](https://github.com/agentclientprotocol/claude-agent-acp/issues/701))
([9e259d1](9e259d128a))
* **deps:** bump the claude-agent-sdk to 0.3.146
([#700](https://github.com/agentclientprotocol/claude-agent-acp/issues/700))
([72875b2](72875b248c))
* **deps:** bump the minor group with 13 updates
([#689](https://github.com/agentclientprotocol/claude-agent-acp/issues/689))
([f66bc31](f66bc31ae4))
* Emit tool calls for memory recall events
([#703](https://github.com/agentclientprotocol/claude-agent-acp/issues/703))
([a0bfb98](a0bfb98ba7)),
closes
[#650](https://github.com/agentclientprotocol/claude-agent-acp/issues/650)


### Bug Fixes

* Avoid cross-version model alias matches
([#702](https://github.com/agentclientprotocol/claude-agent-acp/issues/702))
([e1e1c69](e1e1c69029))
* Avoid redundant initial model sync
([#704](https://github.com/agentclientprotocol/claude-agent-acp/issues/704))
([b275f6f](b275f6ff7f)),
closes
[#646](https://github.com/agentclientprotocol/claude-agent-acp/issues/646)
* Don't expose /clear in commands
([#705](https://github.com/agentclientprotocol/claude-agent-acp/issues/705))
([cfce130](cfce130707))
* emit "cancelled" instead of "end_turn" when the session was
interrupted.
([#694](https://github.com/agentclientprotocol/claude-agent-acp/issues/694))
([2414a6f](2414a6f98b))
* Recover prompt stream after a failed turn
([#706](https://github.com/agentclientprotocol/claude-agent-acp/issues/706))
([2711f50](2711f506d5)),
closes
[#654](https://github.com/agentclientprotocol/claude-agent-acp/issues/654)

---
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-05-22 00:15:02 +02:00
AceGain
9e259d128a feat: add 'Default' option to effort level config (#701)
Add a "Default" selection to the effort level config option, allowing
users to let the SDK decide the effort level instead of forcing a
specific level. When "default" is selected, applyFlagSettings is called
with effortLevel: undefined, clearing any previous override.

Replaces the previous fallback logic (xhigh -> high ->
supportedLevels[0]) with a simpler "default" fallback that lets the SDK
use its own default.

Please,agree it. The third-party model may not support the 'Effort', or
not support 'high' and 'xhigh'. We need it.

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-05-21 22:11:14 +00:00
Ben Brandt
2711f506d5 fix: Recover prompt stream after a failed turn (#706)
When a prompt errors mid-turn (e.g. a 400/529 from the API), the SDK
leaves a trailing session_state_changed: idle in the query iterator.
The next prompt's first query.next() consumed that stale idle and
short-circuited to end_turn with zero usage, shifting every subsequent
response one slot late until the session was restarted.

In the catch block, call query.interrupt() and drain the iterator
until the trailing idle is consumed (bounded so a misbehaving SDK
can't hang the next prompt). In the finally block, on the error path,
resolve all queued pending prompts as cancelled — the previous code
only resolved one (with handoff semantics), leaking the rest forever.

Closes #654
Supersedes #659, #660, #691
2026-05-21 22:03:39 +00:00
Genhao Liu
2414a6f98b fix: emit "cancelled" instead of "end_turn" when the session was interrupted. (#694)
### Summary

Fix session_state_changed: idle handler to check session.cancelled,
ensuring the prompt response returns stopReason:
  "cancelled" instead of "end_turn" when the session was interrupted.

### Problem

When a client sends session/cancel, the cancel() method sets
session.cancelled = true and calls query.interrupt(). The
SDK then transitions to idle state and emits a session_state_changed
event with state: "idle". However, the handler
for this event returns the prompt response immediately without checking
session.cancelled:

```
  case "session_state_changed": {
    if (message.state === "idle") {
      return { stopReason, usage: sessionUsage(session) };  // stopReason defaults to "end_turn"
    }
    break;
  }
```
Since stopReason is initialized as "end_turn" and may not have been
updated to "cancelled" by a preceding result
message (the result handler at line 601 does check session.cancelled),
the prompt response can incorrectly report
  stopReason: "end_turn" when the turn was actually cancelled.

This causes clients (e.g. JetBrains AI Assistant) to treat the turn as
completed normally rather than cancelled,
  leaving the frontend UI stuck in a "running" state.

### Fix

Check session.cancelled in the session_state_changed: idle handler,
mirroring the checks already present in the done
  handler (line 464) and the result handler (line 601):

```
  case "session_state_changed": {
    if (message.state === "idle") {
      if (session.cancelled) {
        stopReason = "cancelled";
      }
      return { stopReason, usage: sessionUsage(session) };
    }
    break;
  }
```

Per the ACP spec, upon receiving session/cancel the agent must respond
to the original session/prompt request with
StopReason::Cancelled. This fix ensures that obligation is met
regardless of which message type triggers the prompt
  response.

### Test plan

- Start a session, send a prompt, then immediately cancel — verify the
prompt response returns stopReason: "cancelled"
   and the client UI transitions out of "running" state
- Start a session, send a prompt, let it complete normally — verify
stopReason remains "end_turn" (no false
  cancellation)
  - Existing test suite passes (npm run test:run)
2026-05-21 22:00:44 +00:00
Ben Brandt
cfce130707 fix: Don't expose /clear in commands (#705)
Closes #657

This probably isn't the desired fix, but as /clear creates a new
session, it breaks a lot of guarantees on ACP's usage of session ids we
want to uphold. Given you can do session/new to get the same effect, it
seems safer.
2026-05-21 21:31:53 +00:00
Ben Brandt
b275f6ff7f fix: Avoid redundant initial model sync (#704)
Addresses #646
2026-05-21 21:07:46 +00:00
Ben Brandt
a0bfb98ba7 feat: Emit tool calls for memory recall events (#703)
Closes #650
2026-05-21 21:05:45 +00:00
Ben Brandt
e1e1c69029 fix: Avoid cross-version model alias matches (#702)
Partially addresses #639

Deduping may reintroduce issues from #620 so going to hold off on that
for now.
2026-05-21 20:49:29 +00:00
dependabot[bot]
72875b248c feat(deps): bump the claude-agent-sdk to 0.3.146 (#700)
Bumps the minor group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.3.143` | `0.3.146` |
|
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
| `0.96.0` | `0.97.1` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.9.0` | `25.9.1` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.6` | `4.1.7` |
| [hono](https://github.com/honojs/hono) | `4.12.19` | `4.12.21` |


Updates `@anthropic-ai/claude-agent-sdk` from 0.3.143 to 0.3.146
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases">@​anthropic-ai/claude-agent-sdk's
releases</a>.</em></p>
<blockquote>
<h2>v0.3.146</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.146</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.146
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.146
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.146
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.146
</code></pre>
<h2>v0.3.145</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.145</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.145
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.145
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.145
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.145
</code></pre>
<h2>v0.3.144</h2>
<h2>What's changed</h2>
<ul>
<li>Assistant messages and <code>StopFailure</code> hooks now report
<code>error: 'model_not_found'</code> when the selected model doesn't
exist or isn't available, instead of the generic
<code>'invalid_request'</code>. The <code>api_error_status</code> field
on result messages is now documented.</li>
<li>Added <code>@anthropic-ai/claude-agent-sdk/extract</code> export for
<code>bun build --compile</code> consumers: import the platform native
binary with <code>with { type: 'file' }</code>, call
<code>extractFromBunfs(binPath)</code> to copy it out of the compiled
executable's virtual filesystem, and pass the result to
<code>options.pathToClaudeCodeExecutable</code></li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.144
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.144
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.144
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.144
&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">@​anthropic-ai/claude-agent-sdk's
changelog</a>.</em></p>
<blockquote>
<h2>0.3.146</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.146</li>
</ul>
<h2>0.3.145</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.145</li>
</ul>
<h2>0.3.144</h2>
<ul>
<li>Assistant messages and <code>StopFailure</code> hooks now report
<code>error: 'model_not_found'</code> when the selected model doesn't
exist or isn't available, instead of the generic
<code>'invalid_request'</code>. The <code>api_error_status</code> field
on result messages is now documented.</li>
<li>Added <code>@anthropic-ai/claude-agent-sdk/extract</code> export for
<code>bun build --compile</code> consumers: import the platform native
binary with <code>with { type: 'file' }</code>, call
<code>extractFromBunfs(binPath)</code> to copy it out of the compiled
executable's virtual filesystem, and pass the result to
<code>options.pathToClaudeCodeExecutable</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c2f379d9cf"><code>c2f379d</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="a1500f03cf"><code>a1500f0</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="e62865e42f"><code>e62865e</code></a>
chore: Update CHANGELOG.md</li>
<li>See full diff in <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/compare/v0.3.143...v0.3.146">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/sdk` from 0.96.0 to 0.97.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/anthropic-sdk-typescript/releases">@​anthropic-ai/sdk's
releases</a>.</em></p>
<blockquote>
<h2>sdk: v0.97.1</h2>
<h2>0.97.1 (2026-05-19)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.97.0...sdk-v0.97.1">sdk-v0.97.0...sdk-v0.97.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>runner:</strong> skip tool calls SessionToolRunner does not
own (<a
href="9987379abe">9987379</a>)</li>
</ul>
<h2>sdk: v0.97.0</h2>
<h2>0.97.0 (2026-05-19)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.96.0...sdk-v0.97.0">sdk-v0.96.0...sdk-v0.97.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>client:</strong> Add support for self-hosted sandboxes in
CMA with sandbox helpers (<a
href="659a343c82">659a343</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>typescript:</strong> upgrade tsc-multi so that it works with
Node 26 (<a
href="623f71c848">623f71c</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>tests:</strong> remove redundant File import (<a
href="cf821fcc06">cf821fc</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">@​anthropic-ai/sdk's
changelog</a>.</em></p>
<blockquote>
<h2>0.97.1 (2026-05-19)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.97.0...sdk-v0.97.1">sdk-v0.97.0...sdk-v0.97.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>runner:</strong> skip tool calls SessionToolRunner does not
own (<a
href="9987379abe">9987379</a>)</li>
</ul>
<h2>0.97.0 (2026-05-19)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.96.0...sdk-v0.97.0">sdk-v0.96.0...sdk-v0.97.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>client:</strong> Add support for self-hosted sandboxes in
CMA with sandbox helpers (<a
href="659a343c82">659a343</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>typescript:</strong> upgrade tsc-multi so that it works with
Node 26 (<a
href="623f71c848">623f71c</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>tests:</strong> remove redundant File import (<a
href="cf821fcc06">cf821fc</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ac9ece3c56"><code>ac9ece3</code></a>
chore: release main</li>
<li><a
href="1987147935"><code>1987147</code></a>
fix(runner): skip tool calls SessionToolRunner does not own</li>
<li><a
href="409ff0e502"><code>409ff0e</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1052">#1052</a>)</li>
<li>See full diff in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.96.0...sdk-v0.97.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.9.0 to 25.9.1
<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 `vitest` from 4.1.6 to 4.1.7
<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.7</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>runner</strong>: Limit concurrency per task branch in
addition to per leaf callbacks (backport)  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10384">vitest-dev/vitest#10384</a>
<a href="https://github.com/vitest-dev/vitest/commit/4f0f2a1ee"><!-- raw
HTML omitted -->(4f0f2)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.6...v4.1.7">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a09d47236e"><code>a09d472</code></a>
chore: release v4.1.7</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.7/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.3.143
to 0.3.146

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.3.143 to
0.3.146

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.3.143 to
0.3.146

Updates `@oxc-project/types` from 0.130.0 to 0.132.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">@​oxc-project/types's
releases</a>.</em></p>
<blockquote>
<h2>oxc crates_v0.132.0</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>0f26de6 ecmascript: Resolve identifier value type via tracked
constants (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22234">#22234</a>)
(Alexander Lichter)</li>
<li>c27a8cf minifier: Normalize <code>{ x: x }</code> shorthand so
adjacent-if merge is idempotent (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22401">#22401</a>)
(Dunqing)</li>
<li>e431a0e parser: Break extends clause loop on fatal error (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22517">#22517</a>)
(Boshen)</li>
<li>e9ec7c6 minifier: Fold optional chains by base nullishness (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22236">#22236</a>)
(Alexander Lichter)</li>
<li>e6090e7 transformer: Keep enum IIFE when a non-inlinable value
reference remains (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22501">#22501</a>)
(Dunqing)</li>
<li>931b7d6 transformer: Inline const enum members through type-cast
wrappers (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22500">#22500</a>)
(Dunqing)</li>
<li>b9615b2 codegen: Preserve string quotes in require() calls during
minification (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22475">#22475</a>)
(zennnnnnn11)</li>
<li>c73c159 transformer/async-to-generator: Reparent parameter
initializer scopes (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22507">#22507</a>)
(camc314)</li>
<li>ecfd3ca transformer/async-to-generator: Move only parameter bindings
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22503">#22503</a>)
(camc314)</li>
<li>3ce3431 transformer/explicit-resource-managment: Preserve shadowed
for-head block (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22451">#22451</a>)
(camc314)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>ce92c6c semantic: <code>#[inline]</code>
<code>Scoping::get_binding</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22414">#22414</a>)
(Dunqing)</li>
<li>98be95c regular_expression: Track regex flags via bitflags (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22427">#22427</a>)
(Boshen)</li>
<li>dbbc059 jsdoc: Skip should_attach_jsdoc when no remaining comments
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22409">#22409</a>)
(Boshen)</li>
<li>217d7d8 minifier: Index <code>SymbolValues</code> by
<code>SymbolId</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22441">#22441</a>)
(Dunqing)</li>
<li>d782b78 minifier: Use BitSet for LiveUsageCollector live references
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22425">#22425</a>)
(Boshen)</li>
</ul>
<h2>oxc crates_v0.131.0</h2>
<h3>🚀 Features</h3>
<ul>
<li>bc91a17 codegen: Expose <code>Codegen::with_source_type</code>
method (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22432">#22432</a>)
(camc314)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>703557c codegen: Keep <code>exports[STR] = …</code> key as plain
string in minify (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22402">#22402</a>)
(Dunqing)</li>
<li>5ac7e79 minifier: Drop unused-var-init pure IIFEs and preserve
annotation for downstream (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22349">#22349</a>)
(Dunqing)</li>
<li>4ab57eb allocator: Fixed-size allocators use
<code>VirtualAlloc</code> on Windows (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22124">#22124</a>)
(overlookmotel)</li>
<li>66d77eb allocator: Fix segfault on Linux MUSL with fixed-size
allocators (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22388">#22388</a>)
(overlookmotel)</li>
<li>b8fbc1f transformer/object-rest-spread: Correct scope id when moving
bindings (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22419">#22419</a>)
(camc314)</li>
<li>18edc2c codegen: Keep <code>Object.defineProperty</code> property
name as plain string in minify (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22400">#22400</a>)
(Dunqing)</li>
<li>dda33de transformer/explicit-resource-management: Align lexical
binding scopes (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22320">#22320</a>)
(camc314)</li>
<li>8e79de8 transformer: Preserve for-await statement bodies (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22361">#22361</a>)
(camc314)</li>
<li>0cba210 transformer/class: Replace <code>new.target</code> in static
blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22360">#22360</a>)
(camc314)</li>
<li>67ab1c9 transformer/es2018/for-await: Hoist for-await generated
bindings (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22355">#22355</a>)
(camc314)</li>
<li>c3ceb4a transformer/object-rest-spread: Use hoisted scope for
<code>for-of</code> temp refs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22347">#22347</a>)
(camc314)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>73a9043 allocator/bitset: Avoid temp heap <code>String</code>
allocation (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22403">#22403</a>)
(camc314)</li>
<li>8b2f4f9 transformer/object-rest-spread: Collect
<code>Vec&lt;SymbolId</code> over
<code>Vec&lt;BindingIdentifier&gt;</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22418">#22418</a>)
(camc314)</li>
<li>83679ea parser: Split TriviaBuilder::handle_token hot/cold paths (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22415">#22415</a>)
(Boshen)</li>
<li>2c7d781 codegen: Inline identifier-name accessors (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22411">#22411</a>)
(Boshen)</li>
<li>618bc76 diagnostics: Inline <code>OxcDiagnosticInner</code> to avoid
heap allocation (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22406">#22406</a>)
(Boshen)</li>
<li>0b4e158 parser: Reserve cap <code>2</code> for sequence expressions
vec (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22374">#22374</a>)
(camc314)</li>
<li>5f3bdd0 codegen: Add <code>#[inline]</code> to <code>code</code>,
<code>code_len</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22373">#22373</a>)
(camc314)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="63b129182d"><code>63b1291</code></a>
release(crates): oxc v0.132.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22527">#22527</a>)</li>
<li><a
href="564ebbf46f"><code>564ebbf</code></a>
release(crates): oxc v0.131.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22459">#22459</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/crates_v0.132.0/npm/oxc-types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-android-arm64` from 1.0.1 to 1.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-android-arm64's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.2</h2>
<h2>[1.0.2] - 2026-05-20</h2>
<h3>🚀 Features</h3>
<ul>
<li>devtools: emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>update oxc to 0.132.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9449">#9449</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>update oxc to 0.131.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9424">#9424</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>allow checks.* to escalate emissions to hard errors (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9388">#9388</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>dev: support watcher options <code>include</code> and
<code>exclude</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9395">#9395</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>emit warnings for invalid pure annotations (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9381">#9381</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash: keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>call <code>codeSplitting.groups[].name</code> in deterministic order
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>dev/lazy: make <code>resolve_id</code> idempotent when the resolved
id is already a lazy entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9439">#9439</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>chunk-optimization: publish absorbed dynamic-entry namespace
cross-chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9448">#9448</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>treeshake: propagate pure annotation through compound exprs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9431">#9431</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>finalizer: skip redundant init call when barrel executes in same
chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9354">#9354</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>linking: initialize wrapped ESM re-export owners (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9353">#9353</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>do not inherit __toESM across chunks for named-only external imports
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9333">#9333</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9415">#9415</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>watcher: don't write output or emit events after close() (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9328">#9328</a>)
by <a
href="https://github.com/situ2001"><code>@​situ2001</code></a></li>
<li>chunk-optimization: avoid unsafe dynamic-only merges (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9398">#9398</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>cjs: rename CJS-wrapped locals that would shadow chunk-scope names
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9392">#9392</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>dev/lazy: watch lazy modules added in rebuilds (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9391">#9391</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_dev: move dev example to break publish cycle (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9465">#9465</a>)
by <a href="https://github.com/Boshen"><code>@​Boshen</code></a></li>
<li>binding: drop unsafe napi string helper, hoist transform ArcStr (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9456">#9456</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>ecmascript_utils: split rewrite_ident_reference off JsxExt trait (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9417">#9417</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>use <code>ThreadsafeFunction::call_async_catch</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9390">#9390</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>devtools: document <code>@​rolldown/debug</code> usage and package
graph consumption (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9435">#9435</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>replace <code>Inter</code> with system font stack in OG template SVG
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9240">#9240</a>)
by <a
href="https://github.com/yvbopeng"><code>@​yvbopeng</code></a></li>
<li>remove <code>output.comments</code> warning as all issues have been
resolved (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9393">#9393</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>in-depth: clarify @<strong>PURE</strong> scope and document
positions (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9389">#9389</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>readme: remove release candidate notice (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9387">#9387</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>vite-resolve: cache importer existence checks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9443">#9443</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md">@​rolldown/binding-android-arm64's
changelog</a>.</em></p>
<blockquote>
<h2>[1.0.2] - 2026-05-20</h2>
<h3>🚀 Features</h3>
<ul>
<li>devtools: emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>update oxc to 0.132.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9449">#9449</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>update oxc to 0.131.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9424">#9424</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>allow checks.* to escalate emissions to hard errors (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9388">#9388</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>dev: support watcher options <code>include</code> and
<code>exclude</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9395">#9395</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>emit warnings for invalid pure annotations (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9381">#9381</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash: keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>call <code>codeSplitting.groups[].name</code> in deterministic order
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>dev/lazy: make <code>resolve_id</code> idempotent when the resolved
id is already a lazy entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9439">#9439</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>chunk-optimization: publish absorbed dynamic-entry namespace
cross-chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9448">#9448</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>treeshake: propagate pure annotation through compound exprs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9431">#9431</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>finalizer: skip redundant init call when barrel executes in same
chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9354">#9354</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>linking: initialize wrapped ESM re-export owners (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9353">#9353</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>do not inherit __toESM across chunks for named-only external imports
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9333">#9333</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9415">#9415</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>watcher: don't write output or emit events after close() (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9328">#9328</a>)
by <a
href="https://github.com/situ2001"><code>@​situ2001</code></a></li>
<li>chunk-optimization: avoid unsafe dynamic-only merges (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9398">#9398</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>cjs: rename CJS-wrapped locals that would shadow chunk-scope names
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9392">#9392</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>dev/lazy: watch lazy modules added in rebuilds (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9391">#9391</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_dev: move dev example to break publish cycle (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9465">#9465</a>)
by <a href="https://github.com/Boshen"><code>@​Boshen</code></a></li>
<li>binding: drop unsafe napi string helper, hoist transform ArcStr (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9456">#9456</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>ecmascript_utils: split rewrite_ident_reference off JsxExt trait (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9417">#9417</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>use <code>ThreadsafeFunction::call_async_catch</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9390">#9390</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>devtools: document <code>@​rolldown/debug</code> usage and package
graph consumption (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9435">#9435</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>replace <code>Inter</code> with system font stack in OG template SVG
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9240">#9240</a>)
by <a
href="https://github.com/yvbopeng"><code>@​yvbopeng</code></a></li>
<li>remove <code>output.comments</code> warning as all issues have been
resolved (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9393">#9393</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>in-depth: clarify @<strong>PURE</strong> scope and document
positions (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9389">#9389</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>readme: remove release candidate notice (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9387">#9387</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>vite-resolve: cache importer existence checks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9443">#9443</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
<li>binding: reduce plugin string clones (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9436">#9436</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f2757ed768"><code>f2757ed</code></a>
release: v1.0.2 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9478">#9478</a>)</li>
<li><a
href="b88de34520"><code>b88de34</code></a>
docs(devtools): document <code>@​rolldown/debug</code> usage and package
graph consumption ...</li>
<li><a
href="0f811f4d79"><code>0f811f4</code></a>
fix(hash): keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)</li>
<li><a
href="ed010fad05"><code>ed010fa</code></a>
feat(devtools): emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)</li>
<li><a
href="2b0bb7ffe7"><code>2b0bb7f</code></a>
feat(devtools): classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)</li>
<li><a
href="ff6fff24da"><code>ff6fff2</code></a>
fix: call <code>codeSplitting.groups[].name</code> in deterministic
order (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)</li>
<li><a
href="81fcc89b78"><code>81fcc89</code></a>
feat(devtools): map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)</li>
<li><a
href="98619ddbf8"><code>98619dd</code></a>
feat(devtools): mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)</li>
<li><a
href="0c7ac80de7"><code>0c7ac80</code></a>
feat(devtools): make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)</li>
<li><a
href="98e0620775"><code>98e0620</code></a>
feat(devtools): emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rolldown/rolldown/commits/v1.0.2/packages/rolldown">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-darwin-arm64` from 1.0.1 to 1.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-darwin-arm64's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.2</h2>
<h2>[1.0.2] - 2026-05-20</h2>
<h3>🚀 Features</h3>
<ul>
<li>devtools: emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>update oxc to 0.132.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9449">#9449</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>update oxc to 0.131.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9424">#9424</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>allow checks.* to escalate emissions to hard errors (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9388">#9388</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>dev: support watcher options <code>include</code> and
<code>exclude</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9395">#9395</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>emit warnings for invalid pure annotations (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9381">#9381</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash: keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>call <code>codeSplitting.groups[].name</code> in deterministic order
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>dev/lazy: make <code>resolve_id</code> idempotent when the resolved
id is already a lazy entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9439">#9439</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>chunk-optimization: publish absorbed dynamic-entry namespace
cross-chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9448">#9448</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>treeshake: propagate pure annotation through compound exprs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9431">#9431</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>finalizer: skip redundant init call when barrel executes in same
chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9354">#9354</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>linking: initialize wrapped ESM re-export owners (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9353">#9353</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>do not inherit __toESM across chunks for named-only external imports
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9333">#9333</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9415">#9415</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>watcher: don't write output or emit events after close() (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9328">#9328</a>)
by <a
href="https://github.com/situ2001"><code>@​situ2001</code></a></li>
<li>chunk-optimization: avoid unsafe dynamic-only merges (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9398">#9398</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>cjs: rename CJS-wrapped locals that would shadow chunk-scope names
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9392">#9392</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>dev/lazy: watch lazy modules added in rebuilds (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9391">#9391</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_dev: move dev example to break publish cycle (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9465">#9465</a>)
by <a href="https://github.com/Boshen"><code>@​Boshen</code></a></li>
<li>binding: drop unsafe napi string helper, hoist transform ArcStr (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9456">#9456</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>ecmascript_utils: split rewrite_ident_reference off JsxExt trait (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9417">#9417</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>use <code>ThreadsafeFunction::call_async_catch</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9390">#9390</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>devtools: document <code>@​rolldown/debug</code> usage and package
graph consumption (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9435">#9435</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>replace <code>Inter</code> with system font stack in OG template SVG
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9240">#9240</a>)
by <a
href="https://github.com/yvbopeng"><code>@​yvbopeng</code></a></li>
<li>remove <code>output.comments</code> warning as all issues have been
resolved (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9393">#9393</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>in-depth: clarify @<strong>PURE</strong> scope and document
positions (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9389">#9389</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>readme: remove release candidate notice (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9387">#9387</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>vite-resolve: cache importer existence checks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9443">#9443</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md">@​rolldown/binding-darwin-arm64's
changelog</a>.</em></p>
<blockquote>
<h2>[1.0.2] - 2026-05-20</h2>
<h3>🚀 Features</h3>
<ul>
<li>devtools: emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>update oxc to 0.132.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9449">#9449</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>update oxc to 0.131.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9424">#9424</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>allow checks.* to escalate emissions to hard errors (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9388">#9388</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>dev: support watcher options <code>include</code> and
<code>exclude</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9395">#9395</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>emit warnings for invalid pure annotations (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9381">#9381</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash: keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>call <code>codeSplitting.groups[].name</code> in deterministic order
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>dev/lazy: make <code>resolve_id</code> idempotent when the resolved
id is already a lazy entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9439">#9439</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>chunk-optimization: publish absorbed dynamic-entry namespace
cross-chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9448">#9448</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>treeshake: propagate pure annotation through compound exprs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9431">#9431</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>finalizer: skip redundant init call when barrel executes in same
chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9354">#9354</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>linking: initialize wrapped ESM re-export owners (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9353">#9353</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>do not inherit __toESM across chunks for named-only external imports
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9333">#9333</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9415">#9415</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>watcher: don't write output or emit events after close() (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9328">#9328</a>)
by <a
href="https://github.com/situ2001"><code>@​situ2001</code></a></li>
<li>chunk-optimization: avoid unsafe dynamic-only merges (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9398">#9398</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>cjs: rename CJS-wrapped locals that would shadow chunk-scope names
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9392">#9392</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>dev/lazy: watch lazy modules added in rebuilds (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9391">#9391</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_dev: move dev example to break publish cycle (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9465">#9465</a>)
by <a href="https://github.com/Boshen"><code>@​Boshen</code></a></li>
<li>binding: drop unsafe napi string helper, hoist transform ArcStr (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9456">#9456</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>ecmascript_utils: split rewrite_ident_reference off JsxExt trait (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9417">#9417</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>use <code>ThreadsafeFunction::call_async_catch</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9390">#9390</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>devtools: document <code>@​rolldown/debug</code> usage and package
graph consumption (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9435">#9435</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>replace <code>Inter</code> with system font stack in OG template SVG
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9240">#9240</a>)
by <a
href="https://github.com/yvbopeng"><code>@​yvbopeng</code></a></li>
<li>remove <code>output.comments</code> warning as all issues have been
resolved (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9393">#9393</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>in-depth: clarify @<strong>PURE</strong> scope and document
positions (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9389">#9389</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>readme: remove release candidate notice (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9387">#9387</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>vite-resolve: cache importer existence checks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9443">#9443</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
<li>binding: reduce plugin string clones (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9436">#9436</a>)
by <a
href="https://github.com/Brooooooklyn"><code>@​Brooooooklyn</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f2757ed768"><code>f2757ed</code></a>
release: v1.0.2 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9478">#9478</a>)</li>
<li><a
href="b88de34520"><code>b88de34</code></a>
docs(devtools): document <code>@​rolldown/debug</code> usage and package
graph consumption ...</li>
<li><a
href="0f811f4d79"><code>0f811f4</code></a>
fix(hash): keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)</li>
<li><a
href="ed010fad05"><code>ed010fa</code></a>
feat(devtools): emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)</li>
<li><a
href="2b0bb7ffe7"><code>2b0bb7f</code></a>
feat(devtools): classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)</li>
<li><a
href="ff6fff24da"><code>ff6fff2</code></a>
fix: call <code>codeSplitting.groups[].name</code> in deterministic
order (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)</li>
<li><a
href="81fcc89b78"><code>81fcc89</code></a>
feat(devtools): map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)</li>
<li><a
href="98619ddbf8"><code>98619dd</code></a>
feat(devtools): mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)</li>
<li><a
href="0c7ac80de7"><code>0c7ac80</code></a>
feat(devtools): make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)</li>
<li><a
href="98e0620775"><code>98e0620</code></a>
feat(devtools): emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rolldown/rolldown/commits/v1.0.2/packages/rolldown">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-darwin-x64` from 1.0.1 to 1.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-darwin-x64's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.2</h2>
<h2>[1.0.2] - 2026-05-20</h2>
<h3>🚀 Features</h3>
<ul>
<li>devtools: emit package size in PackageGraphReady (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9434">#9434</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: classify package dependency types (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9427">#9427</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: map packages to modules and chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9426">#9426</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: mark used packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9423">#9423</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: make duplicate packages discoverable (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9422">#9422</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>devtools: emit package metadata (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9421">#9421</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>update oxc to 0.132.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9449">#9449</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>update oxc to 0.131.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9424">#9424</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>allow checks.* to escalate emissions to hard errors (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9388">#9388</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>dev: support watcher options <code>include</code> and
<code>exclude</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9395">#9395</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>emit warnings for invalid pure annotations (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9381">#9381</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash: keep chunk file names stable when an unrelated entry is added
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9444">#9444</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>call <code>codeSplitting.groups[].name</code> in deterministic order
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9457">#9457</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>dev/lazy: make <code>resolve_id</code> idempotent when the resolved
id is already a lazy entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9439">#9439</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>chunk-optimization: publish absorbed dynamic-entry namespace
cross-chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9448">#9448</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>treeshake: propagate pure annotation through compound exprs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9431">#9431</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>finalizer: skip redundant init call when barrel executes in same
chunk (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9354">#9354</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>linking: initialize wrapped ESM re-export owners (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9353">#9353</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>do not inherit __toESM across chunks for named-only external imports
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9333">#9333</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9415">#9415</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>watcher: don't write output or emit events after close() (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9328">#9328</a>)
by <a
href="https://github.com/situ2001"><code>@​situ2001</code></a></li>
<li>chunk-optimization: avoid unsafe dynamic-only merges (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9398">#9398</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>cjs: rename CJS-wrapped locals that would shadow chunk-scope names
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9392">#9392</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>dev/lazy: watch lazy modules added in rebuilds (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9391">#9391</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_dev: move dev example to break publish cycle (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9465">#9465</a>)
by <a href="https://github.com/Boshen"><code>@​Boshen</code></a></li>
<li>binding: drop unsafe napi string helper, hoist transform ArcStr (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9456">#9456</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>ecmascript_utils: split rewrite_ident_reference off JsxExt trait (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9417">#9417</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>use <code>ThreadsafeFunction::call_async_catch</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9390">#9390</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>devtools: document <code>@​rolldown/debug</code> usage and package
graph consumption (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9435">#9435</a>)
by <a href="https://github.com/IWANABETHATGUY"><cod...

_Description has been truncated_

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-21 22:35:33 +02:00
dependabot[bot]
f66bc31ae4 feat(deps): bump the minor group with 13 updates (#689)
Bumps the minor group with 13 updates:

| Package | From | To |
| --- | --- | --- |
|
[@agentclientprotocol/sdk](https://github.com/agentclientprotocol/typescript-sdk)
| `0.22.0` | `0.22.1` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.8.0` | `25.9.0` |
|
[@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/project-service](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/project-service)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/scope-manager](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/scope-manager)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/tsconfig-utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/tsconfig-utils)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/type-utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/type-utils)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/types](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/types)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-estree)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils)
| `8.59.3` | `8.59.4` |
|
[@typescript-eslint/visitor-keys](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/visitor-keys)
| `8.59.3` | `8.59.4` |
| [qs](https://github.com/ljharb/qs) | `6.15.1` | `6.15.2` |

Updates `@agentclientprotocol/sdk` from 0.22.0 to 0.22.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/typescript-sdk/releases">@​agentclientprotocol/sdk's
releases</a>.</em></p>
<blockquote>
<h2>v0.22.1</h2>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.22.0...v0.22.1">0.22.1</a>
(2026-05-18)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Event ordering (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/153">#153</a>)
(<a
href="7b632266f0">7b63226</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">@​agentclientprotocol/sdk's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.22.0...v0.22.1">0.22.1</a>
(2026-05-18)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Event ordering (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/153">#153</a>)
(<a
href="7b632266f0">7b63226</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="47da5c6657"><code>47da5c6</code></a>
chore(main): release 0.22.1 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/154">#154</a>)</li>
<li><a
href="7b632266f0"><code>7b63226</code></a>
fix: Event ordering (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/153">#153</a>)</li>
<li>See full diff in <a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.22.0...v0.22.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.8.0 to 25.9.0
<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 `@typescript-eslint/eslint-plugin` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/eslint-plugin's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md">@​typescript-eslint/eslint-plugin's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li><a
href="4302433ae6"><code>4302433</code></a>
fix(eslint-plugin): [no-floating-promises] stack overflow when using
recursiv...</li>
<li><a
href="10b79f1ba8"><code>10b79f1</code></a>
chore(deps): update dependency eslint to v10.4.0 (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12339">#12339</a>)</li>
<li><a
href="2a6765d962"><code>2a6765d</code></a>
chore: clenaup <code>getAwaitedType</code> from
<code>typescript.d.ts</code> (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12302">#12302</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/eslint-plugin">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/parser` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/parser's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md">@​typescript-eslint/parser's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for parser to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/parser">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/project-service` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/project-service's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/project-service/CHANGELOG.md">@​typescript-eslint/project-service's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li><a
href="a98fa1fd0e"><code>a98fa1f</code></a>
fix(project-service): throw error cause in
<code>getParsedConfigFileFromTSServer</code> ...</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/project-service">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/scope-manager` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/scope-manager's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/scope-manager/CHANGELOG.md">@​typescript-eslint/scope-manager's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for scope-manager to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/scope-manager">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/tsconfig-utils` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/tsconfig-utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/tsconfig-utils/CHANGELOG.md">@​typescript-eslint/tsconfig-utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for tsconfig-utils to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/tsconfig-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/type-utils` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/type-utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/type-utils/CHANGELOG.md">@​typescript-eslint/type-utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for type-utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li><a
href="2a6765d962"><code>2a6765d</code></a>
chore: clenaup <code>getAwaitedType</code> from
<code>typescript.d.ts</code> (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/type-utils/issues/12302">#12302</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/type-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/types` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/types's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/types/CHANGELOG.md">@​typescript-eslint/types's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for types to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/typescript-estree` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/typescript-estree's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md">@​typescript-eslint/typescript-estree's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for typescript-estree to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/typescript-estree">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/utils` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md">@​typescript-eslint/utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/visitor-keys` from 8.59.3 to 8.59.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/visitor-keys's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.4</h2>
<h2>8.59.4 (2026-05-18)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-floating-promises] stack
overflow when using recursive types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12294">#12294</a>)</li>
<li><strong>project-service:</strong> throw error cause in
<code>getParsedConfigFileFromTSServer</code> (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12321">#12321</a>)</li>
<li><strong>typescript-eslint:</strong> export Compatible* types from
typescript-eslint to resolve pnpm TS error (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12340">#12340</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>lumir</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/visitor-keys/CHANGELOG.md">@​typescript-eslint/visitor-keys's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.4 (2026-05-18)</h2>
<p>This was a version bump only for visitor-keys to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca6ca1431b"><code>ca6ca14</code></a>
chore(release): publish 8.59.4</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/visitor-keys">compare
view</a></li>
</ul>
</details>
<br />

Updates `qs` from 6.15.1 to 6.15.2
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ljharb/qs/blob/main/CHANGELOG.md">qs's
changelog</a>.</em></p>
<blockquote>
<h2><strong>6.15.2</strong></h2>
<ul>
<li>[Fix] <code>stringify</code>: skip null/undefined entries in
<code>arrayFormat: 'comma'</code> + <code>encodeValuesOnly</code>
instead of crashing in <code>encoder</code></li>
<li>[Fix] <code>stringify</code>: use configured <code>delimiter</code>
after <code>charsetSentinel</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/555">#555</a>)</li>
<li>[Fix] <code>stringify</code>: apply <code>formatter</code> to
encoded key under <code>strictNullHandling</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/554">#554</a>)</li>
<li>[Fix] <code>stringify</code>: skip null/undefined filter-array
entries instead of crashing in <code>encoder</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/551">#551</a>)</li>
<li>[Fix] <code>parse</code>: handle nested bracket groups and add
regression tests (<a
href="https://redirect.github.com/ljharb/qs/issues/530">#530</a>)</li>
<li>[readme] fix grammar (<a
href="https://redirect.github.com/ljharb/qs/issues/550">#550</a>)</li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code></li>
<li>[Tests] add regression tests for keys containing percent-encoded
bracket text</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9aca4076fe"><code>9aca407</code></a>
v6.15.2</li>
<li><a
href="5e33d33447"><code>5e33d33</code></a>
[Dev Deps] update <code>@ljharb/eslint-config</code></li>
<li><a
href="21f80b33e5"><code>21f80b3</code></a>
[Fix] <code>stringify</code>: skip null/undefined entries in
<code>arrayFormat: 'comma'</code> + `e...</li>
<li><a
href="a0a81ea207"><code>a0a81ea</code></a>
[Fix] <code>stringify</code>: use configured <code>delimiter</code>
after <code>charsetSentinel</code></li>
<li><a
href="e3062f78f5"><code>e3062f7</code></a>
[Fix] <code>stringify</code>: apply <code>formatter</code> to encoded
key under <code>strictNullHandling</code></li>
<li><a
href="0c180a40ad"><code>0c180a4</code></a>
[Fix] <code>stringify</code>: skip null/undefined filter-array entries
instead of crashi...</li>
<li><a
href="3a8b94aec1"><code>3a8b94a</code></a>
[Tests] add regression tests for keys containing percent-encoded bracket
text</li>
<li><a
href="96755abd35"><code>96755ab</code></a>
[readme] fix grammar</li>
<li><a
href="a419ce5bbf"><code>a419ce5</code></a>
[Fix] <code>parse</code>: handle nested bracket groups and add
regression tests</li>
<li>See full diff in <a
href="https://github.com/ljharb/qs/compare/v6.15.1...v6.15.2">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-05-19 06:31:55 +02:00
acp-release-bot[bot]
5b2e147b5d chore(main): release 0.36.1 (#687)
🤖 I have created a release *beep* *boop*
---


##
[0.36.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.36.0...v0.36.1)
(2026-05-18)


### Bug Fixes

* flaky authentication bypass for gateway
([#686](https://github.com/agentclientprotocol/claude-agent-acp/issues/686))
([db852dc](db852dcf7c))

---
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-05-18 15:33:45 +02:00
Aleksandr Suhinin
db852dcf7c fix: flaky authentication bypass for gateway (#686)
Sometimes leads to auth required error.
2026-05-18 15:31:51 +02:00
acp-release-bot[bot]
505f9c13c0 chore(main): release 0.36.0 (#683)
🤖 I have created a release *beep* *boop*
---


##
[0.36.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.35.0...v0.36.0)
(2026-05-18)


### Features

* Add experimental session delete support
([#682](https://github.com/agentclientprotocol/claude-agent-acp/issues/682))
([2162d5a](2162d5af62))
* Support experimental additionalDirectories field
([#684](https://github.com/agentclientprotocol/claude-agent-acp/issues/684))
([f37e9a0](f37e9a0d47))

---
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-05-18 13:02:28 +02:00
Ben Brandt
f37e9a0d47 feat: Support experimental additionalDirectories field (#684) 2026-05-18 10:51:45 +00:00
Ben Brandt
2162d5af62 feat: Add experimental session delete support (#682)
- **Update Agent Client Protocol SDK to 0.22.0**
- **feat: Add session delete support**
2026-05-18 10:43:07 +00:00
Ben Brandt
798844726f chore: tighten local-command-stdout handler comment and pass full options (#678)
## Summary

Follow-up cleanup to #649. Two small changes:

- **Tighten the comment block** above the marker-strip branch in
`acp-agent.ts:1119`. The original 15-line block restated history that
already lives in the PR description; replaced with a 5-line "what this
does, and why the no-op case is preserved" comment that points at the
replay path for parallel context.
- **Forward `clientCapabilities`, `parentToolUseId`, `cwd`, and
`taskState`** to `toAcpNotifications` so the new strip-and-render call
matches the sibling call below it at `acp-agent.ts:1192`. Without these
the rendered output loses threading under a wrapping tool use and skips
terminal-output detection.
- **Only log the raw payload when nothing renders** — previously every
marker-containing message was logged AND rendered. Now we render the
stripped prose if anything remains, and fall back to logging only the
pure-marker case (e.g. `/compact`).

## Test plan

- [x] `npm run check` (lint + format) — passes
- [x] `npm run build` (tsc) — passes
- [x] `stripLocalCommandMetadata` unit tests — 8 passed

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 00:45:33 +02:00
acp-release-bot[bot]
f6e12d425e chore(main): release 0.35.0 (#670)
🤖 I have created a release *beep* *boop*
---


##
[0.35.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.34.1...v0.35.0)
(2026-05-16)


### Features

* **deps:** bump actions/create-github-app-token from 3.1.1 to 3.2.0
([#669](https://github.com/agentclientprotocol/claude-agent-acp/issues/669))
([47df1f2](47df1f2a0b))
* **deps:** bump hono from 4.12.18 to 4.12.19 in the minor group
([#671](https://github.com/agentclientprotocol/claude-agent-acp/issues/671))
([5d7165d](5d7165d961))
* **deps:** update to claude-agent-sdk 0.3.143
([#664](https://github.com/agentclientprotocol/claude-agent-acp/issues/664))
([27ca2e5](27ca2e5d40))
* Use SDK settings resolution for defaults
([#677](https://github.com/agentclientprotocol/claude-agent-acp/issues/677))
([eb1259c](eb1259cf88))


### Bug Fixes

* Add task hooks for plan state updates
([#676](https://github.com/agentclientprotocol/claude-agent-acp/issues/676))
([5ff7d50](5ff7d50f0e))
* render local-command-stdout messages instead of dropping them
([#649](https://github.com/agentclientprotocol/claude-agent-acp/issues/649))
([3b9b7d5](3b9b7d5a56))

---
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-05-16 23:41:18 +02:00
Wandering Consciousness
3b9b7d5a56 fix: render local-command-stdout messages instead of dropping them (#649)
AI disclaimer: I identified this bug after noticing that custom skills
produced no output within the Zed Thread/Claude Agent UI. I used Claude
to investigate the issue and develop the fix. I have manually verified
the equivalent fix against an installed
`@zed-industries/claude-code-acp@0.16.1` (the deprecated package Zed
currently ships): custom slash commands that previously produced empty
threads now render the model's response correctly after Zed restart.

## Summary

The live `case "user" / "assistant"` handler in `src/acp-agent.ts` drops
every SDK message whose string content contains
`<local-command-stdout>`. The branch was added to tolerate `/compact`'s
malformed output, but its side-effect is silencing every successful
slash command invocation — custom user-defined skills (whose expanded
bodies arrive wrapped in `<command-*>` + `<local-command-stdout>`
markers) and built-in commands that emit textual output through these
tags.

## Symptom in ACP clients

User types `/some-command` (custom skill, or one of the affected
built-ins). Thread renders the user's `/some-command` bubble at the top,
then nothing — no expanded skill body, no model response. Under the hood
the model has actually received the expansion and produced a turn, but
the user message carrying the expansion never reaches the UI, and the
cascade of subsequent assistant content gets visually decoupled.

In CLI Claude Code the same expansion is printed to the terminal, so the
asymmetry is purely client-side.

## Fix

This repo already ships `stripLocalCommandMetadata` (and its underlying
`stripMarkerTags` helper) — they return `null` for marker-only payloads
and the stripped prose otherwise. They are already wired into session
replay/load (`acp-agent.ts:1385`) but not into the live handler.

The change wires the same helper into the live handler: strip the
markers and route what remains through the existing `toAcpNotifications`
path, preserving the message's role. Pure-marker payloads (e.g.
`/compact`'s) still no-op via the `null` branch, so the existing
`/compact works` integration test in `src/tests/acp-agent.test.ts`
continues to pass.

## Why the previous behaviour was conservative-but-wrong

The inline comment notes the filter exists for `/compact`'s SDK-side
malformed output. That tradeoff swallows a much larger class of
legitimate output (anything that uses `<local-command-stdout>` to wrap
real prose) to avoid one specific command's noise. With
`stripLocalCommandMetadata` available, the conservative behaviour can
target exactly the empty-after-strip case (still `null` → no-op) without
affecting messages that have real prose alongside markers — which is
exactly the regression case the helper's tests were written to cover
(see `src/tests/acp-agent.test.ts:1145-1163`, *"in the original bug
report the entire /model preamble and the user's real 'hi' prompt were
concatenated into a single message. We want to strip the marker tags and
preserve the real prose, not drop the whole message."*).

The fix applies that same principle to the live handler, where the
helper is most needed.

## Refs

- `zed-industries/claude-code-acp#624` — "'Skill' Session Updates
missing when invoked via slash command". The reporter correctly
diagnoses the mechanism: *"Claude just attaches the skill directly to
context when the /command is used, which means the skill loader isn't
used."* The skill body arrives wrapped in markers and gets dropped by
this filter.
- `zed-industries/claude-code-acp#642` — built-in slash commands
(`/usage`, `/status`, `/model`, `/memory`, `/permissions`, `/agents`,
`/mcp`) emit no output when invoked. Same root cause: their output
arrives in messages tagged with `<local-command-stdout>` and is filtered
out.

Both upstream issues remain open against the old repo
`zed-industries/claude-code-acp` and have no comments / linked PRs yet.
Cross-linking here so this PR can be the closing reference for both.

## Test plan

- [x] `npm run check` (lint + format) — passes
- [x] `npm run build` (tsc) — passes
- [x] `npx vitest run src/tests/acp-agent.test.ts -t
"stripLocalCommandMetadata"` — 8 passed
- [ ] Existing `/compact works` integration test — needs a CLI
environment to run; relies on the `null` branch preserving the no-op
behaviour for marker-only payloads, which the helper tests already cover

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-16 21:31:05 +00:00
Ben Brandt
eb1259cf88 feat: Use SDK settings resolution for defaults (#677) 2026-05-16 23:08:50 +02:00
Ben Brandt
5ff7d50f0e fix: Add task hooks for plan state updates (#676) 2026-05-16 21:05:27 +00:00
dependabot[bot]
47df1f2a0b feat(deps): bump actions/create-github-app-token from 3.1.1 to 3.2.0 (#669)
Bumps
[actions/create-github-app-token](https://github.com/actions/create-github-app-token)
from 3.1.1 to 3.2.0.
<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.2.0</h2>
<h2><a
href="https://github.com/actions/create-github-app-token/compare/v3.1.1...v3.2.0">3.2.0</a>
(2026-05-12)</h2>
<h3>Features</h3>
<ul>
<li>add support for enterprise-level GitHub Apps (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/263">#263</a>)
(<a
href="952a2a7073">952a2a7</a>)</li>
<li>support full repository names in <code>repositories</code> input (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/372">#372</a>)
(<a
href="85eb8dd414">85eb8dd</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> bump <code>@​actions/core</code> from 3.0.0
to 3.0.1 in the production-dependencies group (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/364">#364</a>)
(<a
href="43e5c345bf">43e5c34</a>)</li>
<li>validate private-key input (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/376">#376</a>)
(<a
href="f24bbd8964">f24bbd8</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/create-github-app-token/blob/main/CHANGELOG.md">actions/create-github-app-token's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2><a
href="https://github.com/actions/create-github-app-token/compare/v3.1.1...v3.2.0">3.2.0</a>
(2026-05-12)</h2>
<h3>Features</h3>
<ul>
<li>add support for enterprise-level GitHub Apps (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/263">#263</a>)
(<a
href="952a2a7073">952a2a7</a>)</li>
<li>support full repository names in <code>repositories</code> input (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/372">#372</a>)
(<a
href="85eb8dd414">85eb8dd</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> bump <code>@​actions/core</code> from 3.0.0
to 3.0.1 in the production-dependencies group (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/364">#364</a>)
(<a
href="43e5c345bf">43e5c34</a>)</li>
<li>validate private-key input (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/376">#376</a>)
(<a
href="f24bbd8964">f24bbd8</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bcd2ba4921"><code>bcd2ba4</code></a>
chore(main): release 3.2.0 (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/370">#370</a>)</li>
<li><a
href="f24bbd8964"><code>f24bbd8</code></a>
fix: validate private-key input (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/376">#376</a>)</li>
<li><a
href="363531b6d9"><code>363531b</code></a>
docs: capitalize Git as a proper noun in README (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/374">#374</a>)</li>
<li><a
href="fd2801133e"><code>fd28011</code></a>
docs: update procedure to configure Git (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/287">#287</a>)</li>
<li><a
href="85eb8dd414"><code>85eb8dd</code></a>
feat: support full repository names in <code>repositories</code> input
(<a
href="https://redirect.github.com/actions/create-github-app-token/issues/372">#372</a>)</li>
<li><a
href="c9aabb8372"><code>c9aabb8</code></a>
build(deps-dev): bump yaml from 2.8.3 to 2.8.4 in the
development-dependencie...</li>
<li><a
href="e02e816e55"><code>e02e816</code></a>
build(deps-dev): bump undici from 7.24.6 to 8.2.0 (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/366">#366</a>)</li>
<li><a
href="8d835bfd37"><code>8d835bf</code></a>
build(deps-dev): bump esbuild from 0.27.4 to 0.28.0 in the
development-depend...</li>
<li><a
href="952a2a7073"><code>952a2a7</code></a>
feat: add support for enterprise-level GitHub Apps (<a
href="https://redirect.github.com/actions/create-github-app-token/issues/263">#263</a>)</li>
<li><a
href="43e5c345bf"><code>43e5c34</code></a>
fix(deps): bump <code>@​actions/core</code> from 3.0.0 to 3.0.1 in the
production-dependenc...</li>
<li>Additional commits viewable in <a
href="1b10c78c78...bcd2ba4921">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.1.1&new-version=3.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-05-16 22:26:39 +02:00
dependabot[bot]
5d7165d961 feat(deps): bump hono from 4.12.18 to 4.12.19 in the minor group (#671)
Bumps the minor group with 1 update:
[hono](https://github.com/honojs/hono).

Updates `hono` from 4.12.18 to 4.12.19
<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.19</h2>
<h2>What's Changed</h2>
<ul>
<li>ci: pin GitHub Actions to SHAs by <a
href="https://github.com/yusukebe"><code>@​yusukebe</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4932">honojs/hono#4932</a></li>
<li>fix(serveStatic): make options parameter optional in all adapters by
<a href="https://github.com/mixelburg"><code>@​mixelburg</code></a> in
<a
href="https://redirect.github.com/honojs/hono/pull/4934">honojs/hono#4934</a></li>
<li>fix(cookie): return the first cookie when there are multiple cookies
with the same name by <a
href="https://github.com/usualoma"><code>@​usualoma</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4922">honojs/hono#4922</a></li>
<li>feat(bearer-auth): make bearerAuth generic for typed context in
verifyToken by <a
href="https://github.com/justinnais"><code>@​justinnais</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4913">honojs/hono#4913</a></li>
<li>feat(cache): key cache entries by configured vary headers by <a
href="https://github.com/usualoma"><code>@​usualoma</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4915">honojs/hono#4915</a></li>
<li>feat(request): add <code>bytes()</code> by <a
href="https://github.com/yusukebe"><code>@​yusukebe</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4921">honojs/hono#4921</a></li>
<li>fix(stream): upgrade <code>@hono/node-server</code> to v2 and fix
abort handling by <a
href="https://github.com/yusukebe"><code>@​yusukebe</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4940">honojs/hono#4940</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/justinnais"><code>@​justinnais</code></a> made
their first contribution in <a
href="https://redirect.github.com/honojs/hono/pull/4913">honojs/hono#4913</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/honojs/hono/compare/v4.12.18...v4.12.19">https://github.com/honojs/hono/compare/v4.12.18...v4.12.19</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7e62bcd22f"><code>7e62bcd</code></a>
4.12.19</li>
<li><a
href="e2f252a874"><code>e2f252a</code></a>
fix(stream): upgrade <code>@hono/node-server</code> to v2 and fix abort
handling (<a
href="https://redirect.github.com/honojs/hono/issues/4940">#4940</a>)</li>
<li><a
href="54f2f0cfda"><code>54f2f0c</code></a>
feat(request): add <code>bytes()</code> (<a
href="https://redirect.github.com/honojs/hono/issues/4921">#4921</a>)</li>
<li><a
href="e59db594fb"><code>e59db59</code></a>
feat(cache): key cache entries by configured vary headers (<a
href="https://redirect.github.com/honojs/hono/issues/4915">#4915</a>)</li>
<li><a
href="48a7ccbc0e"><code>48a7ccb</code></a>
feat(bearer-auth): make bearerAuth generic for typed context in
verifyToken (...</li>
<li><a
href="ff7522fdcc"><code>ff7522f</code></a>
fix(cookie): return the first cookie when there are multiple cookies
with the...</li>
<li><a
href="26f8c33f23"><code>26f8c33</code></a>
fix(serveStatic): make options parameter optional in all adapters (<a
href="https://redirect.github.com/honojs/hono/issues/4934">#4934</a>)</li>
<li><a
href="16c4e3885f"><code>16c4e38</code></a>
ci: pin GitHub Actions to SHAs (<a
href="https://redirect.github.com/honojs/hono/issues/4932">#4932</a>)</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.12.18...v4.12.19">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.18&new-version=4.12.19)](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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-16 22:26:23 +02:00
dependabot[bot]
27ca2e5d40 feat(deps): update to claude-agent-sdk 0.3.143 (#664)
Bumps the minor group with 11 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@agentclientprotocol/sdk](https://github.com/agentclientprotocol/typescript-sdk)
| `0.21.0` | `0.21.1` |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.132` | `0.3.143` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.6.0` | `25.8.0` |
|
[@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)
| `8.59.2` | `8.59.3` |
|
[@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)
| `8.59.2` | `8.59.3` |
| [eslint](https://github.com/eslint/eslint) | `10.3.0` | `10.4.0` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.5` | `4.1.6` |
| [brace-expansion](https://github.com/juliangruber/brace-expansion) |
`5.0.5` | `5.0.6` |
|
[express-rate-limit](https://github.com/express-rate-limit/express-rate-limit)
| `8.5.1` | `8.5.2` |
| [semver](https://github.com/npm/node-semver) | `7.7.4` | `7.8.0` |
| [type-is](https://github.com/jshttp/type-is) | `2.0.1` | `2.1.0` |


Updates `@agentclientprotocol/sdk` from 0.21.0 to 0.21.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/typescript-sdk/releases">@​agentclientprotocol/sdk's
releases</a>.</em></p>
<blockquote>
<h2>v0.21.1</h2>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.21.0...v0.21.1">0.21.1</a>
(2026-05-14)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>emit .js extensions in generated schema barrel for nodenext
consumers (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/146">#146</a>)
(<a
href="63b96db49d">63b96db</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">@​agentclientprotocol/sdk's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.21.0...v0.21.1">0.21.1</a>
(2026-05-14)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>emit .js extensions in generated schema barrel for nodenext
consumers (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/146">#146</a>)
(<a
href="63b96db49d">63b96db</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e0099180fe"><code>e009918</code></a>
chore(main): release 0.21.1 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/147">#147</a>)</li>
<li><a
href="63b96db49d"><code>63b96db</code></a>
fix: emit .js extensions in generated schema barrel for nodenext
consumers (#...</li>
<li><a
href="dfb5692fb0"><code>dfb5692</code></a>
chore(deps): bump crate-ci/typos from 1.46.0 to 1.46.1 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/144">#144</a>)</li>
<li><a
href="8ca90556b0"><code>8ca9055</code></a>
chore(deps): bump the minor group with 22 updates (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/145">#145</a>)</li>
<li><a
href="7355cdd139"><code>7355cdd</code></a>
chore(deps): bump crate-ci/typos from 1.45.1 to 1.46.0 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/140">#140</a>)</li>
<li><a
href="0b33b85eba"><code>0b33b85</code></a>
chore(deps): bump the minor group with 20 updates (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/141">#141</a>)</li>
<li><a
href="f017cfaf52"><code>f017cfa</code></a>
chore(deps-dev): bump nanoid from 3.3.11 to 3.3.12 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/142">#142</a>)</li>
<li>See full diff in <a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.21.0...v0.21.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.132 to 0.3.143
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases">@​anthropic-ai/claude-agent-sdk's
releases</a>.</em></p>
<blockquote>
<h2>v0.3.143</h2>
<h2>What's changed</h2>
<ul>
<li><code>@anthropic-ai/sdk</code> and
<code>@modelcontextprotocol/sdk</code> are now
<code>peerDependencies</code> instead of <code>dependencies</code>.
Runtime is unaffected (both are bundled); npm/bun/pnpm auto-install
them. yarn classic users should add them explicitly for full TypeScript
type resolution</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.143
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.143
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.143
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.143
</code></pre>
<h2>v0.3.142</h2>
<h2>What's changed</h2>
<ul>
<li><strong>Breaking:</strong> Removed the v2 session API
(<code>unstable_v2_createSession</code>,
<code>unstable_v2_resumeSession</code>, <code>unstable_v2_prompt</code>,
<code>SDKSession</code>, <code>SDKSessionOptions</code>), deprecated
since 0.2.133. Use <code>query()</code> — pass an
<code>AsyncIterable&lt;SDKUserMessage&gt;</code> for multi-turn, or
<code>options.resume</code> to continue a session.</li>
<li><strong>Breaking:</strong> MCP servers now connect in the background
by default; sessions start immediately and slow servers report
<code>status: &quot;pending&quot;</code> in <code>init</code> until
ready. Set <code>MCP_CONNECTION_NONBLOCKING=0</code> to restore the old
behavior of waiting up to 5s before the first query, or mark a server
<code>alwaysLoad: true</code> to require it in turn 1.</li>
<li><strong>Breaking:</strong> Headless and SDK sessions now use Task
tools (<code>TaskCreate</code> / <code>TaskUpdate</code> /
<code>TaskGet</code> / <code>TaskList</code>) instead of
<code>TodoWrite</code>, deprecated since 0.2.136. Tool consumers should
accumulate by task ID instead of replacing a snapshot list.</li>
<li>Surfaced <code>request_id</code>, <code>subagent_type</code>, and
<code>task_description</code> on SDK message types and task system
events</li>
<li>Headless <code>--sdk-url</code> sessions now exit non-zero with a
stderr diagnostic when the remote transport closes permanently
(401/403/404 or WS permanent close), instead of silently exiting 0</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.142
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.142
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.142
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.142
</code></pre>
<h2>v0.2.141</h2>
<h2>What's changed</h2>
<ul>
<li><code>TaskCreateInput</code>, <code>TaskCreateOutput</code>,
<code>TaskGetInput</code>, <code>TaskGetOutput</code>,
<code>TaskUpdateInput</code>, <code>TaskUpdateOutput</code>,
<code>TaskListInput</code>, and <code>TaskListOutput</code> types are
now exported from <code>@anthropic-ai/claude-agent-sdk/sdk-tools</code>
and included in the
<code>ToolInputSchemas</code>/<code>ToolOutputSchemas</code> unions</li>
<li>Aligned <code>@anthropic-ai/sdk</code> dependency to ^0.93.0</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.141
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.141
&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">@​anthropic-ai/claude-agent-sdk's
changelog</a>.</em></p>
<blockquote>
<h2>0.3.143</h2>
<ul>
<li><code>@anthropic-ai/sdk</code> and
<code>@modelcontextprotocol/sdk</code> are now
<code>peerDependencies</code> instead of <code>dependencies</code>.
Runtime is unaffected (both are bundled); npm/bun/pnpm auto-install
them. yarn classic users should add them explicitly for full TypeScript
type resolution</li>
</ul>
<h2>0.3.142</h2>
<ul>
<li><strong>Breaking:</strong> Removed the v2 session API
(<code>unstable_v2_createSession</code>,
<code>unstable_v2_resumeSession</code>, <code>unstable_v2_prompt</code>,
<code>SDKSession</code>, <code>SDKSessionOptions</code>), deprecated
since 0.2.133. Use <code>query()</code> — pass an
<code>AsyncIterable&lt;SDKUserMessage&gt;</code> for multi-turn, or
<code>options.resume</code> to continue a session.</li>
<li><strong>Breaking:</strong> MCP servers now connect in the background
by default; sessions start immediately and slow servers report
<code>status: &quot;pending&quot;</code> in <code>init</code> until
ready. Set <code>MCP_CONNECTION_NONBLOCKING=0</code> to restore the old
behavior of waiting up to 5s before the first query, or mark a server
<code>alwaysLoad: true</code> to require it in turn 1.</li>
<li><strong>Breaking:</strong> Headless and SDK sessions now use Task
tools (<code>TaskCreate</code> / <code>TaskUpdate</code> /
<code>TaskGet</code> / <code>TaskList</code>) instead of
<code>TodoWrite</code>, deprecated since 0.2.136. Tool consumers should
accumulate by task ID instead of replacing a snapshot list.</li>
<li>Surfaced <code>request_id</code>, <code>subagent_type</code>, and
<code>task_description</code> on SDK message types and task system
events</li>
<li>Headless <code>--sdk-url</code> sessions now exit non-zero with a
stderr diagnostic when the remote transport closes permanently
(401/403/404 or WS permanent close), instead of silently exiting 0</li>
</ul>
<h2>0.2.141</h2>
<ul>
<li><code>TaskCreateInput</code>, <code>TaskCreateOutput</code>,
<code>TaskGetInput</code>, <code>TaskGetOutput</code>,
<code>TaskUpdateInput</code>, <code>TaskUpdateOutput</code>,
<code>TaskListInput</code>, and <code>TaskListOutput</code> types are
now exported from <code>@anthropic-ai/claude-agent-sdk/sdk-tools</code>
and included in the
<code>ToolInputSchemas</code>/<code>ToolOutputSchemas</code> unions</li>
<li>Aligned <code>@anthropic-ai/sdk</code> dependency to ^0.93.0</li>
</ul>
<h2>0.2.140</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.140</li>
</ul>
<h2>0.2.139</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.139</li>
</ul>
<h2>0.2.138</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.138</li>
</ul>
<h2>0.2.137</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.137</li>
</ul>
<h2>0.2.136</h2>
<ul>
<li>Added <code>resolveSettings()</code> (alpha) to inspect effective
merged settings without spawning the Claude CLI; reads MDM
(plist/HKLM/HKCU) for parity with CLI startup</li>
<li>Deprecated <code>TodoWrite</code> tool — future versions will switch
to Task tools (<code>TaskCreate</code>, <code>TaskGet</code>,
<code>TaskUpdate</code>, <code>TaskList</code>)</li>
</ul>
<h2>0.2.135</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.135</li>
</ul>
<h2>0.2.134</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.134</li>
</ul>
<h2>0.2.133</h2>
<ul>
<li>Deprecated the unstable V2 session API
(<code>unstable_v2_createSession</code> /
<code>unstable_v2_resumeSession</code> /
<code>unstable_v2_prompt</code>) — use <code>query()</code> instead</li>
<li>Deprecated passing <code>'Skill'</code> in <code>allowedTools</code>
— use the <code>skills</code> option instead</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fa5d004c65"><code>fa5d004</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="dcac1633cc"><code>dcac163</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="b6d0490791"><code>b6d0490</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="b14b7c97ff"><code>b14b7c9</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="ee3fe61081"><code>ee3fe61</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="1d9038531e"><code>1d90385</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="8d0a9588e6"><code>8d0a958</code></a>
Pin GitHub Actions to commit SHAs (<a
href="https://redirect.github.com/anthropics/claude-agent-sdk-typescript/issues/320">#320</a>)</li>
<li><a
href="3ccbe544fd"><code>3ccbe54</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="de7d6c1a35"><code>de7d6c1</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="1b3ab7bd01"><code>1b3ab7b</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.132...v0.3.143">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.6.0 to 25.8.0
<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 `@typescript-eslint/eslint-plugin` from 8.59.2 to 8.59.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/eslint-plugin's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.3</h2>
<h2>8.59.3 (2026-05-11)</h2>
<p>This was a version bump only, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md">@​typescript-eslint/eslint-plugin's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.3 (2026-05-11)</h2>
<p>This was a version bump only for eslint-plugin to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="48e13c0261"><code>48e13c0</code></a>
chore(release): publish 8.59.3</li>
<li><a
href="e26dc8003a"><code>e26dc80</code></a>
docs: update stale links to latest (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12313">#12313</a>)</li>
<li><a
href="44f9625336"><code>44f9625</code></a>
chore(deps): update vitest monorepo to v4.1.5 (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12307">#12307</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/eslint-plugin">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/parser` from 8.59.2 to 8.59.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/parser's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.3</h2>
<h2>8.59.3 (2026-05-11)</h2>
<p>This was a version bump only, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md">@​typescript-eslint/parser's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.3 (2026-05-11)</h2>
<p>This was a version bump only for parser to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="48e13c0261"><code>48e13c0</code></a>
chore(release): publish 8.59.3</li>
<li><a
href="44f9625336"><code>44f9625</code></a>
chore(deps): update vitest monorepo to v4.1.5 (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser/issues/12307">#12307</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/parser">compare
view</a></li>
</ul>
</details>
<br />

Updates `eslint` from 10.3.0 to 10.4.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.4.0</h2>
<h2>Features</h2>
<ul>
<li><a
href="1a45ec596a"><code>1a45ec5</code></a>
feat: check sequence expressions in <code>for-direction</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20701">#20701</a>)
(kuldeep kumar)</li>
<li><a
href="450040bd89"><code>450040b</code></a>
feat: add <code>includeIgnoreFile()</code> to <code>eslint/config</code>
(<a
href="https://redirect.github.com/eslint/eslint/issues/20735">#20735</a>)
(Kirk Waiblinger)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li><a
href="544c0c3da5"><code>544c0c3</code></a>
fix: escape code path DOT labels in debug output (<a
href="https://redirect.github.com/eslint/eslint/issues/20866">#20866</a>)
(Pixel998)</li>
<li><a
href="6799431203"><code>6799431</code></a>
fix: update dependency <code>@​eslint/config-helpers</code> to ^0.6.0
(<a
href="https://redirect.github.com/eslint/eslint/issues/20850">#20850</a>)
(renovate[bot])</li>
<li><a
href="f078fef500"><code>f078fef</code></a>
fix: handle non-array deprecated rule replacements (<a
href="https://redirect.github.com/eslint/eslint/issues/20825">#20825</a>)
(xbinaryx)</li>
</ul>
<h2>Documentation</h2>
<ul>
<li><a
href="7e52a7151f"><code>7e52a71</code></a>
docs: add mention of <code>@eslint-react/eslint-plugin</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20869">#20869</a>)
(Pavel)</li>
<li><a
href="db3468ba74"><code>db3468b</code></a>
docs: tweak wording around ambiguous CJS-vs-ESM config (<a
href="https://redirect.github.com/eslint/eslint/issues/20865">#20865</a>)
(Kirk Waiblinger)</li>
<li><a
href="90846643ec"><code>9084664</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="9cc7387504"><code>9cc7387</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="3d7b548440"><code>3d7b548</code></a>
docs: Update README (GitHub Actions Bot)</li>
<li><a
href="191ec3c0a3"><code>191ec3c</code></a>
docs: Update README (GitHub Actions Bot)</li>
</ul>
<h2>Chores</h2>
<ul>
<li><a
href="6616856f28"><code>6616856</code></a>
chore: upgrade knip to v6 (<a
href="https://redirect.github.com/eslint/eslint/issues/20875">#20875</a>)
(Pixel998)</li>
<li><a
href="d13b084a3a"><code>d13b084</code></a>
ci: ensure auto-created PRs run CI (<a
href="https://redirect.github.com/eslint/eslint/issues/20860">#20860</a>)
(lumir)</li>
<li><a
href="e71c7af86d"><code>e71c7af</code></a>
ci: bump pnpm/action-setup from 6.0.5 to 6.0.7 (<a
href="https://redirect.github.com/eslint/eslint/issues/20862">#20862</a>)
(dependabot[bot])</li>
<li><a
href="d84393dea1"><code>d84393d</code></a>
test: add unit tests for SuppressionsService.applySuppressions() (<a
href="https://redirect.github.com/eslint/eslint/issues/20863">#20863</a>)
(kuldeep kumar)</li>
<li><a
href="24db8cb8e6"><code>24db8cb</code></a>
test: add tests for SuppressionsService.save() (<a
href="https://redirect.github.com/eslint/eslint/issues/20802">#20802</a>)
(kuldeep kumar)</li>
<li><a
href="2ef0549cac"><code>2ef0549</code></a>
chore: update ecosystem plugins (<a
href="https://redirect.github.com/eslint/eslint/issues/20857">#20857</a>)
(github-actions[bot])</li>
<li><a
href="a4297918d2"><code>a429791</code></a>
ci: remove <code>eslint-webpack-plugin</code> types integration test (<a
href="https://redirect.github.com/eslint/eslint/issues/20668">#20668</a>)
(Milos Djermanovic)</li>
<li><a
href="9e37386aa7"><code>9e37386</code></a>
chore: replace <code>recast</code> with range approach in
code-sample-minimizer (<a
href="https://redirect.github.com/eslint/eslint/issues/20682">#20682</a>)
(Copilot)</li>
<li><a
href="0dd1f9ffc9"><code>0dd1f9f</code></a>
test: disable warning for
<code>vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20845">#20845</a>)
(Francesco Trotta)</li>
<li><a
href="9da3c7bc92"><code>9da3c7b</code></a>
refactor: remove deprecated <code>meta.language</code> and migrate
<code>meta.dialects</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20716">#20716</a>)
(Pixel998)</li>
<li><a
href="2099ed12a0"><code>2099ed1</code></a>
refactor: add <code>meta.defaultOptions</code> to more rules, enable
linting (<a
href="https://redirect.github.com/eslint/eslint/issues/20800">#20800</a>)
(xbinaryx)</li>
<li><a
href="f1dfbc9ca5"><code>f1dfbc9</code></a>
chore: update ecosystem plugins (<a
href="https://redirect.github.com/eslint/eslint/issues/20836">#20836</a>)
(github-actions[bot])</li>
<li><a
href="c75941390c"><code>c759413</code></a>
ci: bump pnpm/action-setup from 6.0.3 to 6.0.5 (<a
href="https://redirect.github.com/eslint/eslint/issues/20843">#20843</a>)
(dependabot[bot])</li>
<li><a
href="5b817d6fdc"><code>5b817d6</code></a>
test: add unit tests for lib/shared/ast-utils (<a
href="https://redirect.github.com/eslint/eslint/issues/20838">#20838</a>)
(kuldeep kumar)</li>
<li><a
href="1c13ae3934"><code>1c13ae3</code></a>
test: add unit tests for lib/shared/severity (<a
href="https://redirect.github.com/eslint/eslint/issues/20835">#20835</a>)
(kuldeep kumar)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="452c4010c0"><code>452c401</code></a>
10.4.0</li>
<li><a
href="b6417e8b55"><code>b6417e8</code></a>
Build: changelog update for 10.4.0</li>
<li><a
href="6616856f28"><code>6616856</code></a>
chore: upgrade knip to v6 (<a
href="https://redirect.github.com/eslint/eslint/issues/20875">#20875</a>)</li>
<li><a
href="d13b084a3a"><code>d13b084</code></a>
ci: ensure auto-created PRs run CI (<a
href="https://redirect.github.com/eslint/eslint/issues/20860">#20860</a>)</li>
<li><a
href="7e52a7151f"><code>7e52a71</code></a>
docs: add mention of <code>@eslint-react/eslint-plugin</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/20869">#20869</a>)</li>
<li><a
href="e71c7af86d"><code>e71c7af</code></a>
ci: bump pnpm/action-setup from 6.0.5 to 6.0.7 (<a
href="https://redirect.github.com/eslint/eslint/issues/20862">#20862</a>)</li>
<li><a
href="544c0c3da5"><code>544c0c3</code></a>
fix: escape code path DOT labels in debug output (<a
href="https://redirect.github.com/eslint/eslint/issues/20866">#20866</a>)</li>
<li><a
href="db3468ba74"><code>db3468b</code></a>
docs: tweak wording around ambiguous CJS-vs-ESM config (<a
href="https://redirect.github.com/eslint/eslint/issues/20865">#20865</a>)</li>
<li><a
href="d84393dea1"><code>d84393d</code></a>
test: add unit tests for SuppressionsService.applySuppressions() (<a
href="https://redirect.github.com/eslint/eslint/issues/20863">#20863</a>)</li>
<li><a
href="90846643ec"><code>9084664</code></a>
docs: Update README</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/eslint/compare/v10.3.0...v10.4.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 4.1.5 to 4.1.6
<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.6</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Provide project reference in
<code>ToMatchScreenshotResolvePath</code>  -  by <a
href="https://github.com/macarie"><code>@​macarie</code></a> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10138">vitest-dev/vitest#10138</a>
<a href="https://github.com/vitest-dev/vitest/commit/31882607c"><!-- raw
HTML omitted -->(31882)<!-- raw HTML omitted --></a></li>
<li>Global <code>sequence.concurrent: true</code> with top-level
<code>test(..., { concurrent: false })</code> + depreacte
<code>sequential</code> test API and options  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Codex</strong> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10196">vitest-dev/vitest#10196</a>
<a href="https://github.com/vitest-dev/vitest/commit/2847dfa2a"><!-- raw
HTML omitted -->(2847d)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Simplify orchestrator otel carrier  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10285">vitest-dev/vitest#10285</a>
<a href="https://github.com/vitest-dev/vitest/commit/18af98cee"><!-- raw
HTML omitted -->(18af9)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🏎 Performance</h3>
<ul>
<li>Stringify diff objects only once  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10276">vitest-dev/vitest#10276</a>
<a href="https://github.com/vitest-dev/vitest/commit/9f7b1528c"><!-- raw
HTML omitted -->(9f7b1)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.5...v4.1.6">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a8fd24c1ca"><code>a8fd24c</code></a>
chore: release v4.1.6</li>
<li><a
href="18af98cee1"><code>18af98c</code></a>
fix(browser): simplify orchestrator otel carrier (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10285">#10285</a>)</li>
<li><a
href="31882607cc"><code>3188260</code></a>
feat(browser): provide project reference in
<code>ToMatchScreenshotResolvePath</code> (#...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.2.132
to 0.3.143

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.2.132 to
0.3.143

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.2.132 to
0.3.143

Updates `@eslint/config-helpers` from 0.5.5 to 0.6.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases">@​eslint/config-helpers's
releases</a>.</em></p>
<blockquote>
<h2>plugin-kit: v0.6.0</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/plugin-kit-v0.5.1...plugin-kit-v0.6.0">0.6.0</a>
(2026-01-29)</h2>
<h3>Features</h3>
<ul>
<li>add <code>CustomRuleVisitorWithExit</code> type to
<code>@eslint/plugin-kit</code> (<a
href="https://redirect.github.com/eslint/rewrite/issues/351">#351</a>)
(<a
href="e7d1be4066">e7d1be4</a>)</li>
<li>Add custom rule type helpers to <code>@eslint/plugin-kit</code> (<a
href="https://redirect.github.com/eslint/rewrite/issues/355">#355</a>)
(<a
href="8ac853046a">8ac8530</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.0.1 to ^1.1.0</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>config-helpers: v0.6.0</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-helpers-v0.5.5...config-helpers-v0.6.0">0.6.0</a>
(2026-05-08)</h2>
<h3>Features</h3>
<ul>
<li>Add new <code>includeIgnoreFile()</code> to config-helpers (<a
href="https://redirect.github.com/eslint/rewrite/issues/430">#430</a>)
(<a
href="9b51352902">9b51352</a>)</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">@​eslint/config-helpers's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/config-helpers-v0.5.5...config-helpers-v0.6.0">0.6.0</a>
(2026-05-08)</h2>
<h3>Features</h3>
<ul>
<li>Add new <code>includeIgnoreFile()</code> to config-helpers (<a
href="https://redirect.github.com/eslint/rewrite/issues/430">#430</a>)
(<a
href="9b51352902">9b51352</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/eslint/rewrite/commits/core-v0.6.0/packages/config-helpers">compare
view</a></li>
</ul>
</details>
<br />

Updates `@oxc-project/types` from 0.128.0 to 0.130.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">@​oxc-project/types's
releases</a>.</em></p>
<blockquote>
<h2>oxc crates_v0.130.0</h2>
<h3>🚀 Features</h3>
<ul>
<li>66c9b01 transformer/typescript: Debug_assert that
<code>enum_eval</code> ran in semantic (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22252">#22252</a>)
(Dunqing)</li>
<li>ffe6475 minifier: Fold <code>Array</code> constructor with safe
spreads (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22215">#22215</a>)
(camc314)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>d3d0b18 traverse: Handle
<code>ChainElement::TSNonNullExpression</code> in
<code>GatherNodeParts</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22247">#22247</a>)
(leaysgur)</li>
<li>4e880de transformer/object-rest-spread: Declare temp vars for
computed keys (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22284">#22284</a>)
(camc314)</li>
<li>a7c3e22 semantic: Clear member write target for computed keys (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22302">#22302</a>)
(camc314)</li>
<li>6a8852d codegen: Emit newline after legal-comment orphan flush (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22304">#22304</a>)
(Dunqing)</li>
<li>5da9fda transformer/explicit-resource-management: Preserve class
names (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22306">#22306</a>)
(Dunqing)</li>
<li>b5d970f transformer/explicit-resource-management: Preserve class
names (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22290">#22290</a>)
(camc314)</li>
<li>bc54fd4 minifier: Keep function / class names if direct eval is
present in the scope (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22241">#22241</a>)
(sapphi-red)</li>
<li>7a810c0 minifier: Refresh direct eval flags after DCE (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21787">#21787</a>)
(Dunqing)</li>
<li>dd88726 transformer/legacy-decorator: Preserve accessor type
annotation for emitDecoratorMetadata (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21966">#21966</a>)
(Dunqing)</li>
<li>29a3cd7 codegen: Swap mapping/indent order for top-level decls (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22206">#22206</a>)
(Dunqing)</li>
<li>73b4f40 minifier: Preserve catch binding with direct eval (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22221">#22221</a>)
(camc314)</li>
<li>0e13d17 minifier: Preserve optional chain base side effects (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22219">#22219</a>)
(camc314)</li>
<li>0c7c01c transformer/typescript: Inline optional-chain enum member
access (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21834">#21834</a>)
(Dunqing)</li>
<li>a6aff7e codegen: Emit block/array/object end mapping at close char
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22200">#22200</a>)
(Dunqing)</li>
<li>a099b03 codegen: Emit call end mapping at <code>)</code> position,
not past it (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22199">#22199</a>)
(Dunqing)</li>
<li>5753774 minifier: Cap if-return ternary collapse for firefox (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21841">#21841</a>)
(Gurupungav Narayanan)</li>
<li>2493bdd codegen: Correct sourcemap end mappings for closing
delimiters (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22001">#22001</a>)
(Mark Dalgleish)</li>
<li>3b385e2 minifier: Bail optimizing <code>Array</code> with unknown
arg count (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22188">#22188</a>)
(camc314)</li>
<li>9fa2122 parser: Parse array computed class keys (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22159">#22159</a>)
(camc314)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>a4a6892 napi/parser: Correct code comment (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22278">#22278</a>)
(overlookmotel)</li>
<li>9305373 oxc: Update README (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22178">#22178</a>)
(camc314)</li>
</ul>
<h2>oxc crates_v0.129.0</h2>
<h3>💥 BREAKING CHANGES</h3>
<ul>
<li>0ffbe0d allocator: [<strong>BREAKING</strong>] Remove
<code>Allocator::end_ptr</code> method (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21871">#21871</a>)
(overlookmotel)</li>
</ul>
<h3>🚀 Features</h3>
<ul>
<li>9593ec8 transformer/jsx: Add jsxDEV source metadata for fragments
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21932">#21932</a>)
(Ido Rosenthal)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>81e834c parser: Prevent multiple <code>Parser</code> instances in
binary (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22120">#22120</a>)
(overlookmotel)</li>
<li>429deac napi/parser: Export <code>visitorKeys</code> from
<code>wasm</code> entrypoint (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21996">#21996</a>)
(NullVoxPopuli)</li>
<li>e852911 codegen: Preserve legal comments orphaned by upstream passes
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21575">#21575</a>)
(Dunqing)</li>
<li>e3399ec transformer/class-properties: Preserve RHS in
logical-assignment to static private field (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21950">#21950</a>)
(Dunqing)</li>
<li>c59c199 transformer/typescript: Emit class fields for parameter
properties (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21831">#21831</a>)
(Dunqing)</li>
<li>aaabde4 parser: Attach legal comments to following token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/21670">#21670</a>)
(Dunqing)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="650417ffd0"><code>650417f</code></a>
release(crates): oxc v0.130.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22316">#22316</a>)</li>
<li><a
href="ec00055e64"><code>ec00055</code></a>
release(crates): oxc v0.129.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/22108">#22108</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/crates_v0.130.0/npm/oxc-types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-android-arm64` from 1.0.0-rc.18 to 1.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-android-arm64's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.1</h2>
<h2>[1.0.1] - 2026-05-13</h2>
<h3>🚀 Features</h3>
<ul>
<li>experimental/lazy-barrel: advice on oversized barrel modules (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9236">#9236</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown: inline optional-chain enum access (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9379">#9379</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>chunk-optimization: dedupe already-loaded dynamic deps (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9305">#9305</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>binding: call moduleParsed hook in ParallelJsPlugin (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9318">#9318</a>)
by <a href="https://github.com/jaehafe"><code>@​jaehafe</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>transform: enable <code>enum_eval</code> for
<code>transformSync</code> and vite TS transform (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9325">#9325</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>error: remove severity prefix from diagnostic messages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9262">#9262</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>deps: pin pnpm to 10.23.0 to work around catalog mismatch on Netlify
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9364">#9364</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>ci: pin mimalloc-safe to 0.1.58 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9361">#9361</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>dev/lazy: fix exports of lazy requests in lazy chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9249">#9249</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>rolldown_plugin_vite_resolve: handle errors in
<code>resolveSubpathImports</code> callback (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9355">#9355</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>rolldown_plugin_lazy_compilation: use loadExports for fetched proxy
to preserve original export names (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9132">#9132</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>common: include offending index in HybridIndexVec panic message (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9296">#9296</a>)
by <a href="https://github.com/SAY-5"><code>@​SAY-5</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>ecmascript: extract semantic_builder_for_transform helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9326">#9326</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>test: extract reusable static-import-cycle helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9332">#9332</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>clarify scope of <code>topLevelVar</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9380">#9380</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>meta/design: add ast-mutation design doc (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9338">#9338</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>feat: add ai policy in contribution guide (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9315">#9315</a>)
by <a
href="https://github.com/mdong1909"><code>@​mdong1909</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>binding: enable mimalloc v3 to reduce idle memory (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9349">#9349</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🧪 Testing</h3>
<ul>
<li>mcs: cover require() in <code>$initial</code> group (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9376">#9376</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>add regression for CJS facade chunk merge into entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9351">#9351</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<ul>
<li>switch prepare-release to manual dispatch with version input (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9383">#9383</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>migrate <code>@rolldown/pluginutils</code> to
<code>rolldown/plugins</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9317">#9317</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>deps: pin libmimalloc-sys2 to 0.1.54 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9372">#9372</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>replace <code>igorskyflyer/action-readfile</code> with
<code>cat</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9369">#9369</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>deps: update test262 submodule for tests (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9371">#9371</a>)
by <a
href="https://github.com/rolldown-guard"><code>@​rolldown-guard</code></a>[bot]</li>
<li>use app token for test dep update PRs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9368">#9368</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>replace some actions with gh commands (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9367">#9367</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md">@​rolldown/binding-android-arm64's
changelog</a>.</em></p>
<blockquote>
<h2>[1.0.1] - 2026-05-13</h2>
<h3>🚀 Features</h3>
<ul>
<li>experimental/lazy-barrel: advice on oversized barrel modules (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9236">#9236</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown: inline optional-chain enum access (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9379">#9379</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>chunk-optimization: dedupe already-loaded dynamic deps (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9305">#9305</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>binding: call moduleParsed hook in ParallelJsPlugin (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9318">#9318</a>)
by <a href="https://github.com/jaehafe"><code>@​jaehafe</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>transform: enable <code>enum_eval</code> for
<code>transformSync</code> and vite TS transform (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9325">#9325</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>error: remove severity prefix from diagnostic messages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9262">#9262</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>deps: pin pnpm to 10.23.0 to work around catalog mismatch on Netlify
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9364">#9364</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>ci: pin mimalloc-safe to 0.1.58 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9361">#9361</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>dev/lazy: fix exports of lazy requests in lazy chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9249">#9249</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>rolldown_plugin_vite_resolve: handle errors in
<code>resolveSubpathImports</code> callback (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9355">#9355</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>rolldown_plugin_lazy_compilation: use loadExports for fetched proxy
to preserve original export names (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9132">#9132</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>common: include offending index in HybridIndexVec panic message (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9296">#9296</a>)
by <a href="https://github.com/SAY-5"><code>@​SAY-5</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>ecmascript: extract semantic_builder_for_transform helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9326">#9326</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>test: extract reusable static-import-cycle helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9332">#9332</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>clarify scope of <code>topLevelVar</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9380">#9380</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>meta/design: add ast-mutation design doc (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9338">#9338</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>feat: add ai policy in contribution guide (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9315">#9315</a>)
by <a
href="https://github.com/mdong1909"><code>@​mdong1909</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>binding: enable mimalloc v3 to reduce idle memory (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9349">#9349</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🧪 Testing</h3>
<ul>
<li>mcs: cover require() in <code>$initial</code> group (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9376">#9376</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>add regression for CJS facade chunk merge into entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9351">#9351</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<ul>
<li>switch prepare-release to manual dispatch with version input (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9383">#9383</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>migrate <code>@rolldown/pluginutils</code> to
<code>rolldown/plugins</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9317">#9317</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>deps: pin libmimalloc-sys2 to 0.1.54 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9372">#9372</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>replace <code>igorskyflyer/action-readfile</code> with
<code>cat</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9369">#9369</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>deps: update test262 submodule for tests (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9371">#9371</a>)
by <a
href="https://github.com/rolldown-guard"><code>@​rolldown-guard</code></a>[bot]</li>
<li>use app token for test dep update PRs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9368">#9368</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>replace some actions with gh commands (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9367">#9367</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>replace action-semantic-pull-request with inline regex (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9366">#9366</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="27779450b5"><code>2777945</code></a>
release: v1.0.1 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9384">#9384</a>)</li>
<li><a
href="4e353804a3"><code>4e35380</code></a>
feat(experimental/lazy-barrel): advice on oversized barrel modules (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9236">#9236</a>)</li>
<li><a
href="83d2762658"><code>83d2762</code></a>
docs: clarify scope of <code>topLevelVar</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9380">#9380</a>)</li>
<li><a
href="9ba2e73935"><code>9ba2e73</code></a>
chore: migrate <code>@rolldown/pluginutils</code> to
<code>rolldown/plugins</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9317">#9317</a>)</li>
<li><a
href="ef5796f0ec"><code>ef5796f</code></a>
fix(transform): enable <code>enum_eval</code> for
<code>transformSync</code> and vite TS transform ...</li>
<li><a
href="1f5dce1dc8"><code>1f5dce1</code></a>
fix(error): remove severity prefix from diagnostic messages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9262">#9262</a>)</li>
<li><a
href="fd479191a9"><code>fd47919</code></a>
chore(deps): upgrade oxc to 0.130.0 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9360">#9360</a>)</li>
<li><a
href="4c121d30d1"><code>4c121d3</code></a>
chore(deps): update npm packages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9343">#9343</a>)</li>
<li><a
href="024de36969"><code>024de36</code></a>
fix(rolldown_plugin_vite_resolve): handle errors in
<code>resolveSubpathImports</code> c...</li>
<li><a
href="7e5855c336"><code>7e5855c</code></a>
feat(chunk-optimization): dedupe already-loaded dynamic deps (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9305">#9305</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rolldown/rolldown/commits/v1.0.1/packages/rolldown">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-darwin-arm64` from 1.0.0-rc.18 to 1.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-darwin-arm64's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.1</h2>
<h2>[1.0.1] - 2026-05-13</h2>
<h3>🚀 Features</h3>
<ul>
<li>experimental/lazy-barrel: advice on oversized barrel modules (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9236">#9236</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown: inline optional-chain enum access (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9379">#9379</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>chunk-optimization: dedupe already-loaded dynamic deps (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9305">#9305</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>binding: call moduleParsed hook in ParallelJsPlugin (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9318">#9318</a>)
by <a href="https://github.com/jaehafe"><code>@​jaehafe</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>transform: enable <code>enum_eval</code> for
<code>transformSync</code> and vite TS transform (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9325">#9325</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>error: remove severity prefix from diagnostic messages (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9262">#9262</a>)
by <a
href="https://github.com/Kyujenius"><code>@​Kyujenius</code></a></li>
<li>deps: pin pnpm to 10.23.0 to work around catalog mismatch on Netlify
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9364">#9364</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>ci: pin mimalloc-safe to 0.1.58 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9361">#9361</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>dev/lazy: fix exports of lazy requests in lazy chunks (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9249">#9249</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>rolldown_plugin_vite_resolve: handle errors in
<code>resolveSubpathImports</code> callback (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9355">#9355</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>rolldown_plugin_lazy_compilation: use loadExports for fetched proxy
to preserve original export names (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9132">#9132</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
<li>common: include offending index in HybridIndexVec panic message (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9296">#9296</a>)
by <a href="https://github.com/SAY-5"><code>@​SAY-5</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>ecmascript: extract semantic_builder_for_transform helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9326">#9326</a>)
by <a href="https://github.com/Dunqing"><code>@​Dunqing</code></a></li>
<li>test: extract reusable static-import-cycle helper (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9332">#9332</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>clarify scope of <code>topLevelVar</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9380">#9380</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>meta/design: add ast-mutation design doc (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9338">#9338</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>feat: add ai policy in contribution guide (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9315">#9315</a>)
by <a
href="https://github.com/mdong1909"><code>@​mdong1909</code></a></li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>binding: enable mimalloc v3 to reduce idle memory (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9349">#9349</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🧪 Testing</h3>
<ul>
<li>mcs: cover require() in <code>$initial</code> group (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9376">#9376</a>)
by <a href="https://github.com/hyf0"><code>@​hyf0</code></a></li>
<li>add regression for CJS facade chunk merge into entry (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9351">#9351</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<ul>
<li>switch prepare-release to manual dispatch with version input (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9383">#9383</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>migrate <code>@rolldown/pluginutils</code> to
<code>rolldown/plugins</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9317">#9317</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>deps: pin libmimalloc-sys2 to 0.1.54 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9372">#9372</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>replace <code>igorskyflyer/action-readfile</code> with
<code>cat</code> (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9369">#9369</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>deps: update test262 submodule for tests (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9371">#9371</a>)
by <a
href="https://github.com/rolldown-guard"><code>@​rolldown-guard</code></a>[bot]</li>
<li>use app token for test dep update PRs (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9368">#9368</a>)
by <a
href="https://github.com/sapphi-red"><code>@​sapphi-red</code></a></li>
<li>replace some actions with gh c...

_Description has been truncated_

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-05-16 22:13:53 +02:00
acp-release-bot[bot]
0db6e3d6f8 chore(main): release 0.34.1 (#668)
🤖 I have created a release *beep* *boop*
---


##
[0.34.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.34.0...v0.34.1)
(2026-05-16)


### Bug Fixes

* load credential error for bedrock gateway
([#667](https://github.com/agentclientprotocol/claude-agent-acp/issues/667))
([8d76be3](8d76be356a))

---
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-05-16 08:13:32 +02:00
Aleksandr Suhinin
8d76be356a fix: load credential error for bedrock gateway (#667)
Sometimes leads to long initialization and error if
AWS_BEARER_TOKEN_BEDROCK:
Could not load credentials from any providers
2026-05-16 08:11:04 +02:00
acp-release-bot[bot]
9258652169 chore(main): release 0.34.0 (#666)
🤖 I have created a release *beep* *boop*
---


##
[0.34.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.33.1...v0.34.0)
(2026-05-15)


### Features

* add bedrock gateway authentication
([#665](https://github.com/agentclientprotocol/claude-agent-acp/issues/665))
([002c63a](002c63a78b))

---
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-05-15 20:24:14 +02:00
Aleksandr Suhinin
002c63a78b feat: add bedrock gateway authentication (#665) 2026-05-15 20:20:49 +02:00
acp-release-bot[bot]
e0ea9d898a chore(main): release 0.33.1 (#638)
🤖 I have created a release *beep* *boop*
---


##
[0.33.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.33.0...v0.33.1)
(2026-05-07)


### Bug Fixes

* Honor availableModels settings allowlist
([#637](https://github.com/agentclientprotocol/claude-agent-acp/issues/637))
([867a3a0](867a3a0de2)),
closes
[#620](https://github.com/agentclientprotocol/claude-agent-acp/issues/620)

---
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-05-07 23:19:25 +02:00
Ben Brandt
867a3a0de2 fix: Honor availableModels settings allowlist (#637)
Merge and dedupe entries across settings sources, preserve the
default model, and pass user-specified model IDs through to setModel.

Closes #620
2026-05-07 21:15:04 +00:00
acp-release-bot[bot]
31a8931018 chore(main): release 0.33.0 (#628)
🤖 I have created a release *beep* *boop*
---


##
[0.33.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.32.0...v0.33.0)
(2026-05-07)


### Features

* **deps:** bump the minor group with 14 updates
([#631](https://github.com/agentclientprotocol/claude-agent-acp/issues/631))
([8b43ee8](8b43ee813f))
* **deps:** Update to claude-agent-sdk 0.2.132
([#636](https://github.com/agentclientprotocol/claude-agent-acp/issues/636))
([0c8ff27](0c8ff277f2))


### Bug Fixes

* Handle result origins in ACP agent
([#627](https://github.com/agentclientprotocol/claude-agent-acp/issues/627))
([dba1998](dba199839a))

---
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-05-07 22:45:47 +02:00
dependabot[bot]
0c8ff277f2 feat(deps): Update to claude-agent-sdk 0.2.132 (#636)
Bumps the minor group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.126` | `0.2.132` |
|
[@types/estree](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/estree)
| `1.0.8` | `1.0.9` |
|
[express-rate-limit](https://github.com/express-rate-limit/express-rate-limit)
| `8.4.1` | `8.5.1` |
| [fast-uri](https://github.com/fastify/fast-uri) | `3.1.1` | `3.1.2` |
| [hono](https://github.com/honojs/hono) | `4.12.16` | `4.12.18` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.0.10` | `8.0.11` |


Updates `@anthropic-ai/claude-agent-sdk` from 0.2.126 to 0.2.132
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/anthropics/claude-agent-sdk-typescript/releases">@​anthropic-ai/claude-agent-sdk's
releases</a>.</em></p>
<blockquote>
<h2>v0.2.132</h2>
<h2>What's changed</h2>
<ul>
<li>Documented <code>applyFlagSettings()</code> in the TypeScript Agent
SDK reference and added support for <code>null</code> on top-level keys
to clear flag-settings overrides</li>
<li>Updated to parity with Claude Code v2.1.132</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.132
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.132
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.132
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.132
</code></pre>
<h2>v0.2.131</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.131</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.131
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.131
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.131
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.131
</code></pre>
<h2>v0.2.129</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.129</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.129
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.129
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.129
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.129
&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">@​anthropic-ai/claude-agent-sdk's
changelog</a>.</em></p>
<blockquote>
<h2>0.2.132</h2>
<ul>
<li>Documented <code>applyFlagSettings()</code> in the TypeScript Agent
SDK reference and added support for <code>null</code> on top-level keys
to clear flag-settings overrides</li>
<li>Updated to parity with Claude Code v2.1.132</li>
</ul>
<h2>0.2.131</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.131</li>
</ul>
<h2>0.2.130</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.130</li>
</ul>
<h2>0.2.129</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.129</li>
</ul>
<h2>0.2.128</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.128</li>
</ul>
<h2>0.2.127</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.127</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="82da44ce66"><code>82da44c</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="0fe2005ff2"><code>0fe2005</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="7bc3bd7660"><code>7bc3bd7</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="e76e32558b"><code>e76e325</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.126...v0.2.132">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.2.126
to 0.2.132

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.2.126 to
0.2.132

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.2.126 to
0.2.132

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

Updates `express-rate-limit` from 8.4.1 to 8.5.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/express-rate-limit/express-rate-limit/releases">express-rate-limit's
releases</a>.</em></p>
<blockquote>
<h2>v8.5.1</h2>
<p>You can view the changelog <a
href="https://express-rate-limit.mintlify.app/reference/changelog">here</a>.</p>
<h2>v8.5.0</h2>
<p>You can view the changelog <a
href="https://express-rate-limit.mintlify.app/reference/changelog">here</a>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="50cc3f6345"><code>50cc3f6</code></a>
8.5.1</li>
<li><a
href="92c8e3efd8"><code>92c8e3e</code></a>
chore: bump ip-address library to latest (<a
href="https://redirect.github.com/express-rate-limit/express-rate-limit/issues/626">#626</a>)</li>
<li><a
href="807e383875"><code>807e383</code></a>
8.5.0</li>
<li><a
href="b844137931"><code>b844137</code></a>
v8.5.0 changelog</li>
<li><a
href="ceaffabad1"><code>ceaffab</code></a>
feat: async store init (<a
href="https://redirect.github.com/express-rate-limit/express-rate-limit/issues/621">#621</a>)</li>
<li>See full diff in <a
href="https://github.com/express-rate-limit/express-rate-limit/compare/v8.4.1...v8.5.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `fast-uri` from 3.1.1 to 3.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fastify/fast-uri/releases">fast-uri's
releases</a>.</em></p>
<blockquote>
<h2>v3.1.2</h2>
<h2>⚠️ Security Release</h2>
<ul>
<li>Fix for <a
href="https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc">https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Handle malformed fragment decoding as a parse error by <a
href="https://github.com/mcollina"><code>@​mcollina</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/171">fastify/fast-uri#171</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2">https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="919dd8ea76"><code>919dd8e</code></a>
Bumped v3.1.2</li>
<li><a
href="c65ba57371"><code>c65ba57</code></a>
fixup: linting</li>
<li><a
href="6c86c17c3d"><code>6c86c17</code></a>
Merge commit from fork</li>
<li><a
href="a95158ad30"><code>a95158a</code></a>
Handle malformed fragment decoding without throwing (<a
href="https://redirect.github.com/fastify/fast-uri/issues/171">#171</a>)</li>
<li>See full diff in <a
href="https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `hono` from 4.12.16 to 4.12.18
<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.18</h2>
<h2>Security fixes</h2>
<p>This release includes fixes for the following security issues:</p>
<h3>Cache Middleware ignores Vary: Authorization / Vary: Cookie leading
to cross-user cache leakage</h3>
<p>Affects: Cache Middleware. Fixes missing cache-skip handling for
<code>Vary: Authorization</code> and <code>Vary: Cookie</code>, where a
response cached for one authenticated user could be served to other
users. GHSA-p77w-8qqv-26rm</p>
<h3>CSS Declaration Injection via Style Object Values in JSX SSR</h3>
<p>Affects: hono/jsx. Fixes a missing CSS-context escape for
<code>style</code> object values and property names, where untrusted
input could inject additional CSS declarations. The impact is limited to
CSS and does not allow JavaScript execution. GHSA-qp7p-654g-cw7p</p>
<h3>Improper validation of NumericDate claims (exp, nbf, iat) in JWT
verify()</h3>
<p>Affects: <code>hono/utils/jwt</code>. Fixes improper validation of
<code>exp</code>, <code>nbf</code>, and <code>iat</code> claims, where
falsy, non-finite, or non-numeric values could silently bypass
time-based checks instead of being rejected per RFC 7519.
GHSA-hm8q-7f3q-5f36</p>
<hr />
<p>Users who use the JWT helper, hono/jsx, or the Cache middleware are
strongly encouraged to upgrade to this version.</p>
<h2>v4.12.17</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(jsx): normalize SVG attributes on the <!-- raw HTML omitted -->
root element by <a
href="https://github.com/kfly8"><code>@​kfly8</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4893">honojs/hono#4893</a></li>
<li>fix(ssg): add <code>atom+xml</code> and <code>rss+xml</code> to
<code>defaultExtensionMap</code> by <a
href="https://github.com/yuintei"><code>@​yuintei</code></a> in <a
href="https://redirect.github.com/honojs/hono/pull/4899">honojs/hono#4899</a></li>
<li>fix(cors): make origin optional in CORSOptions by <a
href="https://github.com/truffle-dev"><code>@​truffle-dev</code></a> in
<a
href="https://redirect.github.com/honojs/hono/pull/4905">honojs/hono#4905</a></li>
<li>fix(types): propagate middleware response types to app.on overloads
by <a href="https://github.com/T4ko0522"><code>@​T4ko0522</code></a> in
<a
href="https://redirect.github.com/honojs/hono/pull/4906">honojs/hono#4906</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/kfly8"><code>@​kfly8</code></a> made
their first contribution in <a
href="https://redirect.github.com/honojs/hono/pull/4893">honojs/hono#4893</a></li>
<li><a
href="https://github.com/truffle-dev"><code>@​truffle-dev</code></a>
made their first contribution in <a
href="https://redirect.github.com/honojs/hono/pull/4905">honojs/hono#4905</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/honojs/hono/compare/v4.12.16...v4.12.17">https://github.com/honojs/hono/compare/v4.12.16...v4.12.17</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f10dee89ce"><code>f10dee8</code></a>
4.12.18</li>
<li><a
href="a5bd9ebead"><code>a5bd9eb</code></a>
Merge commit from fork</li>
<li><a
href="58d3d3ad56"><code>58d3d3a</code></a>
Merge commit from fork</li>
<li><a
href="568c2ecc1d"><code>568c2ec</code></a>
Merge commit from fork</li>
<li><a
href="ff2b3d31df"><code>ff2b3d3</code></a>
4.12.17</li>
<li><a
href="52aaaf9714"><code>52aaaf9</code></a>
fix(types): propagate middleware response types to app.on overloads (<a
href="https://redirect.github.com/honojs/hono/issues/4906">#4906</a>)</li>
<li><a
href="76d5589e9b"><code>76d5589</code></a>
fix(cors): make origin optional in CORSOptions (<a
href="https://redirect.github.com/honojs/hono/issues/4905">#4905</a>)</li>
<li><a
href="8f027e5574"><code>8f027e5</code></a>
fix(ssg): add <code>atom+xml</code> and <code>rss+xml</code> to
<code>defaultExtensionMap</code> (<a
href="https://redirect.github.com/honojs/hono/issues/4899">#4899</a>)</li>
<li><a
href="bfba97ca7e"><code>bfba97c</code></a>
fix(jsx): normalize SVG attributes on the &lt;svg&gt; root element (<a
href="https://redirect.github.com/honojs/hono/issues/4893">#4893</a>)</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.12.16...v4.12.18">compare
view</a></li>
</ul>
</details>
<br />

Updates `ip-address` from 10.1.0 to 10.2.0
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/beaugunderson/ip-address/commits">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.0.10 to 8.0.11
<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.11</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.0.11/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.10...v8.0.11">8.0.11</a>
(2026-05-07)<!-- raw HTML omitted --></h2>
<h3>Features</h3>
<ul>
<li>update rolldown to 1.0.0-rc.18 (<a
href="https://redirect.github.com/vitejs/vite/issues/22360">#22360</a>)
(<a
href="3f80524aa1">3f80524</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22334">#22334</a>)
(<a
href="672c96288f">672c962</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22382">#22382</a>)
(<a
href="5c0cfcb83d">5c0cfcb</a>)</li>
<li><strong>glob:</strong> align hmr matcher options with glob
enumeration (<a
href="https://redirect.github.com/vitejs/vite/issues/22306">#22306</a>)
(<a
href="30028f9451">30028f9</a>)</li>
<li>make separate object instance for each environment (<a
href="https://redirect.github.com/vitejs/vite/issues/22276">#22276</a>)
(<a
href="7c2aa3b40b">7c2aa3b</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li><strong>create-vite:</strong> list react-compiler templates in
README (<a
href="https://redirect.github.com/vitejs/vite/issues/22347">#22347</a>)
(<a
href="7c3a61f42d">7c3a61f</a>)</li>
<li>explain mergeConfig skips null/undefined (<a
href="https://redirect.github.com/vitejs/vite/issues/22325">#22325</a>)
(<a
href="2151f701dc">2151f70</a>)</li>
<li>mention native config loader in CLI options (<a
href="https://redirect.github.com/vitejs/vite/issues/22348">#22348</a>)
(<a
href="0420c5d37b">0420c5d</a>)</li>
<li>update evan's x handle (<a
href="640202a216">640202a</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li><strong>deps:</strong> update dependency tsdown to ^0.21.10 (<a
href="https://redirect.github.com/vitejs/vite/issues/22333">#22333</a>)
(<a
href="3b51e05021">3b51e05</a>)</li>
<li><strong>deps:</strong> update rolldown-related dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22383">#22383</a>)
(<a
href="555ff36de7">555ff36</a>)</li>
<li><strong>deps:</strong> update transitive packages to fix npm audit
alerts (<a
href="https://redirect.github.com/vitejs/vite/issues/22316">#22316</a>)
(<a
href="86aee6268a">86aee62</a>)</li>
</ul>
<h3>Code Refactoring</h3>
<ul>
<li>devtools integration (<a
href="https://redirect.github.com/vitejs/vite/issues/22312">#22312</a>)
(<a
href="3c8bf064ec">3c8bf06</a>)</li>
<li>remove unnecessary async (<a
href="https://redirect.github.com/vitejs/vite/issues/22296">#22296</a>)
(<a
href="b31fd355d9">b31fd35</a>)</li>
<li>show direct path type in bad character warning (<a
href="https://redirect.github.com/vitejs/vite/issues/22339">#22339</a>)
(<a
href="0c162e96a6">0c162e9</a>)</li>
</ul>
<h3>Tests</h3>
<ul>
<li><strong>create-vite:</strong> use short help alias (<a
href="https://redirect.github.com/vitejs/vite/issues/22389">#22389</a>)
(<a
href="994ab66bc4">994ab66</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="66f3194aa8"><code>66f3194</code></a>
release: v8.0.11</li>
<li><a
href="5c0cfcb83d"><code>5c0cfcb</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22382">#22382</a>)</li>
<li><a
href="555ff36de7"><code>555ff36</code></a>
chore(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22383">#22383</a>)</li>
<li><a
href="b31fd355d9"><code>b31fd35</code></a>
refactor: remove unnecessary async (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22296">#22296</a>)</li>
<li><a
href="3c8bf064ec"><code>3c8bf06</code></a>
refactor: devtools integration (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22312">#22312</a>)</li>
<li><a
href="7c2aa3b40b"><code>7c2aa3b</code></a>
fix: make separate object instance for each environment (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22276">#22276</a>)</li>
<li><a
href="3f80524aa1"><code>3f80524</code></a>
feat: update rolldown to 1.0.0-rc.18 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22360">#22360</a>)</li>
<li><a
href="0c162e96a6"><code>0c162e9</code></a>
refactor: show direct path type in bad character warning (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22339">#22339</a>)</li>
<li><a
href="672c96288f"><code>672c962</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22334">#22334</a>)</li>
<li><a
href="30028f9451"><code>30028f9</code></a>
fix(glob): align hmr matcher options with glob enumeration (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22306">#22306</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v8.0.11/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-05-07 22:21:17 +02:00
dependabot[bot]
8b43ee813f feat(deps): bump the minor group with 14 updates (#631)
Bumps the minor group with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [zod](https://github.com/colinhacks/zod) | `4.4.1` | `4.4.3` |
|
[@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)
| `8.59.1` | `8.59.2` |
| [@tybys/wasm-util](https://github.com/toyobayashi/wasm-util) |
`0.10.1` | `0.10.2` |
|
[@typescript-eslint/project-service](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/project-service)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/scope-manager](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/scope-manager)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/tsconfig-utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/tsconfig-utils)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/type-utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/type-utils)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/types](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/types)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-estree)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils)
| `8.59.1` | `8.59.2` |
|
[@typescript-eslint/visitor-keys](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/visitor-keys)
| `8.59.1` | `8.59.2` |
| [fast-uri](https://github.com/fastify/fast-uri) | `3.1.0` | `3.1.1` |
| [postcss](https://github.com/postcss/postcss) | `8.5.13` | `8.5.14` |

Updates `zod` from 4.4.1 to 4.4.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.3</h2>
<h2>Commits:</h2>
<ul>
<li>4c2fa95ce3f3390fbc522324e406b4e9e89b88f9 docs: use Zernio primary
wordmark for gold sponsor logo</li>
<li>2aeec83eb135e3a83756e973ef44845fc5a455d2 docs: prune lapsed gold
sponsors and rebalance logo sizing</li>
<li>7391be88ac1ee5cd02057f5ccc012a1f5df4efd0 docs: prune lapsed
silver/bronze sponsors and add active ones</li>
<li>2c703322a21b4e2b12f33f49ea8430c451a68b4f docs: normalize bronze
sponsor logos to github avatar pattern</li>
<li>9195250cab0e7950efe39c3926d6c203b4b0a170 docs: remove Mintlify from
bronze sponsors (churned)</li>
<li>b8dffe9e62f17e6571e6249d05cc5102b54d94e4 docs: remove Numeric and
Speakeasy (2+ missed monthly cycles)</li>
<li>1cab69383fcdeae2a366d5e2a2fc4d8fc765d168 fix(v4): restore catch
handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li>c2be4f819064eed62c7c350a2d399b5faecd15f8 fix(v4): generalize
optin/fallback to transform; restore preprocess on absent keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5941">#5941</a>)</li>
<li>f3c9ec03ba7a28ae72d25cc295f38674bee0f559 4.4.3</li>
<li>1fb56a5c18c27102dbc92260a4007c7732a0ccca docs: document release
procedure in AGENTS.md</li>
</ul>
<h2>v4.4.2</h2>
<h2>Commits:</h2>
<ul>
<li>0c62df0ea19fd05abdf90473e9eef7eea530fab2 Clean up docs navigation
and stale labels (<a
href="https://redirect.github.com/colinhacks/zod/issues/5901">#5901</a>)</li>
<li>20cc794895cc8604fe0c87d83a5d1c3f89fad0ac chore: add security policy
and refresh tooling deps</li>
<li>6fbe07b0177efdd1bf1c0b05160e70d7a0702337 fix(docs): heading anchor
links now include the hash so it doesnt scoll all the way up, follows
navbar logic (<a
href="https://redirect.github.com/colinhacks/zod/issues/5791">#5791</a>)</li>
<li>4bbed1b1c73eca4ce9e59b1189ed236aa6c8b5bd Tighten discriminated union
option typing</li>
<li>bbac3e567e7fccfaaf7cdc97f1ce30c295e2c908 Update PR guidance for
agents</li>
<li>cf0dc942a32805c292fff59ade20a7ace980735a Merge remote-tracking
branch 'origin/main' into fix-discriminated-union-key-constraint</li>
<li>292c894a5fd2aa42e527900b83d8d7a3009a709c docs: add Zernio gold
sponsor</li>
<li>1fc9f311c28dcf80d0bb5a36b177086cbc3d8eca docs: document codec
inversion</li>
<li>1373c85da9aeff704a9762d27bc58699618aefb7 docs: remove AI disclosure
guidance</li>
<li>e20d02b473c08e3a4e557bc610b1b5fac079b649 chore: ignore triage
notes</li>
<li>e58ea4d91b1dfe8194b73508203213cbc7e9c936 docs: test Zod Mini tab
code heights</li>
<li>905761a5d127e8d5dd2ebb3bc88c75cb0b8149ff docs: document preprocess
input type narrowing</li>
<li>bf64bac850d4dee2b7dde7e64909d5d796d32043 chore: tighten test
guidance in AGENTS.md</li>
<li>8ec4e73f4c4693b6361ad591be40fb41eb8a9f95 chore: update play.ts
scratch</li>
<li>02c2baf7d0d615872fa4528a8020603b71211702 Make z.preprocess defer
optionality to inner schema (<a
href="https://redirect.github.com/colinhacks/zod/issues/5929">#5929</a>)</li>
<li>88015df8e25c44fb5385eb3ef28935119cd5edea fix(docs): drop deprecated
<code>baseUrl</code> from tsconfig</li>
<li>c59d4474e3b4cad1b323462186cf607178ce8267 4.4.2</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1fb56a5c18"><code>1fb56a5</code></a>
docs: document release procedure in AGENTS.md</li>
<li><a
href="f3c9ec03ba"><code>f3c9ec0</code></a>
4.4.3</li>
<li><a
href="c2be4f8190"><code>c2be4f8</code></a>
fix(v4): generalize optin/fallback to transform; restore preprocess on
absent...</li>
<li><a
href="1cab69383f"><code>1cab693</code></a>
fix(v4): restore catch handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li><a
href="b8dffe9e62"><code>b8dffe9</code></a>
docs: remove Numeric and Speakeasy (2+ missed monthly cycles)</li>
<li><a
href="9195250cab"><code>9195250</code></a>
docs: remove Mintlify from bronze sponsors (churned)</li>
<li><a
href="2c703322a2"><code>2c70332</code></a>
docs: normalize bronze sponsor logos to github avatar pattern</li>
<li><a
href="7391be88ac"><code>7391be8</code></a>
docs: prune lapsed silver/bronze sponsors and add active ones</li>
<li><a
href="2aeec83eb1"><code>2aeec83</code></a>
docs: prune lapsed gold sponsors and rebalance logo sizing</li>
<li><a
href="4c2fa95ce3"><code>4c2fa95</code></a>
docs: use Zernio primary wordmark for gold sponsor logo</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v4.4.1...v4.4.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/eslint-plugin` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/eslint-plugin's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md">@​typescript-eslint/eslint-plugin's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li><a
href="ec3ef25390"><code>ec3ef25</code></a>
test: make no-useless-empty-export tests fully static (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12260">#12260</a>)</li>
<li><a
href="60d0a51387"><code>60d0a51</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in no-...</li>
<li><a
href="5c53da230a"><code>5c53da2</code></a>
fix(eslint-plugin): [no-deprecated] object destructuring values should
be tre...</li>
<li><a
href="80c28a1ada"><code>80c28a1</code></a>
fix(eslint-plugin): [no-unsafe-type-assertion] handle crash on recursive
temp...</li>
<li><a
href="b7b2670123"><code>b7b2670</code></a>
test: make no-this-alias tests fully static (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12258">#12258</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/eslint-plugin">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/parser` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/parser's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md">@​typescript-eslint/parser's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for parser to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/parser">compare
view</a></li>
</ul>
</details>
<br />

Updates `@tybys/wasm-util` from 0.10.1 to 0.10.2
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/toyobayashi/wasm-util/commits">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/project-service` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/project-service's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/project-service/CHANGELOG.md">@​typescript-eslint/project-service's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for project-service to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/project-service">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/scope-manager` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/scope-manager's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/scope-manager/CHANGELOG.md">@​typescript-eslint/scope-manager's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for scope-manager to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/scope-manager">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/tsconfig-utils` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/tsconfig-utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/tsconfig-utils/CHANGELOG.md">@​typescript-eslint/tsconfig-utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for tsconfig-utils to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/tsconfig-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/type-utils` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/type-utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/type-utils/CHANGELOG.md">@​typescript-eslint/type-utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for type-utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/type-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/types` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/types's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/types/CHANGELOG.md">@​typescript-eslint/types's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for types to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/typescript-estree` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/typescript-estree's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md">@​typescript-eslint/typescript-estree's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for typescript-estree to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/typescript-estree">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/utils` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/utils's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md">@​typescript-eslint/utils's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/visitor-keys` from 8.59.1 to 8.59.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">@​typescript-eslint/visitor-keys's
releases</a>.</em></p>
<blockquote>
<h2>v8.59.2</h2>
<h2>8.59.2 (2026-05-04)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unsafe-type-assertion] handle
crash on recursive template literal types (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12150">#12150</a>)</li>
<li><strong>eslint-plugin:</strong> [no-deprecated] object destructuring
values should be treated as declarations (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12292">#12292</a>)</li>
<li><strong>rule-tester:</strong> add TypeScript as a peer dependency
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12288">#12288</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Dariusz Czajkowski</li>
<li>Dima Barabash</li>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/visitor-keys/CHANGELOG.md">@​typescript-eslint/visitor-keys's
changelog</a>.</em></p>
<blockquote>
<h2>8.59.2 (2026-05-04)</h2>
<p>This was a version bump only for visitor-keys to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2ec35f1760"><code>2ec35f1</code></a>
chore(release): publish 8.59.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/visitor-keys">compare
view</a></li>
</ul>
</details>
<br />

Updates `fast-uri` from 3.1.0 to 3.1.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fastify/fast-uri/releases">fast-uri's
releases</a>.</em></p>
<blockquote>
<h2>v3.1.1</h2>
<h2>⚠️ Security Release</h2>
<ul>
<li>Fix for <a
href="https://github.com/fastify/fast-uri/security/advisories/GHSA-q3j6-qgpj-74h6">https://github.com/fastify/fast-uri/security/advisories/GHSA-q3j6-qgpj-74h6</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>build(deps-dev): bump tsd from 0.32.0 to 0.33.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/148">fastify/fast-uri#148</a></li>
<li>build(deps): bump actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/149">fastify/fast-uri#149</a></li>
<li>chore(.npmrc): ignore scripts by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/150">fastify/fast-uri#150</a></li>
<li>build(deps-dev): remove <code>@​fastify/pre-commit</code> by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/151">fastify/fast-uri#151</a></li>
<li>build(deps): bump actions/setup-node from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/152">fastify/fast-uri#152</a></li>
<li>ci(ci): add concurrency config by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/153">fastify/fast-uri#153</a></li>
<li>build(deps): bump actions/setup-node from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/154">fastify/fast-uri#154</a></li>
<li>build(deps): bump 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/fastify/fast-uri/pull/156">fastify/fast-uri#156</a></li>
<li>chore(license): standardise license notice by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/159">fastify/fast-uri#159</a></li>
<li>style: remove trailing whitespace by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/161">fastify/fast-uri#161</a></li>
<li>ci: remove unused github files by <a
href="https://github.com/Tony133"><code>@​Tony133</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/162">fastify/fast-uri#162</a></li>
<li>chore: update readme by <a
href="https://github.com/Tony133"><code>@​Tony133</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/164">fastify/fast-uri#164</a></li>
<li>build(deps): bump
fastify/workflows/.github/workflows/plugins-ci-package-manager.yml from
5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/165">fastify/fast-uri#165</a></li>
<li>build(deps): bump fastify/workflows/.github/workflows/plugins-ci.yml
from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/166">fastify/fast-uri#166</a></li>
<li>build(deps-dev): bump neostandard from 0.12.2 to 0.13.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/167">fastify/fast-uri#167</a></li>
<li>ci: add lock-threads workflow by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/169">fastify/fast-uri#169</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Tony133"><code>@​Tony133</code></a> made
their first contribution in <a
href="https://redirect.github.com/fastify/fast-uri/pull/162">fastify/fast-uri#162</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.1">https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="cea547c91c"><code>cea547c</code></a>
Bumped v3.1.1</li>
<li><a
href="876ce79b66"><code>876ce79</code></a>
Merge commit from fork</li>
<li><a
href="dcdf690b71"><code>dcdf690</code></a>
ci: add lock-threads workflow (<a
href="https://redirect.github.com/fastify/fast-uri/issues/169">#169</a>)</li>
<li><a
href="c860e6589b"><code>c860e65</code></a>
build(deps-dev): bump neostandard from 0.12.2 to 0.13.0 (<a
href="https://redirect.github.com/fastify/fast-uri/issues/167">#167</a>)</li>
<li><a
href="9b4c6dc82f"><code>9b4c6dc</code></a>
build(deps): bump fastify/workflows/.github/workflows/plugins-ci.yml (<a
href="https://redirect.github.com/fastify/fast-uri/issues/166">#166</a>)</li>
<li><a
href="85d09a9f7a"><code>85d09a9</code></a>
build(deps): bump
fastify/workflows/.github/workflows/plugins-ci-package-mana...</li>
<li><a
href="8063e2b554"><code>8063e2b</code></a>
chore: update readme (<a
href="https://redirect.github.com/fastify/fast-uri/issues/164">#164</a>)</li>
<li><a
href="6e85fccc3b"><code>6e85fcc</code></a>
ci: remove unused github files (<a
href="https://redirect.github.com/fastify/fast-uri/issues/162">#162</a>)</li>
<li><a
href="816711797c"><code>8167117</code></a>
style: remove trailing whitespace (<a
href="https://redirect.github.com/fastify/fast-uri/issues/161">#161</a>)</li>
<li><a
href="0f008cee64"><code>0f008ce</code></a>
chore(license): standardise license notice (<a
href="https://redirect.github.com/fastify/fast-uri/issues/159">#159</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `postcss` from 8.5.13 to 8.5.14
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.14</h2>
<ul>
<li>Fixed custom syntax regression (by <a
href="https://github.com/43081j"><code>@​43081j</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.14</h2>
<ul>
<li>Fixed custom syntax regression (by <a
href="https://github.com/43081j"><code>@​43081j</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3ec13948ae"><code>3ec1394</code></a>
Release 8.5.14 version</li>
<li><a
href="f2bb827b20"><code>f2bb827</code></a>
Update dependencies</li>
<li><a
href="d75953d608"><code>d75953d</code></a>
Merge pull request <a
href="https://redirect.github.com/postcss/postcss/issues/2084">#2084</a>
from 43081j/raw-raws-rawing</li>
<li><a
href="68bd2139b5"><code>68bd213</code></a>
fix: always call <code>raw</code> to retrieve raw values</li>
<li>See full diff in <a
href="https://github.com/postcss/postcss/compare/8.5.13...8.5.14">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-05-04 21:26:36 +02:00
Ben Brandt
dba199839a fix: Handle result origins in ACP agent (#627)
Add origin-aware raw SDK message filtering and forward result
origin metadata in usage updates.

Ignore task-notification followup results when computing the
user-turn stop reason or forwarding local slash-command output.
2026-05-04 00:07:16 +02:00
acp-release-bot[bot]
253ddeb6d4 chore(main): release 0.32.0 (#615)
🤖 I have created a release *beep* *boop*
---


##
[0.32.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.4...v0.32.0)
(2026-05-03)


### Features

* **deps-dev:** Bump nanoid from 3.3.11 to 3.3.12
([#622](https://github.com/agentclientprotocol/claude-agent-acp/issues/622))
([c78ac62](c78ac62d05))
* **deps:** Bump the minor group with 2 updates
([#619](https://github.com/agentclientprotocol/claude-agent-acp/issues/619))
([6ccd37c](6ccd37ce94))
* **deps:** update to @anthropic-ai/claude-agent-sdk 0.2.126
([#621](https://github.com/agentclientprotocol/claude-agent-acp/issues/621))
([becc3b8](becc3b86e6))
* **deps:** Update to @anthropic-ai/claude-agent-sdk@0.2.123
([#614](https://github.com/agentclientprotocol/claude-agent-acp/issues/614))
([5b93119](5b9311938d))


### Bug Fixes

* emit a real diff when Write overwrites an existing file
([#618](https://github.com/agentclientprotocol/claude-agent-acp/issues/618))
([8d7e220](8d7e22026e))

---
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-05-04 00:02:01 +02:00
dependabot[bot]
becc3b86e6 feat(deps): update to @anthropic-ai/claude-agent-sdk 0.2.126 (#621)
Bumps the minor group with 12 updates:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.123` | `0.2.126` |
| [eslint](https://github.com/eslint/eslint) | `10.2.1` | `10.3.0` |
| [globals](https://github.com/sindresorhus/globals) | `17.5.0` |
`17.6.0` |
| @anthropic-ai/claude-agent-sdk-darwin-arm64 | `0.2.123` | `0.2.126` |
| @anthropic-ai/claude-agent-sdk-darwin-x64 | `0.2.123` | `0.2.126` |
| @anthropic-ai/claude-agent-sdk-linux-arm64 | `0.2.123` | `0.2.126` |
| @anthropic-ai/claude-agent-sdk-linux-arm64-musl | `0.2.123` |
`0.2.126` |
| @anthropic-ai/claude-agent-sdk-linux-x64 | `0.2.123` | `0.2.126` |
| @anthropic-ai/claude-agent-sdk-linux-x64-musl | `0.2.123` | `0.2.126`
|
| @anthropic-ai/claude-agent-sdk-win32-arm64 | `0.2.123` | `0.2.126` |
| @anthropic-ai/claude-agent-sdk-win32-x64 | `0.2.123` | `0.2.126` |
| [postcss](https://github.com/postcss/postcss) | `8.5.12` | `8.5.13` |

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.123 to 0.2.126
<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.126</h2>
<h2>What's changed</h2>
<ul>
<li>Added <code>origin</code> to result messages
(<code>SDKResultSuccess</code> / <code>SDKResultError</code>) — forwards
the triggering message's <code>SDKMessageOrigin</code> so consumers can
distinguish user-prompted results from <code>task-notification</code>
followups</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.126
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.126
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.126
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.126
</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.126</h2>
<ul>
<li>Added <code>origin</code> to result messages
(<code>SDKResultSuccess</code> / <code>SDKResultError</code>) — forwards
the triggering message's <code>SDKMessageOrigin</code> so consumers can
distinguish user-prompted results from <code>task-notification</code>
followups</li>
</ul>
<h2>0.2.125</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.125</li>
</ul>
<h2>0.2.124</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.124</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="36c350af3e"><code>36c350a</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.123...v0.2.126">compare
view</a></li>
</ul>
</details>
<br />

Updates `eslint` from 10.2.1 to 10.3.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.3.0</h2>
<h2>Features</h2>
<ul>
<li><a
href="379571a975"><code>379571a</code></a>
feat: add suggestions for no-unused-private-class-members (<a
href="https://redirect.github.com/eslint/eslint/issues/20773">#20773</a>)
(sethamus)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li><a
href="b6ae5cf07b"><code>b6ae5cf</code></a>
fix: handle unavailable require cache (<a
href="https://redirect.github.com/eslint/eslint/issues/20812">#20812</a>)
(Simon Podlipsky)</li>
<li><a
href="6fb3685bcb"><code>6fb3685</code></a>
fix: rule suggestions cause continuation in class body (<a
href="https://redirect.github.com/eslint/eslint/issues/20787">#20787</a>)
(Milos Djermanovic)</li>
</ul>
<h2>Documentation</h2>
<ul>
<li><a
href="32cc7ab4ec"><code>32cc7ab</code></a>
docs: fix typos in docs and comments (<a
href="https://redirect.github.com/eslint/eslint/issues/20809">#20809</a>)
(Tanuj Kanti)</li>
<li><a
href="7f479376a2"><code>7f47937</code></a>
docs: Update README (GitHub Actions Bot)</li>
</ul>
<h2>Chores</h2>
<ul>
<li><a
href="d32235ec19"><code>d32235e</code></a>
ci: use pnpm in <code>eslint-flat-config-utils</code> type integration
test (<a
href="https://redirect.github.com/eslint/eslint/issues/20826">#20826</a>)
(Francesco Trotta)</li>
<li><a
href="3ffb14ea51"><code>3ffb14e</code></a>
chore: clean up typos in comments and JSDoc (<a
href="https://redirect.github.com/eslint/eslint/issues/20821">#20821</a>)
(Pixel998)</li>
<li><a
href="22eb58a21c"><code>22eb58a</code></a>
chore: add missing continue-on-error to ecosystem-tests.yml (<a
href="https://redirect.github.com/eslint/eslint/issues/20818">#20818</a>)
(Josh Goldberg ✨)</li>
<li><a
href="88bf0024cb"><code>88bf002</code></a>
ci: bump pnpm/action-setup from 6.0.1 to 6.0.3 (<a
href="https://redirect.github.com/eslint/eslint/issues/20815">#20815</a>)
(dependabot[bot])</li>
<li><a
href="97c8c330be"><code>97c8c33</code></a>
chore: update ilshidur/action-discord action to v0.4.0 (<a
href="https://redirect.github.com/eslint/eslint/issues/20811">#20811</a>)
(renovate[bot])</li>
<li><a
href="2f58136dd4"><code>2f58136</code></a>
chore: pin peter-evans/create-pull-request action to 5f6978f (<a
href="https://redirect.github.com/eslint/eslint/issues/20810">#20810</a>)
(renovate[bot])</li>
<li><a
href="77add7f1bc"><code>77add7f</code></a>
chore: add initial ecosystem plugin tests workflow (<a
href="https://redirect.github.com/eslint/eslint/issues/19643">#19643</a>)
(Josh Goldberg ✨)</li>
<li><a
href="4023b55490"><code>4023b55</code></a>
test: Add unit tests for SuppressionsService.prune() (<a
href="https://redirect.github.com/eslint/eslint/issues/20797">#20797</a>)
(kuldeep kumar)</li>
<li><a
href="54080dad4f"><code>54080da</code></a>
test: add unit tests for ForkContext (<a
href="https://redirect.github.com/eslint/eslint/issues/20778">#20778</a>)
(kuldeep kumar)</li>
<li><a
href="f0e2bcc4bf"><code>f0e2bcc</code></a>
test: add unit tests for SuppressionsService.suppress() method (<a
href="https://redirect.github.com/eslint/eslint/issues/20765">#20765</a>)
(kuldeep kumar)</li>
<li><a
href="a7f0b94743"><code>a7f0b94</code></a>
chore: update dependency prettier to v3.8.3 (<a
href="https://redirect.github.com/eslint/eslint/issues/20782">#20782</a>)
(renovate[bot])</li>
<li><a
href="7bf93d9e79"><code>7bf93d9</code></a>
chore: update TypeScript to v6 (<a
href="https://redirect.github.com/eslint/eslint/issues/20677">#20677</a>)
(sethamus)</li>
<li><a
href="b42dd72e76"><code>b42dd72</code></a>
ci: bump pnpm/action-setup from 6.0.0 to 6.0.1 (<a
href="https://redirect.github.com/eslint/eslint/issues/20781">#20781</a>)
(dependabot[bot])</li>
<li><a
href="2b252be80f"><code>2b252be</code></a>
test: add unit tests for IdGenerator (<a
href="https://redirect.github.com/eslint/eslint/issues/20775">#20775</a>)
(kuldeep kumar)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="78892043a3"><code>7889204</code></a>
10.3.0</li>
<li><a
href="5b69b4fce4"><code>5b69b4f</code></a>
Build: changelog update for 10.3.0</li>
<li><a
href="d32235ec19"><code>d32235e</code></a>
ci: use pnpm in <code>eslint-flat-config-utils</code> type integration
test (<a
href="https://redirect.github.com/eslint/eslint/issues/20826">#20826</a>)</li>
<li><a
href="b6ae5cf07b"><code>b6ae5cf</code></a>
fix: handle unavailable require cache (<a
href="https://redirect.github.com/eslint/eslint/issues/20812">#20812</a>)</li>
<li><a
href="3ffb14ea51"><code>3ffb14e</code></a>
chore: clean up typos in comments and JSDoc (<a
href="https://redirect.github.com/eslint/eslint/issues/20821">#20821</a>)</li>
<li><a
href="6fb3685bcb"><code>6fb3685</code></a>
fix: rule suggestions cause continuation in class body (<a
href="https://redirect.github.com/eslint/eslint/issues/20787">#20787</a>)</li>
<li><a
href="22eb58a21c"><code>22eb58a</code></a>
chore: add missing continue-on-error to ecosystem-tests.yml (<a
href="https://redirect.github.com/eslint/eslint/issues/20818">#20818</a>)</li>
<li><a
href="88bf0024cb"><code>88bf002</code></a>
ci: bump pnpm/action-setup from 6.0.1 to 6.0.3 (<a
href="https://redirect.github.com/eslint/eslint/issues/20815">#20815</a>)</li>
<li><a
href="379571a975"><code>379571a</code></a>
feat: add suggestions for no-unused-private-class-members (<a
href="https://redirect.github.com/eslint/eslint/issues/20773">#20773</a>)</li>
<li><a
href="97c8c330be"><code>97c8c33</code></a>
chore: update ilshidur/action-discord action to v0.4.0 (<a
href="https://redirect.github.com/eslint/eslint/issues/20811">#20811</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/eslint/compare/v10.2.1...v10.3.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `globals` from 17.5.0 to 17.6.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sindresorhus/globals/releases">globals's
releases</a>.</em></p>
<blockquote>
<h2>v17.6.0</h2>
<ul>
<li>Update globals (2026-05-01) (<a
href="https://redirect.github.com/sindresorhus/globals/issues/343">#343</a>)
00a4dd9</li>
</ul>
<hr />
<p><a
href="https://github.com/sindresorhus/globals/compare/v17.5.0...v17.6.0">https://github.com/sindresorhus/globals/compare/v17.5.0...v17.6.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6b15870f1c"><code>6b15870</code></a>
17.6.0</li>
<li><a
href="00a4dd9821"><code>00a4dd9</code></a>
Update globals (2026-05-01) (<a
href="https://redirect.github.com/sindresorhus/globals/issues/343">#343</a>)</li>
<li>See full diff in <a
href="https://github.com/sindresorhus/globals/compare/v17.5.0...v17.6.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.2.123
to 0.2.126

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.2.123 to
0.2.126

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.2.123 to
0.2.126

Updates `postcss` from 8.5.12 to 8.5.13
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.13</h2>
<ul>
<li>Fixed <code>postcss-scss</code> commend regression.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.13</h2>
<ul>
<li>Fixed <code>postcss-scss</code> commend regression.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="af58cf1b7a"><code>af58cf1</code></a>
Release 8.5.13 version</li>
<li><a
href="f227dbd0e9"><code>f227dbd</code></a>
Temporary ignore pnpm 11 config</li>
<li><a
href="d3abd40d72"><code>d3abd40</code></a>
Update dependencies</li>
<li><a
href="dd06c3e113"><code>dd06c3e</code></a>
Revert stringifier changes because of the conflict with
postcss-scss</li>
<li><a
href="ae889c815f"><code>ae889c8</code></a>
Try to fix CI</li>
<li><a
href="e0093e49bc"><code>e0093e4</code></a>
Move to pnpm 11</li>
<li>See full diff in <a
href="https://github.com/postcss/postcss/compare/8.5.12...8.5.13">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-05-03 23:55:27 +02:00
Ben Brandt
1f4d6c2900 test: Fix noisy tests (#626) 2026-05-03 21:52:06 +00:00
davethedev3
8d7e22026e fix: emit a real diff when Write overwrites an existing file (#618)
## What's broken

The PostToolUse hook fan-out (`src/acp-agent.ts`) only invokes
`toolUpdateFromEditToolResponse` for tools named `Edit`. Any `Write`
that overwrites an existing file (`FileWriteOutput.type === "update"`)
keeps the optimistic content built at tool-use time by
`toolInfoFromToolUse` — `oldText: null, newText: input.content` —
permanently. The user sees a "creation" diff regardless of whether the
file already existed, so overwrites visually look indistinguishable from
brand-new files.

This affects every Write that touches an existing file, which Claude
does routinely (rewriting configs, replacing small files, etc.).

## Fix

The SDK's `FileWriteOutput`
(`@anthropic-ai/claude-agent-sdk/sdk-tools.d.ts`) ships the same
hunk-shaped `structuredPatch` for `Write` that we already render for
`Edit`. Extending the dispatch to cover both tools replays the hook's
payload through `toolUpdateFromEditToolResponse` so update mode shows
the actual diff.

Create mode is unchanged in practice because the structuredPatch hunk's
lines are all additions, which collapse to the same `oldText: null,
newText: <content>` shape the optimistic path produced.

## Tests

Two regression tests added in `src/tests/tools.test.ts` under a new
`describe("post-tool-use hook sends diff content for Write tool")`:

- `Write` with `type: "update"` asserts the corrected diff (real
`oldText` / `newText` derived from `structuredPatch`)
- `Write` with `type: "create"` asserts the existing optimistic-style
diff is preserved

All existing tests pass. Total: 240 → 242.

## Validation

- `npm run check` ✅
- `npm run build` ✅
- `npm run test:run` ✅ (242 passed, 13 integration skipped)

---------

Co-authored-by: dave <dave@mint.lan>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-05-03 23:44:47 +02:00
dependabot[bot]
c78ac62d05 feat(deps-dev): Bump nanoid from 3.3.11 to 3.3.12 (#622)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.11 to 3.3.12.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ai/nanoid/releases">nanoid's
releases</a>.</em></p>
<blockquote>
<h2>3.3.12</h2>
<ul>
<li>Fixed breaking Nano ID by requesting big ID.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ai/nanoid/blob/main/CHANGELOG.md">nanoid's
changelog</a>.</em></p>
<blockquote>
<h2>3.3.12</h2>
<ul>
<li>Fixed breaking Nano ID by requesting big ID.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="aa9c399f69"><code>aa9c399</code></a>
Release 3.3.12 version</li>
<li><a
href="b0036ed60d"><code>b0036ed</code></a>
Backport fix to CommonJS version too</li>
<li><a
href="08a19a4c82"><code>08a19a4</code></a>
Update test</li>
<li><a
href="821dfed7b5"><code>821dfed</code></a>
Backport pool breaking fix</li>
<li><a
href="609646c644"><code>609646c</code></a>
Fix CI</li>
<li>See full diff in <a
href="https://github.com/ai/nanoid/compare/3.3.11...3.3.12">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nanoid&package-manager=npm_and_yarn&previous-version=3.3.11&new-version=3.3.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)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-01 19:44:59 +02:00
dependabot[bot]
6ccd37ce94 feat(deps): Bump the minor group with 2 updates (#619)
Bumps the minor group with 2 updates:
[zod](https://github.com/colinhacks/zod) and
[hono](https://github.com/honojs/hono).

Updates `zod` from 4.3.6 to 4.4.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.1</h2>
<h2>Commits:</h2>
<ul>
<li>481f7be4238c83ed58183f921b2646f340a91c6a ci: gate release publishing
on full test workflow</li>
<li>95ccab423aec720b2523c3a64cdc7e3204537cc7 test(v3): restore optional
undefined expectations</li>
<li>cede2c63739a5823d6aa5093d291e9a111da943d fix(v4): reject tuple holes
before required defaults (<a
href="https://redirect.github.com/colinhacks/zod/issues/5900">#5900</a>)</li>
<li>edd0bf0f5ada4a8dc581c259407d7bbad0a71ea7 release: 4.4.1</li>
<li>180d83d1dbe6a59260710cc8637a3dea2281ee56 docs: remove Jazz featured
sponsor</li>
</ul>
<h2>v4.4.0</h2>
<h2>4.4.0</h2>
<p>This is a minor release with a wide set of correctness and soundness
fixes. Some fixes intentionally make Zod stricter, so code that depended
on previously accepted invalid or ambiguous inputs may need small
updates.</p>
<h2>Potentially breaking bug fixes</h2>
<h3>Tuple defaults now materialize output values correctly</h3>
<p>Fixed in <a
href="https://redirect.github.com/colinhacks/zod/pull/5661">#5661</a>.
Tuple parsing now more accurately reflects defaults, optional tails,
explicit <code>undefined</code>, and under-filled inputs. The headline
behavior is that defaults in tuple positions now properly appear in
parsed output.</p>
<pre lang="ts"><code>const schema = z.tuple([
  z.string(),
  z.string().default(&quot;fallback&quot;),
]);
<p>schema.parse([&quot;a&quot;]);
// [&quot;a&quot;, &quot;fallback&quot;]
</code></pre></p>
<p>Trailing optional elements that are absent still stay absent; they
are not filled with <code>undefined</code>.</p>
<pre lang="ts"><code>const schema = z.tuple([
  z.string(),
  z.string().optional(),
]);
<p>schema.parse([&quot;a&quot;]);
// [&quot;a&quot;]
</code></pre></p>
<p>But explicit <code>undefined</code> values supplied by the caller are
preserved.</p>
<pre lang="ts"><code>schema.parse([&quot;a&quot;, undefined]);
// [&quot;a&quot;, undefined]
</code></pre>
<p>When optional elements appear before later defaults, the parsed tuple
is now dense so array operations behave predictably.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="180d83d1db"><code>180d83d</code></a>
docs: remove Jazz featured sponsor</li>
<li><a
href="edd0bf0f5a"><code>edd0bf0</code></a>
release: 4.4.1</li>
<li><a
href="cede2c6373"><code>cede2c6</code></a>
fix(v4): reject tuple holes before required defaults (<a
href="https://redirect.github.com/colinhacks/zod/issues/5900">#5900</a>)</li>
<li><a
href="95ccab423a"><code>95ccab4</code></a>
test(v3): restore optional undefined expectations</li>
<li><a
href="481f7be423"><code>481f7be</code></a>
ci: gate release publishing on full test workflow</li>
<li><a
href="d05f026e9e"><code>d05f026</code></a>
release: 4.4.0</li>
<li><a
href="f778e02a81"><code>f778e02</code></a>
build: bump zshy for JSR wildcard exports</li>
<li><a
href="6db607be3c"><code>6db607b</code></a>
fix(release): keep JSR manifest publishable</li>
<li><a
href="ad0b82713e"><code>ad0b827</code></a>
ci: update release workflow for trusted publishing</li>
<li><a
href="b6066b3e47"><code>b6066b3</code></a>
fix(v4): align object and tuple optionality handling (<a
href="https://redirect.github.com/colinhacks/zod/issues/5661">#5661</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v4.3.6...v4.4.1">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />

Updates `hono` from 4.12.15 to 4.12.16
<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.16</h2>
<h2>Security fixes</h2>
<p>This release includes fixes for the following security issues:</p>
<h3>Unvalidated JSX Tag Names in hono/jsx May Allow HTML Injection</h3>
<p>Affects: hono/jsx. Fixes missing validation of JSX tag names when
using <code>jsx()</code> or <code>createElement()</code>, which could
allow HTML injection if untrusted input is used as the tag name.
GHSA-69xw-7hcm-h432</p>
<h3>bodyLimit() can be bypassed for chunked / unknown-length
requests</h3>
<p>Affects: Body Limit Middleware. Fixes late enforcement for request
bodies without a reliable Content-Length (e.g. chunked requests), where
oversized requests could reach handlers and return successful responses
before being rejected. GHSA-9vqf-7f2p-gf9v</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="90d4182aab"><code>90d4182</code></a>
4.12.16</li>
<li><a
href="db05b96d7a"><code>db05b96</code></a>
Merge commit from fork</li>
<li><a
href="614b834551"><code>614b834</code></a>
Merge commit from fork</li>
<li><a
href="027e3dfca9"><code>027e3df</code></a>
fix(method-override): handle Content-Type with charset parameter (<a
href="https://redirect.github.com/honojs/hono/issues/4894">#4894</a>)</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.12.15...v4.12.16">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-05-01 02:44:51 +02:00
dependabot[bot]
5b9311938d feat(deps): Update to @anthropic-ai/claude-agent-sdk@0.2.123 (#614)
Bumps the minor group with 11 updates:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.121` | `0.2.123` |
|
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
| `0.89.0` | `0.91.1` |
| @anthropic-ai/claude-agent-sdk-darwin-arm64 | `0.2.121` | `0.2.123` |
| @anthropic-ai/claude-agent-sdk-darwin-x64 | `0.2.121` | `0.2.123` |
| @anthropic-ai/claude-agent-sdk-linux-arm64 | `0.2.121` | `0.2.123` |
| @anthropic-ai/claude-agent-sdk-linux-arm64-musl | `0.2.121` |
`0.2.123` |
| @anthropic-ai/claude-agent-sdk-linux-x64 | `0.2.121` | `0.2.123` |
| @anthropic-ai/claude-agent-sdk-linux-x64-musl | `0.2.121` | `0.2.123`
|
| @anthropic-ai/claude-agent-sdk-win32-arm64 | `0.2.121` | `0.2.123` |
| @anthropic-ai/claude-agent-sdk-win32-x64 | `0.2.121` | `0.2.123` |
| [tinyexec](https://github.com/tinylibs/tinyexec) | `1.1.1` | `1.1.2` |

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.121 to 0.2.123
<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.123</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.123</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.123
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.123
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.123
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.123
</code></pre>
<h2>v0.2.122</h2>
<h2>What's changed</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.122</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.122
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.122
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.122
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.122
</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.123</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.123</li>
</ul>
<h2>0.2.122</h2>
<ul>
<li>Updated to parity with Claude Code v2.1.122</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="38cd292318"><code>38cd292</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="5f07f15d5d"><code>5f07f15</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.121...v0.2.123">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/sdk` from 0.89.0 to 0.91.1
<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.91.1</h2>
<h2>0.91.1 (2026-04-24)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.91.0...sdk-v0.91.1">sdk-v0.91.0...sdk-v0.91.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> use restrictive file mode for memory files
(<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/901">#901</a>)
(<a
href="6db3b7e221">6db3b7e</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>formatter:</strong> run prettier and eslint separately (<a
href="974d22fcf6">974d22f</a>)</li>
</ul>
<h2>sdk: v0.91.0</h2>
<h2>0.91.0 (2026-04-23)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.90.0...sdk-v0.91.0">sdk-v0.90.0...sdk-v0.91.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> CMA Memory public beta (<a
href="ddf732f5f3">ddf732f</a>)</li>
<li><strong>bedrock:</strong> use auth header for mantle client (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/866">#866</a>)
(<a
href="aec801afc7">aec801a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> fix errors in api spec (<a
href="ae10768485">ae10768</a>)</li>
<li><strong>api:</strong> restore missing features (<a
href="1a5b47b689">1a5b47b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> more robust bootstrap script (<a
href="7716e19f7f">7716e19</a>)</li>
<li><strong>tests:</strong> bump steady to v0.22.1 (<a
href="219a971743">219a971</a>)</li>
</ul>
<h2>sdk: v0.90.0</h2>
<h2>0.90.0 (2026-04-16)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.90.0">sdk-v0.89.0...sdk-v0.90.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add claude-opus-4-7, token budgets and
user_profiles (<a
href="b26134bb17">b26134b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li>actually delete release-doctor.yml (<a
href="0fe984d1f6">0fe984d</a>)</li>
<li><strong>ci:</strong> remove release-doctor workflow (<a
href="08e58bd0bb">08e58bd</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.91.1 (2026-04-24)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.91.0...sdk-v0.91.1">sdk-v0.91.0...sdk-v0.91.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> use restrictive file mode for memory files
(<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/901">#901</a>)
(<a
href="6db3b7e221">6db3b7e</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>formatter:</strong> run prettier and eslint separately (<a
href="974d22fcf6">974d22f</a>)</li>
</ul>
<h2>0.91.0 (2026-04-23)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.90.0...sdk-v0.91.0">sdk-v0.90.0...sdk-v0.91.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> CMA Memory public beta (<a
href="ddf732f5f3">ddf732f</a>)</li>
<li><strong>bedrock:</strong> use auth header for mantle client (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/866">#866</a>)
(<a
href="aec801afc7">aec801a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> fix errors in api spec (<a
href="ae10768485">ae10768</a>)</li>
<li><strong>api:</strong> restore missing features (<a
href="1a5b47b689">1a5b47b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> more robust bootstrap script (<a
href="7716e19f7f">7716e19</a>)</li>
<li><strong>tests:</strong> bump steady to v0.22.1 (<a
href="219a971743">219a971</a>)</li>
</ul>
<h2>0.90.0 (2026-04-16)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.90.0">sdk-v0.89.0...sdk-v0.90.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add claude-opus-4-7, token budgets and
user_profiles (<a
href="b26134bb17">b26134b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li>actually delete release-doctor.yml (<a
href="0fe984d1f6">0fe984d</a>)</li>
<li><strong>ci:</strong> remove release-doctor workflow (<a
href="08e58bd0bb">08e58bd</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="74ac150346"><code>74ac150</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1014">#1014</a>)</li>
<li><a
href="22cb810364"><code>22cb810</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1008">#1008</a>)</li>
<li><a
href="93ac7c7e05"><code>93ac7c7</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1003">#1003</a>)</li>
<li>See full diff in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.91.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.2.121
to 0.2.123

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.2.121 to
0.2.123

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.2.121 to
0.2.123

Updates `tinyexec` from 1.1.1 to 1.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tinylibs/tinyexec/releases">tinyexec's
releases</a>.</em></p>
<blockquote>
<h2>1.1.2</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: accept readonly string[] for args parameters by <a
href="https://github.com/tatzyr"><code>@​tatzyr</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/112">tinylibs/tinyexec#112</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 7
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/113">tinylibs/tinyexec#113</a></li>
<li>fix: Fix typo in <code>README</code> by <a
href="https://github.com/porada"><code>@​porada</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/114">tinylibs/tinyexec#114</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 5
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/116">tinylibs/tinyexec#116</a></li>
<li>chore(deps): bump actions/setup-node from 6.3.0 to 6.4.0 in the
github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/115">tinylibs/tinyexec#115</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/117">tinylibs/tinyexec#117</a></li>
<li>fix: remove normalisation of commands by <a
href="https://github.com/43081j"><code>@​43081j</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/118">tinylibs/tinyexec#118</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/tatzyr"><code>@​tatzyr</code></a> made
their first contribution in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/112">tinylibs/tinyexec#112</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/tinylibs/tinyexec/compare/1.1.1...1.1.2">https://github.com/tinylibs/tinyexec/compare/1.1.1...1.1.2</a></p>
<h2>1.1.2-next.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: accept readonly string[] for args parameters by <a
href="https://github.com/tatzyr"><code>@​tatzyr</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/112">tinylibs/tinyexec#112</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 7
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/113">tinylibs/tinyexec#113</a></li>
<li>fix: Fix typo in <code>README</code> by <a
href="https://github.com/porada"><code>@​porada</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/114">tinylibs/tinyexec#114</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 5
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/116">tinylibs/tinyexec#116</a></li>
<li>chore(deps): bump actions/setup-node from 6.3.0 to 6.4.0 in the
github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/115">tinylibs/tinyexec#115</a></li>
<li>chore(deps-dev): bump the development-dependencies group with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/117">tinylibs/tinyexec#117</a></li>
<li>fix: remove normalisation of commands by <a
href="https://github.com/43081j"><code>@​43081j</code></a> in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/118">tinylibs/tinyexec#118</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/tatzyr"><code>@​tatzyr</code></a> made
their first contribution in <a
href="https://redirect.github.com/tinylibs/tinyexec/pull/112">tinylibs/tinyexec#112</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/tinylibs/tinyexec/compare/1.1.1...1.1.2-next.0">https://github.com/tinylibs/tinyexec/compare/1.1.1...1.1.2-next.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="66f20383d8"><code>66f2038</code></a>
fix: remove normalisation of commands (<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/118">#118</a>)</li>
<li><a
href="7a412e2c4b"><code>7a412e2</code></a>
chore(deps-dev): bump the development-dependencies group with 4 updates
(<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/117">#117</a>)</li>
<li><a
href="bb8e95baeb"><code>bb8e95b</code></a>
chore(deps): bump actions/setup-node in the github-actions group (<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/115">#115</a>)</li>
<li><a
href="2eb8aa1089"><code>2eb8aa1</code></a>
chore(deps-dev): bump the development-dependencies group with 5 updates
(<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/116">#116</a>)</li>
<li><a
href="64d77c1c95"><code>64d77c1</code></a>
chore: fix typo in readme (<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/114">#114</a>)</li>
<li><a
href="d5443a19f3"><code>d5443a1</code></a>
chore(deps-dev): bump the development-dependencies group with 7 updates
(<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/113">#113</a>)</li>
<li><a
href="76f9e38477"><code>76f9e38</code></a>
feat: accept readonly string[] for args parameters (<a
href="https://redirect.github.com/tinylibs/tinyexec/issues/112">#112</a>)</li>
<li>See full diff in <a
href="https://github.com/tinylibs/tinyexec/compare/1.1.1...1.1.2">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>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 18:22:42 +02:00
acp-release-bot[bot]
9957b54882 chore(main): release 0.31.4 (#611)
🤖 I have created a release *beep* *boop*
---


##
[0.31.4](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.3...v0.31.4)
(2026-04-28)


### Bug Fixes

* gate auto mode on model support
([#604](https://github.com/agentclientprotocol/claude-agent-acp/issues/604))
([ec47d34](ec47d3446f))

---
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-28 18:10:28 +02:00
davethedev3
ec47d3446f fix: gate auto mode on model support (#604)
## Summary

Closes #594

Only advertise and accept `auto` permission mode when the active SDK
model reports `supportsAutoMode: true`.

This fixes the Haiku path where clients could select `auto`, only for
the SDK to later reject it with `auto mode unavailable for this model`.

Changes included:

- build available permission modes from the active model's `ModelInfo`
- omit `auto` from `availableModes` when `supportsAutoMode` is absent or
false
- clamp `permissions.defaultMode: "auto"` to `default` when the resolved
model cannot use auto mode
- recompute and clamp the current mode on model switch
- reject direct `setSessionMode("auto")` when `auto` is not available
- filter `ExitPlanMode` choices so unavailable modes are not offered or
accepted
- add regression coverage for session creation, model switching, direct
mode setting, and `ExitPlanMode`

## Verification

- `npm run lint`
- `npx prettier --check src/acp-agent.ts
src/tests/acp-agent-settings.test.ts src/tests/acp-agent.test.ts
src/tests/session-config-options.test.ts`
- `npm run build`
- `npm run test:run`
- Manual ACP subprocess smoke test with `ANTHROPIC_MODEL=haiku`
  - `auto` was not advertised
  - `setSessionMode("auto")` was rejected before reaching the SDK

---------

Co-authored-by: dave <dave@mint.lan>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-28 16:08:46 +00:00
acp-release-bot[bot]
546040ffe7 chore(main): release 0.31.3 (#610)
🤖 I have created a release *beep* *boop*
---


##
[0.31.3](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.2...v0.31.3)
(2026-04-28)


### Bug Fixes

* Rename effort config category to thought_level
([#609](https://github.com/agentclientprotocol/claude-agent-acp/issues/609))
([76b4e96](76b4e96508))

---
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-28 16:59:32 +02:00
dependabot[bot]
a52ab4ab64 chore(deps): bump the minor group across 1 directory with 25 updates (#608)
Bumps the minor group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@agentclientprotocol/sdk](https://github.com/agentclientprotocol/typescript-sdk)
| `0.20.0` | `0.21.0` |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.2.119` | `0.2.121` |
|
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
| `0.89.0` | `0.91.1` |
|
[@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)
| `8.59.0` | `8.59.1` |
|
[@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)
| `8.59.0` | `8.59.1` |
| [es-module-lexer](https://github.com/guybedford/es-module-lexer) |
`2.0.0` | `2.1.0` |
|
[express-rate-limit](https://github.com/express-rate-limit/express-rate-limit)
| `8.4.0` | `8.4.1` |
| [jose](https://github.com/panva/jose) | `6.2.2` | `6.2.3` |
| [postcss](https://github.com/postcss/postcss) | `8.5.10` | `8.5.12` |


Updates `@agentclientprotocol/sdk` from 0.20.0 to 0.21.0
<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.21.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.20.0...v0.21.0">0.21.0</a>
(2026-04-28)</h2>
<h3>Features</h3>
<ul>
<li><strong>unstable:</strong> Add <code>providers/*</code> support (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/138">#138</a>)
(<a
href="e234c213d3">e234c21</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.20.0...v0.21.0">0.21.0</a>
(2026-04-28)</h2>
<h3>Features</h3>
<ul>
<li><strong>unstable:</strong> Add <code>providers/*</code> support (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/138">#138</a>)
(<a
href="e234c213d3">e234c21</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="74372b59f8"><code>74372b5</code></a>
chore(main): release 0.21.0 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/139">#139</a>)</li>
<li><a
href="e234c213d3"><code>e234c21</code></a>
feat(unstable): Add <code>providers/*</code> support (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/138">#138</a>)</li>
<li><a
href="b0e1d046a5"><code>b0e1d04</code></a>
chore(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/134">#134</a>)</li>
<li><a
href="c6ee38997c"><code>c6ee389</code></a>
chore(deps): bump googleapis/release-please-action from 4.4.1 to 5.0.0
(<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/135">#135</a>)</li>
<li><a
href="bd0b486fce"><code>bd0b486</code></a>
chore(deps): bump the minor group with 43 updates (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/136">#136</a>)</li>
<li><a
href="3becf2ee80"><code>3becf2e</code></a>
chore(deps-dev): bump ajv from 6.14.0 to 6.15.0 (<a
href="https://redirect.github.com/agentclientprotocol/typescript-sdk/issues/137">#137</a>)</li>
<li>See full diff in <a
href="https://github.com/agentclientprotocol/typescript-sdk/compare/v0.20.0...v0.21.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk` from 0.2.119 to 0.2.121
<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.121</h2>
<h2>What's changed</h2>
<ul>
<li>Added <code>updatedToolOutput</code> to
<code>PostToolUseHookSpecificOutput</code> for replacing tool output on
all tools. <code>updatedMCPToolOutput</code> is deprecated.</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.2.121
# or
yarn add @anthropic-ai/claude-agent-sdk@0.2.121
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.2.121
# or
bun add @anthropic-ai/claude-agent-sdk@0.2.121
</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.121</h2>
<ul>
<li>Added <code>updatedToolOutput</code> to
<code>PostToolUseHookSpecificOutput</code> for replacing tool output on
all tools. <code>updatedMCPToolOutput</code> is deprecated.</li>
</ul>
<h2>0.2.120</h2>
<ul>
<li>Added <code>skills</code> option (<code>string[] | 'all'</code>) to
control which Skills are loaded into the main session, matching the
Python SDK</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="49b6b0e827"><code>49b6b0e</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="2b1ffcc321"><code>2b1ffcc</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="48de067ca4"><code>48de067</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.119...v0.2.121">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/sdk` from 0.89.0 to 0.91.1
<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.91.1</h2>
<h2>0.91.1 (2026-04-24)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.91.0...sdk-v0.91.1">sdk-v0.91.0...sdk-v0.91.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> use restrictive file mode for memory files
(<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/901">#901</a>)
(<a
href="6db3b7e221">6db3b7e</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>formatter:</strong> run prettier and eslint separately (<a
href="974d22fcf6">974d22f</a>)</li>
</ul>
<h2>sdk: v0.91.0</h2>
<h2>0.91.0 (2026-04-23)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.90.0...sdk-v0.91.0">sdk-v0.90.0...sdk-v0.91.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> CMA Memory public beta (<a
href="ddf732f5f3">ddf732f</a>)</li>
<li><strong>bedrock:</strong> use auth header for mantle client (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/866">#866</a>)
(<a
href="aec801afc7">aec801a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> fix errors in api spec (<a
href="ae10768485">ae10768</a>)</li>
<li><strong>api:</strong> restore missing features (<a
href="1a5b47b689">1a5b47b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> more robust bootstrap script (<a
href="7716e19f7f">7716e19</a>)</li>
<li><strong>tests:</strong> bump steady to v0.22.1 (<a
href="219a971743">219a971</a>)</li>
</ul>
<h2>sdk: v0.90.0</h2>
<h2>0.90.0 (2026-04-16)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.90.0">sdk-v0.89.0...sdk-v0.90.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add claude-opus-4-7, token budgets and
user_profiles (<a
href="b26134bb17">b26134b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li>actually delete release-doctor.yml (<a
href="0fe984d1f6">0fe984d</a>)</li>
<li><strong>ci:</strong> remove release-doctor workflow (<a
href="08e58bd0bb">08e58bd</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.91.1 (2026-04-24)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.91.0...sdk-v0.91.1">sdk-v0.91.0...sdk-v0.91.1</a></p>
<h3>Bug Fixes</h3>
<ul>
<li><strong>memory:</strong> use restrictive file mode for memory files
(<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/901">#901</a>)
(<a
href="6db3b7e221">6db3b7e</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>formatter:</strong> run prettier and eslint separately (<a
href="974d22fcf6">974d22f</a>)</li>
</ul>
<h2>0.91.0 (2026-04-23)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.90.0...sdk-v0.91.0">sdk-v0.90.0...sdk-v0.91.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> CMA Memory public beta (<a
href="ddf732f5f3">ddf732f</a>)</li>
<li><strong>bedrock:</strong> use auth header for mantle client (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/866">#866</a>)
(<a
href="aec801afc7">aec801a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> fix errors in api spec (<a
href="ae10768485">ae10768</a>)</li>
<li><strong>api:</strong> restore missing features (<a
href="1a5b47b689">1a5b47b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> more robust bootstrap script (<a
href="7716e19f7f">7716e19</a>)</li>
<li><strong>tests:</strong> bump steady to v0.22.1 (<a
href="219a971743">219a971</a>)</li>
</ul>
<h2>0.90.0 (2026-04-16)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.90.0">sdk-v0.89.0...sdk-v0.90.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add claude-opus-4-7, token budgets and
user_profiles (<a
href="b26134bb17">b26134b</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li>actually delete release-doctor.yml (<a
href="0fe984d1f6">0fe984d</a>)</li>
<li><strong>ci:</strong> remove release-doctor workflow (<a
href="08e58bd0bb">08e58bd</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="74ac150346"><code>74ac150</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1014">#1014</a>)</li>
<li><a
href="22cb810364"><code>22cb810</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1008">#1008</a>)</li>
<li><a
href="93ac7c7e05"><code>93ac7c7</code></a>
chore: release main (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1003">#1003</a>)</li>
<li>See full diff in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.89.0...sdk-v0.91.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/eslint-plugin` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/eslint-plugin</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md"><code>@​typescript-eslint/eslint-plugin</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li><a
href="3cef124716"><code>3cef124</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in dot...</li>
<li><a
href="27c507b6e5"><code>27c507b</code></a>
test: make sort-type-constituents tests fully static (<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12262">#12262</a>)</li>
<li><a
href="a03b31d422"><code>a03b31d</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in no-...</li>
<li><a
href="a7099a7895"><code>a7099a7</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in no-...</li>
<li><a
href="bfbd4a5433"><code>bfbd4a5</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in no-...</li>
<li><a
href="b49d4b15cd"><code>b49d4b1</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in no-...</li>
<li><a
href="3097e72747"><code>3097e72</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in nam...</li>
<li><a
href="676191bbd7"><code>676191b</code></a>
chore(eslint-plugin): switch auto-generated test cases to hand-written
in mem...</li>
<li><a
href="e9dce8bdc6"><code>e9dce8b</code></a>
fix(eslint-plugin): [no-unnecessary-condition] treat void as nullish in
no-un...</li>
<li>Additional commits viewable in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/eslint-plugin">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/parser` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/parser</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md"><code>@​typescript-eslint/parser</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for parser to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/parser">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.2.119
to 0.2.121

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.2.119 to
0.2.121

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.2.119 to
0.2.121

Updates `@typescript-eslint/project-service` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/project-service</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/project-service/CHANGELOG.md"><code>@​typescript-eslint/project-service</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for project-service to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/project-service">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/scope-manager` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/scope-manager</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/scope-manager/CHANGELOG.md"><code>@​typescript-eslint/scope-manager</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for scope-manager to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/scope-manager">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/tsconfig-utils` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/tsconfig-utils</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/tsconfig-utils/CHANGELOG.md"><code>@​typescript-eslint/tsconfig-utils</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for tsconfig-utils to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/tsconfig-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/type-utils` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/type-utils</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/type-utils/CHANGELOG.md"><code>@​typescript-eslint/type-utils</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for type-utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/type-utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/types` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/types</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/types/CHANGELOG.md"><code>@​typescript-eslint/types</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for types to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/typescript-estree` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/typescript-estree</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md"><code>@​typescript-eslint/typescript-estree</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for typescript-estree to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/typescript-estree">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/utils` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/utils</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md"><code>@​typescript-eslint/utils</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for utils to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/utils">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/visitor-keys` from 8.59.0 to 8.59.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/visitor-keys</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.59.1</h2>
<h2>8.59.1 (2026-04-27)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] fix
crash &quot;TypeError: checker.getTypeArguments is not a function&quot;
(<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12246">#12246</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve index signatures in undefined unions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12257">#12257</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
preserve phantom type arguments in generic inference (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12269">#12269</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
avoid false positive in logical assignment assertions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12278">#12278</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-arguments]
handle instantiation expressions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12220">#12220</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-condition] treat
void as nullish in no-unnecessary-condition (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12241">#12241</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>anasm266 <a
href="https://github.com/anasm266"><code>@​anasm266</code></a></li>
<li>Anshika Jain <a
href="https://github.com/Anshikakalpana"><code>@​Anshikakalpana</code></a></li>
<li>Ulrich Stark</li>
<li>yugo innami <a
href="https://github.com/nami8824"><code>@​nami8824</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/visitor-keys/CHANGELOG.md"><code>@​typescript-eslint/visitor-keys</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.59.1 (2026-04-27)</h2>
<p>This was a version bump only for visitor-keys to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.1">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52457932e5"><code>5245793</code></a>
chore(release): publish 8.59.1</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/visitor-keys">compare
view</a></li>
</ul>
</details>
<br />

Updates `es-module-lexer` from 2.0.0 to 2.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/guybedford/es-module-lexer/releases">es-module-lexer's
releases</a>.</em></p>
<blockquote>
<h2>2.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Always exclude dyn import attributes from specifier range by <a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>
in <a
href="https://redirect.github.com/guybedford/es-module-lexer/pull/197">guybedford/es-module-lexer#197</a></li>
<li>fix: handle new of conflict cases by <a
href="https://github.com/guybedford"><code>@​guybedford</code></a> in <a
href="https://redirect.github.com/guybedford/es-module-lexer/pull/195">guybedford/es-module-lexer#195</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>
made their first contribution in <a
href="https://redirect.github.com/guybedford/es-module-lexer/pull/197">guybedford/es-module-lexer#197</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/guybedford/es-module-lexer/compare/2.0.0...2.1.0">https://github.com/guybedford/es-module-lexer/compare/2.0.0...2.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5fb11e1e01"><code>5fb11e1</code></a>
2.1.0</li>
<li><a
href="cc29c5bca1"><code>cc29c5b</code></a>
fix: handle new of conflict cases (<a
href="https://redirect.github.com/guybedford/es-module-lexer/issues/195">#195</a>)</li>
<li><a
href="4a351384ff"><code>4a35138</code></a>
Always exclude dyn import attributes from specifier range (<a
href="https://redirect.github.com/guybedford/es-module-lexer/issues/197">#197</a>)</li>
<li>See full diff in <a
href="https://github.com/guybedford/es-module-lexer/compare/2.0.0...2.1.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `express-rate-limit` from 8.4.0 to 8.4.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/express-rate-limit/express-rate-limit/releases">express-rate-limit's
releases</a>.</em></p>
<blockquote>
<h2>v8.4.1</h2>
<p>You can view the changelog <a
href="https://express-rate-limit.mintlify.app/reference/changelog">here</a>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="69568d4ea7"><code>69568d4</code></a>
8.4.1</li>
<li><a
href="c686acd0ba"><code>c686acd</code></a>
v8.4.1 changelog</li>
<li><a
href="ba71353abb"><code>ba71353</code></a>
test: bump timeout in flakey skipFailedRequests test (<a
href="https://redirect.github.com/express-rate-limit/express-rate-limit/issues/618">#618</a>)</li>
<li><a
href="dd4c8944d4"><code>dd4c894</code></a>
feat: allow usage of custom logger (<a
href="https://redirect.github.com/express-rate-limit/express-rate-limit/issues/616">#616</a>)</li>
<li>See full diff in <a
href="https://github.com/express-rate-limit/express-rate-limit/compare/v8.4.0...v8.4.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `jose` from 6.2.2 to 6.2.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/panva/jose/releases">jose's
releases</a>.</em></p>
<blockquote>
<h2>v6.2.3</h2>
<h3>Refactor</h3>
<ul>
<li>cleanly reject invalid PBES2 p2c (<a
href="0cdb851ca5">0cdb851</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/panva/jose/blob/main/CHANGELOG.md">jose's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/panva/jose/compare/v6.2.2...v6.2.3">6.2.3</a>
(2026-04-27)</h2>
<h3>Refactor</h3>
<ul>
<li>cleanly reject invalid PBES2 p2c (<a
href="0cdb851ca5">0cdb851</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="41ad7e9a76"><code>41ad7e9</code></a>
chore(release): 6.2.3</li>
<li><a
href="988e90f666"><code>988e90f</code></a>
chore: account for commit-and-tag-version instead of
standard-version</li>
<li><a
href="4b24656b61"><code>4b24656</code></a>
chore: update CHANGELOG.md header</li>
<li><a
href="0cdb851ca5"><code>0cdb851</code></a>
refactor: cleanly reject invalid PBES2 p2c</li>
<li><a
href="a0b261eddf"><code>a0b261e</code></a>
test: update Bun expectations</li>
<li><a
href="b39dc1af78"><code>b39dc1a</code></a>
chore: use fs.globSync</li>
<li><a
href="0675be19a6"><code>0675be1</code></a>
build: replace rollup umd build with a custom esbuild iife wrap</li>
<li><a
href="9b0332370a"><code>9b03323</code></a>
chore: bump packages</li>
<li><a
href="914b73dad2"><code>914b73d</code></a>
chore(deps-dev): bump lodash</li>
<li><a
href="9dce817d74"><code>9dce817</code></a>
chore: bump packages</li>
<li>Additional commits viewable in <a
href="https://github.com/panva/jose/compare/v6.2.2...v6.2.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `postcss` from 8.5.10 to 8.5.12
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.12</h2>
<ul>
<li>Fixed reading any file via user-generated CSS.</li>
<li>Added <code>opts.unsafeMap</code> to disable checks.</li>
</ul>
<h2>8.5.11</h2>
<ul>
<li>Fixed nested brackets parsing performance (by <a
href="https://github.com/offset"><code>@​offset</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.12</h2>
<ul>
<li>Fixed reading any file via user-generated CSS.</li>
<li>Added <code>opts.unsafeMap</code> to disable checks.</li>
</ul>
<h2>8.5.11</h2>
<ul>
<li>Fixed nested brackets parsing performance (by <a
href="https://github.com/offset"><code>@​offset</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9bc81c48f0"><code>9bc81c4</code></a>
Release 8.5.12 version</li>
<li><a
href="85c4d7dab8"><code>85c4d7d</code></a>
Another try to fix coverage</li>
<li><a
href="94484cae6d"><code>94484ca</code></a>
Try to fix coverage</li>
<li><a
href="c64b7488d2"><code>c64b748</code></a>
Load only .map source maps</li>
<li><a
href="aaec7b78b3"><code>aaec7b7</code></a>
Avoid throwing JSON parsing errors for non-JSON source maps</li>
<li><a
href="233fb264ea"><code>233fb26</code></a>
Mention original author of the solution</li>
<li><a
href="2502f75030"><code>2502f75</code></a>
Release 8.5.11 version</li>
<li><a
href="5ca1901949"><code>5ca1901</code></a>
Speed up parsing many nested brackets</li>
<li><a
href="42b5337dd7"><code>42b5337</code></a>
Update dependencies</li>
<li><a
href="7e36e153d0"><code>7e36e15</code></a>
Cache node.raws locally in Stringifier hot methods</li>
<li>Additional commits viewable in <a
href="https://github.com/postcss/postcss/compare/8.5.10...8.5.12">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>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-28 16:57:58 +02:00
Ben Brandt
76b4e96508 fix: Rename effort config category to thought_level (#609)
Uses the canonical version it should have been using.
2026-04-28 14:54:53 +00:00
acp-release-bot[bot]
32abd34bc0 chore(main): release 0.31.2 (#605)
🤖 I have created a release *beep* *boop*
---


##
[0.31.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.1...v0.31.2)
(2026-04-28)


### Bug Fixes

* tolerate invalid values in settings.json
([#601](https://github.com/agentclientprotocol/claude-agent-acp/issues/601))
([67af018](67af018d02))

---
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-28 10:21:32 +02:00
Alex Plãte
67af018d02 fix: tolerate invalid values in settings.json (#601)
A broken value in settings.json (e.g. an unknown permissions.defaultMode
or a non-string model) used to throw and prevent session creation. Match
the Claude Code SDK behavior by logging the bad value and falling back
to defaults instead, so a single typo no longer renders the agent
unusable.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-28 10:20:09 +02:00
acp-release-bot[bot]
a55f31a6b0 chore(main): release 0.31.1 (#600)
🤖 I have created a release *beep* *boop*
---


##
[0.31.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.0...v0.31.1)
(2026-04-27)


### Bug Fixes

* detect glibc and use correct binary
([#599](https://github.com/agentclientprotocol/claude-agent-acp/issues/599))
([f0801d5](f0801d50b2))

---
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-27 12:02:31 +02:00
Ben Brandt
f0801d50b2 fix: detect glibc and use correct binary (#599)
## Summary

Re-records #598 with a Conventional Commit prefix so
[release-please](https://github.com/googleapis/release-please) generates
a release PR. The actual fix was merged in 1a9d3ce but lacked the `fix:`
prefix, so release-please skipped it.

This PR is intentionally empty — once squash-merged, the resulting
commit message on `main` will start with `fix:` and trigger a patch
release.

See https://github.com/tidewave-ai/tidewave_app/issues/141.
2026-04-27 10:01:08 +00:00
Steffen Deusch
1a9d3cebcd detect glibc and use correct binary (#598)
On Linux, the current code prefers the musl binary if multiple versions
are installed, but it actually crashes on glibc systems.

Supersedes
https://github.com/agentclientprotocol/claude-agent-acp/pull/597.

Importantly, we need to pass the detected binary to
`pathToClaudeCodeExecutable`, otherwise the SDK itself selects the wrong
version.

See https://github.com/tidewave-ai/tidewave_app/issues/141.
Closes https://github.com/tidewave-ai/tidewave_app/issues/141.
2026-04-27 11:54:12 +02:00
acp-release-bot[bot]
84e05eecc5 chore(main): release 0.31.0 (#574)
🤖 I have created a release *beep* *boop*
---


##
[0.31.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.30.0...v0.31.0)
(2026-04-24)


### Features

* allow configuring models through env vars
([#586](https://github.com/agentclientprotocol/claude-agent-acp/issues/586))
([1e15f3d](1e15f3d8b0))
* Support effort levels
([#464](https://github.com/agentclientprotocol/claude-agent-acp/issues/464))
([9e1185b](9e1185bfd5))
* Update to acp sdk v0.20
([#589](https://github.com/agentclientprotocol/claude-agent-acp/issues/589))
([92adcbd](92adcbd1ac))
* Update to claude-agent-sdk 0.2.119
([#587](https://github.com/agentclientprotocol/claude-agent-acp/issues/587))
([ef1dbd1](ef1dbd1cb4))


### Bug Fixes

* Forward full systemPrompt preset options from _meta
([#591](https://github.com/agentclientprotocol/claude-agent-acp/issues/591))
([b3ddfc3](b3ddfc3b86))
* Session Replay and Permission rendering
([#593](https://github.com/agentclientprotocol/claude-agent-acp/issues/593))
([5faefab](5faefab8ab)),
closes
[#579](https://github.com/agentclientprotocol/claude-agent-acp/issues/579)

---
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-24 17:14:31 +02:00
Ben Brandt
5faefab8ab fix: Session Replay and Permission rendering (#593)
Cleans up the replay of loaded sessions.
Also makes always allow permissions clearer of what will be applied.

Closes #579
2026-04-24 15:13:02 +00:00
Ben Brandt
b3ddfc3b86 fix: Forward full systemPrompt preset options from _meta (#591)
Closes #581

Pass through object-based systemPrompt options from _meta while
forcing the claude_code preset, and add tests for defaulting,
string replacement, option forwarding, and override protection.
2026-04-24 16:08:04 +02:00
Eric Holk
e09f1486f1 fix: Forward SDKAssistantMessage.error as structured data on internal errors (#582)
## Motivation

When a Zed user on the Claude Pro tier hits their usage limit, Zed
receives an error like this from claude-agent-acp:

```json
{
  "code": -32603,
  "message": "Internal error: You've hit your limit \u00b7 resets 8pm (America/Los_Angeles)",
  "data": undefined
}
```

The only way for a client to recognize this as a rate-limit condition
(vs. any of the other things that can hit the `is_error: true` path —
billing issues, server errors, max tokens, etc.) is to pattern-match on
the human-readable message text. That's fragile and breaks every time
the message gets reworded upstream.

## What Claude Code already provides

The Claude Agent SDK actually emits a categorical kind on the
`SDKAssistantMessage` that precedes the failing `result`:

```ts
export declare type SDKAssistantMessageError =
  | 'authentication_failed'
  | 'billing_error'
  | 'rate_limit'
  | 'invalid_request'
  | 'server_error'
  | 'unknown'
  | 'max_output_tokens';
```

\(Confirmed by inspection of the shipped `cli.js`: the CLI calls a
helper that wraps errors into assistant messages with `error:
"rate_limit"` \(or `billing_error`, etc.\) based on the nature of the
failure.\)

The adapter today reads `message.message.usage`,
`message.message.model`, and `message.message.content` off the
`SDKAssistantMessage`, but ignores the top-level `error` field. By the
time we throw `RequestError.internalError\(undefined, message.result\)`
on the failing result, the categorical info has been discarded.

## This PR

Capture the last seen `SDKAssistantMessage.error` and forward it to
`RequestError.internalError`'s `data` as `{ errorKind }`:

```json
{
  "code": -32603,
  "message": "Internal error: You've hit your limit \u00b7 resets 8pm (America/Los_Angeles)",
  "data": { "errorKind": "rate_limit" }
}
```

ACP clients can then dispatch on the structured kind instead of
pattern-matching on the message text. Clients that don't understand the
field fall back to the existing message-based rendering unchanged
\(`data` is now populated in some cases where it used to be `undefined`,
but that's purely additive — no existing client reads this field today
so there's no compatibility risk\).

When the SDK doesn't provide a categorical error, we continue to pass
`undefined` so `data` stays absent.

## Changes

- `src/acp-agent.ts`: Track a `lastAssistantError:
SDKAssistantMessageError | undefined` through the `prompt()` iteration,
populated from the assistant branch. Thread it through to all three
`throw RequestError.internalError` sites in the result branch via a
small `errorKindData` helper.
- `src/tests/acp-agent.test.ts`: Two new tests — one verifying that an
upstream `error: "rate_limit"` on an `SDKAssistantMessage` shows up as
`{ errorKind: "rate_limit" }` on the thrown error's `data`, one
verifying that absence stays `undefined`.

## Open questions

1. **Field name.** I went with `errorKind` since it's short,
agent-agnostic, and not conflated with JSON-RPC's own `code`. Open to
bikeshedding.
2. **Whether to push this toward being an ACP-wide convention.** Other
adapters \(codex, gemini\) face the same problem — everything non-auth
squashed into `InternalError`. If this lands and works well here, it
might be worth writing up a little guidance in the ACP docs for "how
adapters should encode categorical error reasons" so we get the same
shape from every agent.
3. **Companion Zed PR.** The Zed-side change to read `data.errorKind`
and map to the existing `ThreadError::RateLimitExceeded` /
`AuthenticationRequired` / `PaymentRequired` / `MaxOutputTokens`
variants is straightforward \(~20 lines\) but I've held off on it until
this ships and a release is cut.

## Testing

- `npm run test:run`: 199 passing \(was 197; 2 new\).
- `npm run build`: clean.
- `npm run check`: lint + format clean.

This is part of a broader quality-week effort in Zed to improve the
external-agent debugging experience
\(<https://github.com/zed-industries/zed/issues/54531>\).
2026-04-24 13:52:20 +00:00
Anna Zhdan
1e15f3d8b0 feat: allow configuring models through env vars (#586)
Allow providing Claude model settings via env var on startup. Providing
model settings is required when using Claude with alternative llm
provider, e.g. Bedrock as models have different IDs there
2026-04-24 15:50:28 +02:00
Ben Brandt
92adcbd1ac feat: Update to acp sdk v0.20 (#589) 2026-04-24 13:49:18 +00:00
dependabot[bot]
e474a0c127 chore(deps): bump googleapis/release-please-action from 4.4.1 to 5.0.0 (#588)
Bumps
[googleapis/release-please-action](https://github.com/googleapis/release-please-action)
from 4.4.1 to 5.0.0.
<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>v5.0.0</h2>
<h2><a
href="https://github.com/googleapis/release-please-action/compare/v4.4.1...v5.0.0">5.0.0</a>
(2026-04-22)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>upgrade to node24 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1188">#1188</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>upgrade to node24 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1188">#1188</a>)
(<a
href="46dfc01594">46dfc01</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>bump release-please from 17.3.0 to 17.6.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1199">#1199</a>)
(<a
href="f533c26b74">f533c26</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.1...v5.0.0">5.0.0</a>
(2026-04-22)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>upgrade to node24 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1188">#1188</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>upgrade to node24 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1188">#1188</a>)
(<a
href="46dfc01594">46dfc01</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>bump release-please from 17.3.0 to 17.6.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1199">#1199</a>)
(<a
href="f533c26b74">f533c26</a>)</li>
</ul>
<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>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="45996ed1f6"><code>45996ed</code></a>
chore(main): release 5.0.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1200">#1200</a>)</li>
<li><a
href="a8121b99c9"><code>a8121b9</code></a>
chore: build dist (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1201">#1201</a>)</li>
<li><a
href="f533c26b74"><code>f533c26</code></a>
fix: bump release-please from 17.3.0 to 17.6.0 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1199">#1199</a>)</li>
<li><a
href="46dfc01594"><code>46dfc01</code></a>
feat!: upgrade to node24 (<a
href="https://redirect.github.com/googleapis/release-please-action/issues/1188">#1188</a>)</li>
<li>See full diff in <a
href="5c625bfb5d...45996ed1f6">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.1&new-version=5.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-04-24 15:49:15 +02:00
XiaoYan Li
ef1dbd1cb4 feat: Update to claude-agent-sdk 0.2.119 (#587)
Bumps `@anthropic-ai/claude-agent-sdk` from `0.2.114` to `0.2.119`
(latest).

## Why

Primarily to pick up the April 20 system prompt verbosity revert called
out in the [April 23
postmortem](https://www.anthropic.com/engineering/april-23-postmortem),
which shipped in `claude-agent-sdk` `0.2.116` (parity with Claude Code
v2.1.116). Per the postmortem, an instruction added on April 16 —
_"Length limits: keep text between tool calls to ≤25 words. Keep final
responses to ≤100 words unless the task requires more detail."_ — caused
a measurable drop in coding quality for Sonnet 4.6, Opus 4.6, and Opus
4.7, and was reverted in the v2.1.116 release.

The other two regressions described in the postmortem (the
cache-clearing thinking-blocks bug fixed on April 10, and the default
reasoning effort revert on April 7) were already addressed before the
`0.2.114` this repo currently pins, so this upgrade is specifically
about the verbosity-prompt fix and the SDK improvements that have landed
since.

## What's also included between 0.2.114 and 0.2.119

From the [SDK release
notes](https://github.com/anthropics/claude-agent-sdk-typescript/releases):

- **0.2.116** — parity with Claude Code v2.1.116 (postmortem fix)
- **0.2.117** — parity with Claude Code v2.1.117
- **0.2.118** — adds `Options.managedSettings` for embedders to pass
policy-tier settings to the spawned CLI in-memory, honored below
IT-controlled managed sources
- **0.2.119**
- `excludeDynamicSections` now keeps static auto-memory instructions in
the cacheable system-prompt block; only the per-user memory directory
path and per-machine environment values are relocated to the first user
message
- Long-running SDK sessions now reconnect claude.ai-proxied MCP servers
after a transport-stream abort
- `SessionStore.append()` failures are now retried up to 3 times with
short backoff before the batch is dropped and `mirror_error` is emitted

No source changes were required in this repo — the public API surface
this project uses is unchanged.

## Verification

- `npm run build` ✅
- `npm run check` (lint + prettier) ✅
- `npm run test:run` ✅ (197 passed, 11 skipped)

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-24 13:44:38 +00:00
dependabot[bot]
e30f0e5ba0 chore(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#577)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from
6.3.0 to 6.4.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.4.0</h2>
<h2>What's Changed</h2>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade <a
href="https://github.com/actions"><code>@​actions</code></a>
dependencies by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li>
<li>Update Node.js versions in versions.yml and bump package to v6.4.0
by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1533">actions/setup-node#1533</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v6.4.0">https://github.com/actions/setup-node/compare/v6...v6.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="48b55a011b"><code>48b55a0</code></a>
Update Node.js versions in versions.yml and bump package to v6.4.0 (<a
href="https://redirect.github.com/actions/setup-node/issues/1533">#1533</a>)</li>
<li><a
href="ab72c7e7eb"><code>ab72c7e</code></a>
Upgrade <a href="https://github.com/actions"><code>@​actions</code></a>
dependencies (<a
href="https://redirect.github.com/actions/setup-node/issues/1525">#1525</a>)</li>
<li>See full diff in <a
href="53b83947a5...48b55a011b">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=6.3.0&new-version=6.4.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-04-20 19:00:23 +02:00
Ben Brandt
9e1185bfd5 feat: Support effort levels (#464) 2026-04-20 15:21:41 +02:00
acp-release-bot[bot]
3d2fd36de2 chore(main): release 0.30.0 (#573)
🤖 I have created a release *beep* *boop*
---


##
[0.30.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.2...v0.30.0)
(2026-04-20)


### Features

* Update to claude-agent-sdk 0.2.114
([#572](https://github.com/agentclientprotocol/claude-agent-acp/issues/572))
([e9dd452](e9dd45207d))

---
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-20 11:45:55 +00:00
Ben Brandt
e9dd45207d feat: Update to claude-agent-sdk 0.2.114 (#572)
This now uses an exectuble version of claude code under the hood, so we
should be hopefully getting faster new session times.
2026-04-20 11:44:50 +00:00
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
Ben Brandt
e8545266fe Prep 0.22.1 release (#438) 2026-03-17 21:58:33 +00:00
Aleksandr Suhinin
ff3b97aece fix: suppress account assertion if gateway authentication is used (#436) 2026-03-17 17:51:02 +01:00
Steffen Deusch
c40d7bc30f fix session close method name (#431)
that's the nice part about unit tests, all green and still broken...

Relates to https://github.com/zed-industries/claude-agent-acp/pull/409.
2026-03-16 19:06:55 +01:00
Ben Brandt
152fe91152 Prep 0.22.0 release (#430) 2026-03-16 15:48:04 +00:00
Ben Brandt
45de3d2847 Use stable list sessions method (#429) 2026-03-16 15:41:27 +00:00
Ben Brandt
c7ae07da6b Use correct Claude CLI path for static binaries (#428)
Closes #424
2026-03-16 15:30:24 +00:00
Ben Brandt
0af467c400 Update claude-agent-sdk to 0.2.76 (#427)
Closes #420
2026-03-16 15:18:51 +00:00
mudrii
f4ce899223 fix: resolve model aliases in setSessionConfigOption (#401) (#403)
## Summary
Fixes #401 by enabling model alias/fuzzy resolution in
`setSessionConfigOption` when updating the `model` config option.

## Root cause
`setSessionConfigOption` validated model values using an exact string
match against config option values (model IDs like `claude-opus-4-5`):

```ts
const validValue = allValues.find((o) => o.value === params.value);
```

Clients often send human-friendly model preferences (`opus`, `sonnet`,
`Claude Sonnet`), which failed this exact check and produced:

- `Invalid value for config option model: <value>`

The file already had `resolveModelPreference(...)`, which supports
exact/display/substring/tokenized matching, but that logic was only used
in model initialization paths and not in `setSessionConfigOption`.

## What changed
### 1) Fuzzy model resolution in `setSessionConfigOption`
- Kept the existing exact-match validation path.
- When `configId === "model"` and exact match fails, map config option
entries to `ModelInfo[]` (`value` + `displayName`) and call
`resolveModelPreference(...)`.
- If resolution succeeds, use the resolved canonical model ID
(`resolvedValue`) for:
  - `query.setModel(...)`
  - `session.configOptions` current value update
  - response payload (`configOptions`)

### 2) Notification behavior unchanged by design
- Intentionally **did not** add `updateConfigOption(...)` in
`setSessionConfigOption`.
- This preserves existing behavior/tests that verify no
`config_option_update` notification is sent for this RPC (response
already returns full `configOptions`).

## Tests
Added focused coverage in `src/tests/session-config-options.test.ts`
under `describe("setSessionConfigOption")`:
- resolves model alias `opus` -> `claude-opus-4-5`
- resolves model alias `sonnet` -> `claude-sonnet-4-5`
- resolves display name `Claude Sonnet` -> `claude-sonnet-4-5`
- still accepts exact model ID
- still throws for invalid model value (`gpt-4`)

## Behavior before / after
### Before
- `setSessionConfigOption({ configId: "model", value: "opus" })` ->
error

### After
- same call resolves to canonical ID and succeeds:
  - `setModel("claude-opus-4-5")`
  - returned `configOptions.model.currentValue === "claude-opus-4-5"`

## Verification
- `npm run build` ✅
- `npm test` ✅ (all tests passing)
2026-03-16 16:05:01 +01:00
Ben Brandt
31539b4ee9 Reuse existing sessions for load/resume if possible (#426)
Closes #415

Add `getOrCreateSession` so resume/load returns existing session config
without recreating the session. Replace ad-hoc permission tracking with
`modes.currentModeId` and centralize config updates through
`syncSessionConfigState` to keep `modes` and `models` in sync with
config option changes. Update tests for the new session shape.
2026-03-16 15:59:45 +01:00
Ben Brandt
61a39ea801 Remove interrupt flag from deny responses (#425)
Now that the models are doing more parallel tool calls, we don't
necessarily want to interrupt in all of these cases.

Closes #402
2026-03-16 14:04:38 +00:00
Shivansh
c0b7752b45 Allow Bypass permissions mode after Exiting plan (#410)
Adds a new `ExitPlanMode` choice so users can switch directly to
`bypassPermissions` after accepting a plan, instead of only
`acceptEdits` or `default`.

### Changes
- Updated the `ExitPlanMode` permission options in `src/acp-agent.ts` to
conditionally include:
- `Yes, and bypass permissions` (`optionId: "bypassPermissions"`)
- Reused existing `ALLOW_BYPASS` guard so the option is only shown when
bypass is supported.
- Updated selection handling so `bypassPermissions` is treated as a
valid accepted outcome and applies mode updates like the existing paths.
2026-03-13 16:01:46 +00:00
Ben Brandt
3002539e4a Fix test (#416) 2026-03-13 15:58:18 +00:00
Steffen Deusch
87a0886a34 Don't get out of sync when background task creates new init/result (try 2) (#400)
Followup for
https://github.com/zed-industries/claude-agent-acp/pull/386.

When sending `/compact`, there's no replay for the user message, so we
did not resolve the prompt. Same for `/context`.

I tried what happens when sending a `/context` or `/compact` while
another prompt is running and Claude does not properly handle it.
Instead, it responds with something like

> I also noticed you sent /compact while I was working. That's a
built-in CLI command (not a skill), which compacts the conversation
context. It should be invoked directly in the CLI rather than as a
message to me.

The important part is
f52f214937.
2026-03-13 16:55:42 +01:00
Steffen Deusch
2193a13a3b Add session/close support (#409)
~Waiting for
https://github.com/agentclientprotocol/agent-client-protocol/pull/723.~

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-13 16:53:22 +01:00
Ben Brandt
c13edf3b02 Prep 0.21.0 release (#399) 2026-03-09 15:10:34 +00:00
Ben Brandt
a217891e6c Revert "Don't get out of sync when background task creates new init/result (#386)" (#398) 2026-03-09 16:07:23 +01:00
Ben Brandt
867de85f0b Revert "Don't get out of sync when background task creates new init/result (#386)" (#398) 2026-03-09 15:05:30 +00:00
Ben Brandt
af11cdbba5 Update to claude-agent-sdk 0.2.71 (#397) 2026-03-09 15:00:58 +00:00
Cengiz Han
f7af07758c feat: pass through tools array to control built-in tool availability (#387)
## Summary

- Pass through `_meta.claudeCode.options.tools` to the Claude Agent SDK
instead of hard-coding `{ type: "preset", preset: "claude_code" }`
- Reimplement `disableBuiltInTools` as `tools: []` instead of pushing 14
tool names into `disallowedTools`
- Explicit `tools` array takes precedence over `disableBuiltInTools`

## Problem

The ACP adapter hard-coded `tools: { type: "preset", preset:
"claude_code" }`, ignoring any value the caller provided via
`_meta.claudeCode.options.tools`. This caused two problems:

1. **Wasted context tokens** — All ~15 tool schemas were always sent to
the model, even when the caller only needed a subset (e.g., Read and
Glob for a review-only workflow) or none at all (MCP-only sessions).

2. **Rejected tool call round trips** — When `disableBuiltInTools: true`
was used, the tools were still registered in the model's context (the
flag only added them to `disallowedTools`). The model would see the tool
schemas, attempt to call them, get rejected, and waste a round trip.

Additionally, the existing `disableBuiltInTools` flag maintained a
hard-coded list of 14 tool names to blocklist. If the SDK added a new
built-in tool, `disableBuiltInTools` wouldn't cover it — the new tool
would leak through.

## SDK Contract Validation

The `tools` option is documented in the [Claude Agent SDK TypeScript
reference](https://platform.claude.com/docs/en/agent-sdk/typescript) as:

```typescript
tools?: string[] | { type: 'preset'; preset: 'claude_code' };
```

> Tool configuration. Pass an array of tool names or use the preset to
get Claude Code's default tools.

The type `string[]` includes `[]` (empty array) with no minimum length
constraint. Passing an empty array to disable all built-in tools is a
valid use of the SDK contract, not a workaround.

## Changes

### `src/acp-agent.ts`

**One line of behavioral change** — the `tools` field now uses the
caller-provided value if present, falling back to the preset:

```typescript
tools: userProvidedOptions?.tools ?? { type: "preset", preset: "claude_code" },
```

**`disableBuiltInTools` reimplemented** — instead of pushing 14 tool
names into `disallowedTools`, it resolves to `tools: []`:

```typescript
const resolvedTools: Options["tools"] =
  userProvidedOptions?.tools ??
  (params._meta?.disableBuiltInTools === true
    ? []
    : { type: "preset", preset: "claude_code" });
```

Resolution priority:
```
_meta.claudeCode.options.tools  →  use it (explicit whitelist)
_meta.disableBuiltInTools: true →  tools: [] (legacy shorthand)
neither                         →  { type: "preset", preset: "claude_code" } (default)
```

### `src/tests/create-session-options.test.ts`

4 new tests + 1 updated test:

| Test | Verifies |
|------|----------|
| `defaults tools to claude_code preset when not provided` | Backward
compatibility — no `tools` = full preset |
| `passes through user-provided tools string array` | Whitelist:
`["Read", "Glob"]` arrives as-is |
| `passes through empty tools array to disable all built-in tools` |
`tools: []` disables everything |
| `explicit tools array takes precedence over disableBuiltInTools` |
Resolution priority: explicit `tools` wins over `disableBuiltInTools` |
| `sets tools to empty array when disableBuiltInTools is true` | Legacy
flag now produces `tools: []` instead of blocklist |

## Usage Examples

```typescript
// Review-only session: model can only read files
_meta: { claudeCode: { options: { tools: ["Read", "Glob"] } } }

// MCP-only session: no built-in tools
_meta: { claudeCode: { options: { tools: [] } } }

// Legacy: still works, now equivalent to tools: []
_meta: { disableBuiltInTools: true }
```

## Non-breaking

Callers that don't provide `tools` get identical behavior (full
`claude_code` preset). `disableBuiltInTools: true` still works but is
now a less flexible alias for `tools: []`.

## Test plan

- [x] All existing tests pass (`npm test` — 131 tests, 126 passed, 5
skipped)
- [x] New tests cover: default preset, explicit array, empty array,
precedence over `disableBuiltInTools`
- [x] Verified `tools` type against [official SDK
docs](https://platform.claude.com/docs/en/agent-sdk/typescript)

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-09 13:31:48 +00:00
Steffen Deusch
3524606555 Don't get out of sync when background task creates new init/result (#386)
Relates to #336.

This does NOT ensure that the results are immediately sent to the
client.

See
https://github.com/zed-industries/claude-agent-acp/issues/336#issuecomment-4011939471.

I guess some tests for this would be useful.
2026-03-09 14:19:49 +01:00
Rohan Patra
9ecb222807 feat: show project-relative paths in tool call titles (#393)
## Summary
- Tool call titles (Read, Write, Edit) currently display absolute file
paths like `/Users/jane/my-project/src/main.ts`, which are long and
redundant since the user already knows their project root.
- This PR converts those paths to project-relative display paths (e.g.,
`src/main.ts`) by comparing against the session's `cwd`. Paths outside
the project directory remain absolute.
- The `locations.path` field is **not** changed, it stays absolute for
Zed's file navigation.

## Test plan
- [x] Added unit tests for `toDisplayPath` (relativizes paths inside
cwd, keeps absolute paths outside, handles partial directory name
matches)
- [x] Added unit test for `toolInfoFromToolUse` with `cwd` parameter
(verifies title uses relative path, locations stay absolute)
- [x] All 124 existing tests pass
2026-03-09 14:13:08 +01:00
Steffen Deusch
dd9fe3a98e skip user replay (#385)
Closes #381.
Relates to #348.

In #348 I added replay to handle queued prompts.
In Tidewave, we ignore user_message_chunks, so I did not experience the
issue when testing. But clients that show the user_message_chunk like
Zed showed the replayed content. This commit ensures that replayed
messages are skipped.
2026-03-06 14:38:31 +01:00
Rohan Patra
1c641cd6a7 fix: handle renamed Agent tool in toolInfoFromToolUse (#384)
## Summary
- The Claude SDK renamed the `Task` tool to `Agent`, but
`toolInfoFromToolUse` only matched `case "Task":`, so the `Agent` tool
fell through to the `default` case — rendering as a bare "Agent" label
with no description or content in the chat UI.
- Adds `case "Agent":` as a fallthrough before `case "Task":` so both
names are handled identically.

## Test plan
- [ ] Verify that when Claude spawns a subagent, the tool call in Zed's
chat shows the agent's description as the title (not a bare "Agent"
label)
2026-03-06 07:23:07 +00:00
Ben Brandt
a02ef184d3 Put back gateway auth check (#380) 2026-03-04 21:28:34 +00:00
Ben Brandt
3beddee766 Update to claude-agent-sdk 0.2.68 (#379) 2026-03-04 21:26:24 +00:00
José O R Ferreira
52d5b74aa7 fix: inherit process.env when spawning agent subprocess (#374)
In 0.20.0, the env option was introduced with an explicit object spread,
but without including process.env. This caused the subprocess to receive
an empty environment, stripping HOME, PATH and other inherited variables
when spawned from an external editor such as Zed.

Add ...process.env as the base so user-provided and gateway env vars
still override it, while preserving the parent process environment.

Add tests to verify HOME/PATH are inherited and that user-provided vars
are merged on top correctly.

Fixes #373

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-04 07:05:49 +01:00
Aleksandr Suhinin
edf6486c44 Authentication adjustments for JB integration (#350)
Updated authentication methods for IDEA compatibility and SDK compliance

#### New authentication type: gateway (url + custom headers)
 
- Required to support native IDEA authentication flows
 
#### Process argument to hide Claude Code authentication

- Ensures compliance with Anthropic’s third-party authentication
policies.

https://platform.claude.com/docs/en/agent-sdk/overview

> Unless previously approved, Anthropic does not allow third party
developers to offer claude.ai login or rate limits for their products,
including agents built on the Claude Agent SDK. Please use the API key
authentication methods described in this document instead.

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-03 20:29:44 +01:00
Ben Brandt
232a8cd8e2 Only store session on successful setup (#372) 2026-03-03 15:10:59 +00:00
Ben Brandt
37e3f389f6 prep release 0.20.0 (#371)
- **Remove unnecessary static-entry file**
- **Prep 0.20 release**
2026-03-03 15:49:37 +01:00
Ben Brandt
f513a14a46 Support more notifications (#370)
- **Give notification of compaction**
- **Also support local command output**
2026-03-03 14:16:43 +00:00
Kunall Banerjee
c0e2cee265 Surface better error message when Claude Code process exits unexpectedly (#366)
As seen in https://github.com/zed-industries/zed/issues/39563, Claude
Agent child processes can die mid-session (crash, signal, OOM, et al).
When that happens, the SDK throws errors with internal messages like
`"ProcessTransport closed"`, `"Failed to write to process stdin"`, or
`"process terminated by signal"`. These would bubble up to the user
as-is, which is not helpful.

At this point, it’s [not possible to continue the
session](https://github.com/zed-industries/zed/issues/39563#issuecomment-3776814727)
either (which I also confirmed myself), but that is not obvious from the
error the user sees (screenshot on the left).

In my testing, I could not get the `Error: ProcessTransport is not ready
for writing` error, but you can easily trigger the `SIGTERM` (exit code
143) by simply killing the `claude` child process spawned by the ACP
adapter while the agent is streaming a response:

<img width="1621" height="54" alt="image"
src="https://github.com/user-attachments/assets/29d989f1-7e56-44b3-992d-065218444958"
/>

In this case, you’d do `kill 74573` to trigger the error.

AFAICT, the child process is managed internally by the Claude Agent SDK
(inside the `query` object returned by `query()`). The ACP agent only
sees it as an `AsyncGenerator`. There’s no `process.pid` or
`ChildProcess` handle exposed to check liveness against. The only way to
discover the process is dead is when the SDK throws one of these
transport-level errors*.

\*I got these error strings by asking Opus 4.6 to de-obfuscate
(`node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs`)

| Before | After |
|--------|--------|
| <img width="466" height="62" alt="image"
src="https://github.com/user-attachments/assets/dc959924-0929-4587-9ddd-4a3873f1fa5d"
/> | <img width="462" height="77" alt="image"
src="https://github.com/user-attachments/assets/77eff880-28da-489a-b9e3-e9f93abf3c7f"
/> |

In other words, I think the best we (the ACP adapter) can do here is to
grep for these transport errors and surface a _better_ error message to
the user, as seen above.

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-03 13:54:51 +01:00
Anurag Akkiraju
b4f56b17fc fix: throw resourceNotFound when loadSession fails to resume (#363)
## Summary

- When `loadSession` calls `createSession({ resume: sessionId })` and
the CLI subprocess can't find persisted session data (no `.jsonl` file),
the subprocess exits immediately and `createSession` rejects with a
generic `-32603` ("Query closed before response received")
- ACP clients like [acpx](https://github.com/openclaw/acpx) check for
`-32001`/`-32002` (resource not found) to fall back to `session/new` —
the generic `-32603` bypasses this, causing the turn to fail entirely
- This commonly happens when `session/new` creates an ACP session but
the subprocess exits before writing session data (no prompt to process),
then `session/prompt` tries `session/load` to resume a session that was
never persisted

## Fix

Wrap the `createSession({ resume })` call in `loadSession()` with
try/catch and re-throw as `RequestError.resourceNotFound()` (code
`-32002`). This lets callers handle it with their existing fallback
logic.

## Verification

Confirmed working in production with the
[OpenClaw](https://github.com/openclaw/openclaw) gateway + acpx
integration. Before the fix, all ACP tasks failed silently. After
patching both this code path and acpx's `shouldFallbackToNewSession()`
([openclaw/acpx#30](https://github.com/openclaw/acpx/pull/30)), sessions
fall back to `session/new` correctly.

Fixes #338
Closes #361
Closes #362

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-03 13:47:25 +01:00
Anurag Akkiraju
c2e45e638d fix: add missing zod dependency (#364)
## Summary

- `@agentclientprotocol/sdk@0.14.1` declares `zod` as a peer dependency
(`"^3.25.0 || ^4.0.0"`) but this package does not include it as a direct
dependency
- On clean installs (e.g. Zed's external agent directory), `zod` is not
hoisted from any other package, causing `ERR_MODULE_NOT_FOUND` on every
agent start
- Users must manually `npm install zod` after every update as a
workaround

## Fix

Add `"zod": "^3.25.0 || ^4.0.0"` to `dependencies` to match the SDK's
peer dependency range.

Fixes #357

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-03-03 12:01:03 +00:00
Luis
5c1863d56e Fix: propagate max_tokens stop reason instead of throwing internal error (#365)
## Summary

- When the Claude SDK reports `stop_reason: "max_tokens"`, the ACP
adapter now returns `{ stopReason: "max_tokens" }` instead of throwing a
`RequestError.internalError` (JSON-RPC `-32603`)
- Scoped to `success` and `error_during_execution` result subtypes only
— `error_max_turns` / `error_max_budget_usd` still correctly map to
`max_turn_requests`

## Problem

When tokens are exhausted, the SDK sends a `result` message with
`stop_reason: "max_tokens"` and `is_error: true`. The adapter hit the
`is_error` check first and threw an internal error, so ACP clients never
received the `stopReason` field. Downstream tools like
[toad](https://github.com/batrachianai/toad/discussions/176#discussioncomment-15445958)
saw a JSON-RPC exception instead of a clean stop reason.

## Fix

Check `stop_reason === "max_tokens"` before the `is_error` throw in the
`success` and `error_during_execution` branches. Token exhaustion is a
normal stop condition, not an internal error.

## Test plan

- [x] Added 5 unit tests covering:
  - `success` + `max_tokens` + `is_error: false` → returns `max_tokens`
- `success` + `max_tokens` + `is_error: true` → returns `max_tokens`
(main bug)
- `error_during_execution` + `max_tokens` + `is_error: true` → returns
`max_tokens`
- `success` + `null` stop_reason → still returns `end_turn` (no
regression)
- `success` + `is_error: true` + non-max_tokens → still throws (no
regression)
- [x] All 100 tests pass
- [x] Build passes

Fixes #235

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:58:40 +00:00
Tim Visher
6253b1611e Respect user settings for permission mode and model selection (#340)
Most user settings (`env`, permission rules like `allow`/`deny`/`ask`)
already work through the SDK's `settingSources` or are handled by the
CLI subprocess. Two settings require explicit handling by the ACP agent
and were not being respected:

**`permissions.defaultMode`**: Must be passed as the `permissionMode`
option to `query()`. The SDK defaults to `"default"` internally and does
not read it from settings files. The CLI handles this by reading the
setting and passing it to the SDK; `createSession` was hardcoding it to
`"default"` instead.

**`model`**: The CLI persists display strings like `"opus[1m]"` in
settings, but the SDK model list uses IDs like `"claude-opus-4-6-1m"`.
The existing substring matching in `getAvailableModels` couldn't resolve
these aliases, so they silently fell back to the first model. Passing
the raw alias to `query.setModel()` doesn't work either — the CLI's
internal `dg()` function strips `[1m]` and loses the context hint.

Changes:
- Fix pre-existing build errors from SDK type changes
(`SDKTaskStartedMessage` removed, `SDKMessageTemp` replaced with SDK's
own `SDKMessage`)
- Add `permissions.defaultMode` to `ClaudeCodeSettings`, merge it
through the settings hierarchy, and resolve it via
`resolvePermissionMode()` with case-insensitive aliases, validation, and
root-user guard
- Add tokenized model matching (`resolveModelPreference`) that handles
CLI display strings like `"opus[1m]"` by scoring against the available
models list
- Add unit and integration tests for both features

Co-authored-by: Codex <codex@openai.com>

---------

Co-authored-by: Tim Visher <194828183+timvisher-dd@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Codex <codex@openai.com>
2026-03-03 12:54:36 +01:00
Ben Brandt
6ff856c94f Update to claude-agent-sdk 0.2.63 (#369) 2026-03-03 12:53:16 +01:00
Steffen Deusch
1b057923e8 support --cli for node (#358)
This allows to also use `--cli` when not using the standalone build.
2026-02-27 21:44:59 +01:00
Steffen Deusch
3b3ce6f287 Ensure concurrent prompts are handled. (#348)
This basically implements the pending prompt queueing RFD. When a prompt
request is received while the agent is already generating, we
immediately forward the message to Claude and then wait until it replays
the message back to us. When it replays it, we respond to the previous
prompt request with "end_turn", which also singifies to the client that
the message is now being processed by the agent.

See
https://github.com/agentclientprotocol/agent-client-protocol/pull/484.
2026-02-27 18:53:00 +01:00
Ben Brandt
b1d09f2366 Fix history support (#356) 2026-02-27 12:06:47 +01:00
Ben Brandt
d24066bd9d Support windows arm builds and clean up artifact names (#355) 2026-02-27 10:46:23 +00:00
Ben Brandt
5ca63abc47 Update to claude-agent-sdk 0.2.62 (#354) 2026-02-27 10:14:30 +00:00
Steffen Deusch
001614b459 expose parent_tool_use_id for subagents (#341)
I'm not sure yet how a good protocol for subagents could look like, so
instead of opening an RFD, I opted to expose Claude's
`parent_tool_use_id` in `_meta.claudeCode.parentToolUseId`. This will
allow Tidewave to render tools from subagents in a better way.
2026-02-26 22:45:12 +01:00
Steffen Deusch
218661f97b ACP Session Usage (#345)
The AI in https://github.com/zed-industries/claude-agent-acp/pull/344
had one good idea: only use the usage from the last assistant message
for context size. Of course, `usage` on the AssistantMessage is not
documented in the Agent SDK (we need to do an ugly cast), but this seems
to work alright.

We don't get the exact new usage after compaction, so I set it to zero.
2026-02-26 22:44:20 +01:00
Ben Brandt
5ede2b7c4c Use history methods from the SDK (#352) 2026-02-26 21:37:15 +00:00
Ben Brandt
988a741d59 Update to claude-agent-sdk 0.2.59 (#351) 2026-02-26 22:29:45 +01:00
Ben Limmer
b57a429867 fix: merge user-provided disallowedTools instead of overwriting (#335)
The disallowedTools merge fix from #295 was regressed by #316 when the
options object was restructured. Restore the merge behavior and add
regression tests for all three documented merge fields (disallowedTools,
hooks, mcpServers).

Fixes #334
2026-02-20 18:55:16 +01:00
Steffen Deusch
101f09dbf8 Add single-file executable using bun (#332)
This adds a single-file executable using bun. The trick is to use a
separate flag for ACP `--acp` and spawn the regular `cli.js` bundled by
the Agent SDK if no flags are passed. This was, we can pass ourselves as
pathToClaudeCodeExecutable.
2026-02-20 12:23:04 +01:00
Ben Brandt
d36204f6da Prep 0.18.0 release (#331) 2026-02-18 20:20:21 +00:00
Ben Brandt
4de2f98a8e Make sure we don't override terminal content (#328)
- **Fix sending markdown content that replaces terminal content**
- **Make sure to always updated content to be safe**
2026-02-18 13:46:18 +00:00
Ben Brandt
f5a5c73607 Use edit tool response to construct a better diff (#327) 2026-02-18 10:35:54 +00:00
Ben Brandt
5bd0af27ec Support session config options (#326) 2026-02-18 10:25:29 +01:00
Ben Brandt
be618f5dcb Switch over to built-in Claude Code tools (#316)
Given a number of recent issues stemming from Claude Code using more
subagents that don't play nicely with our custom mcp server, plus some
slowly diverging behavior, we made the decision to just switch back over
to the built-in tools and do more processing on the tool input/output

There are some downsides, but also a lot of upsides, on the whole, it
feels like a win for now.

Closes #310, #279, #305, #236, #94

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-02-18 09:52:16 +01:00
Ben Limmer
28b85aed41 fix: convert Read tool image content to ACP format (#322) (#323)
When the Read tool returns image content (e.g., reading a .png file),
the raw Claude SDK image block was passed through unconverted, causing
ACP clients to fail deserializing the tool call completion event. Route
non-text content through `toAcpContentBlock` to produce the correct ACP
image format.
2026-02-18 09:33:29 +01:00
Ben Brandt
44bb150b5d Update to claude-agent-sdk 0.2.45 to add access to Sonnet 4.6 (#324) 2026-02-17 22:08:43 +00:00
Ben Brandt
18bd9f2490 Fix bin path (#321) 2026-02-17 11:23:40 +00:00
Ben Brandt
b8e655d7ac Fix lockfile (#320) 2026-02-17 11:21:50 +00:00
Ben Brandt
0e77751692 Claude Code -> Claude Agent (#319)
Update based on
https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines
2026-02-17 12:14:55 +01:00
Ben Brandt
e5b836820b Prep 0.16.2 release (#318) 2026-02-17 10:06:15 +00:00
Ben Brandt
c3ffcfa98f Update to claude-agent-sdk 0.2.44 (#317) 2026-02-17 10:00:54 +00:00
RAIT-09
4d232dafad fix: Replace all non-alphanumeric characters in encodeProjectPath (#307)
This PR fixes `encodeProjectPath` to replace all non-alphanumeric
characters with `-`, matching how Claude Code actually encodes project
paths.

The previous implementation only replaced path separators (`/` on Unix,
`\` on Windows), so characters like `_`, non-ASCII characters (e.g.
CJK), and other non-alphanumeric characters were left as-is. This caused
a mismatch with the paths encoded by Claude Code, resulting in session
lookups failing with "Session not found" for directories containing such
characters.

The fix also removes the Windows-specific code path, as the simple regex
`[^a-zA-Z0-9]` correctly handles all platforms.

Related to #300
2026-02-16 18:26:41 +01:00
Steffen Deusch
4f0ffa2735 don't include /login slash command in login command (#315)
Claude resubmits the slash command after authenticating, so it will ask
for authentication twice.
Since Claude Code prompts for setup and authentication anyway if not
signed in, we can just not include /login in the command.
2026-02-16 18:22:27 +01:00
dependabot[bot]
f069df5857 Bump qs from 6.14.1 to 6.14.2 in the npm_and_yarn group across 1 directory (#311)
Bumps the npm_and_yarn group with 1 update in the / directory:
[qs](https://github.com/ljharb/qs).

Updates `qs` from 6.14.1 to 6.14.2
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ljharb/qs/blob/main/CHANGELOG.md">qs's
changelog</a>.</em></p>
<blockquote>
<h2><strong>6.14.2</strong></h2>
<ul>
<li>[Fix] <code>parse</code>: mark overflow objects for indexed notation
exceeding <code>arrayLimit</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/546">#546</a>)</li>
<li>[Fix] <code>arrayLimit</code> means max count, not max index, in
<code>combine</code>/<code>merge</code>/<code>parseArrayValue</code></li>
<li>[Fix] <code>parse</code>: throw on <code>arrayLimit</code> exceeded
with indexed notation when <code>throwOnLimitExceeded</code> is true (<a
href="https://redirect.github.com/ljharb/qs/issues/529">#529</a>)</li>
<li>[Fix] <code>parse</code>: enforce <code>arrayLimit</code> on
<code>comma</code>-parsed values</li>
<li>[Fix] <code>parse</code>: fix error message to reflect arrayLimit as
max index; remove extraneous comments (<a
href="https://redirect.github.com/ljharb/qs/issues/545">#545</a>)</li>
<li>[Robustness] avoid <code>.push</code>, use <code>void</code></li>
<li>[readme] document that <code>addQueryPrefix</code> does not add
<code>?</code> to empty output (<a
href="https://redirect.github.com/ljharb/qs/issues/418">#418</a>)</li>
<li>[readme] clarify <code>parseArrays</code> and
<code>arrayLimit</code> documentation (<a
href="https://redirect.github.com/ljharb/qs/issues/543">#543</a>)</li>
<li>[readme] replace runkit CI badge with shields.io check-runs
badge</li>
<li>[meta] fix changelog typo (<code>arrayLength</code> →
<code>arrayLimit</code>)</li>
<li>[actions] fix rebase workflow permissions</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bdcf0c7f82"><code>bdcf0c7</code></a>
v6.14.2</li>
<li><a
href="294db90c81"><code>294db90</code></a>
[readme] document that <code>addQueryPrefix</code> does not add
<code>?</code> to empty output</li>
<li><a
href="5c308e5516"><code>5c308e5</code></a>
[readme] clarify <code>parseArrays</code> and <code>arrayLimit</code>
documentation</li>
<li><a
href="6addf8cf73"><code>6addf8c</code></a>
[Fix] <code>parse</code>: mark overflow objects for indexed notation
exceeding <code>arrayLimit</code></li>
<li><a
href="cfc108f662"><code>cfc108f</code></a>
[Fix] <code>arrayLimit</code> means max count, not max index, in
<code>combine</code>/<code>merge</code>/`pars...</li>
<li><a
href="febb64442a"><code>febb644</code></a>
[Fix] <code>parse</code>: throw on <code>arrayLimit</code> exceeded with
indexed notation when `thr...</li>
<li><a
href="f6a7abff1f"><code>f6a7abf</code></a>
[Fix] <code>parse</code>: enforce <code>arrayLimit</code> on
<code>comma</code>-parsed values</li>
<li><a
href="fbc5206c25"><code>fbc5206</code></a>
[Fix] <code>parse</code>: fix error message to reflect arrayLimit as max
index; remove e...</li>
<li><a
href="1b9a8b4e78"><code>1b9a8b4</code></a>
[actions] fix rebase workflow permissions</li>
<li><a
href="2a35775614"><code>2a35775</code></a>
[meta] fix changelog typo (<code>arrayLength</code> →
<code>arrayLimit</code>)</li>
<li>Additional commits viewable in <a
href="https://github.com/ljharb/qs/compare/v6.14.1...v6.14.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=qs&package-manager=npm_and_yarn&previous-version=6.14.1&new-version=6.14.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-code-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-02-14 14:34:29 +01:00
Ben Brandt
e2a1ac9b9d Update to claude-agent-sdk 0.2.38 (#304) 2026-02-10 21:11:04 +00:00
Ben Brandt
673b0507d7 Make sure updating commands happens at the end of loading (#302) 2026-02-10 13:18:04 +00:00
Ben Brandt
ea00a4014a More permissive load session (#301)
Adds a lookup that checks the expected cwd path first, then
scans all project directories to locate the session JSONL file.
Ultimately matches the behavior we allow for resume
2026-02-10 12:36:02 +00:00
Ben Brandt
ebdd115b76 fix: Incorrect paths for session list (#298)
How Claude Code encodes the paths is lossy, so now we actually check the
cwd from the json files to make sure it is a valid path (otherwise
Claude Code just hangs)
2026-02-09 09:56:02 +00:00
Ben Limmer
7c87fe7a8c fix: merge user-provided disallowedTools instead of overwriting (#295)
## Summary

- User-provided `disallowedTools` from `_meta.claudeCode.options` were
silently overwritten by ACP's internal list
- Now merges both lists, following the same pattern used for `hooks` and
`mcpServers`
- Updated `NewSessionMeta` JSDoc to document the merge behavior

Fixes #294
2026-02-07 09:30:50 +00:00
Ben Brandt
8420b50523 Update to claude agent sdk 0.2.34 (#293)
Allows us to pass in session id via the SDK as well as use one promise
to get commands + models
2026-02-06 15:07:46 +01:00
Maximilian Krause
24339faf2b feat: implement loadSession by replaying JSONL session files (#285)
Based on the groundwork in #254, this adds support for `loadSession` to
replay messages and tool calls from resumed/loaded sessions through
Claude Code's persisted JSONL files.

- Advertise the `loadSession` capability
- Stream JSONL entries from
`~/.claude/projects/<cwd-encoded>/<sessionId>.jsonl`
- Correctly parse user/assistant messages and tool calls/results into
ACP session updates
- Add unit tests for the new functionality
2026-02-06 14:44:18 +01:00
Elle Najt
8360a21358 test: add tests for cross-tool rule isolation (#291)
## Summary
- Adds tests verifying that permission rules only apply to their
intended tool types
- Tests confirm the fix from #282 (commit d471ccf) works correctly

## Tests added
- Bash rules should not match Edit/Write/Read operations
- Edit rules should not match Bash operations
- Read rules should not match Bash operations

These tests catch the bug where `Bash(./**:*)` would incorrectly allow
file operations on matching paths.

## Verification
Confirmed tests fail on the commit before the fix (6b68ddf) and pass
after.

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:09:44 +01:00
Ben Brandt
a9985d49e9 Update anthropic types (#292) 2026-02-05 23:08:09 +00:00
Agus Zubiaga
9dfd0a0c4f Bump version to 0.15.0 (#290)
Prepares release 0.15.0 with Opus 4.6 support.
2026-02-05 20:14:07 +00:00
Agus Zubiaga
fd4fd247bf Use fixed version for claude-agent-sdk (#289)
Removes caret prefix to pin the exact SDK version.
2026-02-05 20:11:38 +00:00
Agus Zubiaga
67926a9ac2 Upgrade claude-agent-sdk to 0.2.32 (#287)
Adds support for Opus 4.6 and the new 1M context Opus model.
2026-02-05 17:07:11 -03:00
dependabot[bot]
4d0cb9cbdd Bump @modelcontextprotocol/sdk from 1.25.3 to 1.26.0 in the npm_and_yarn group across 1 directory (#286)
Bumps the npm_and_yarn group with 1 update in the / directory:
[@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk).

Updates `@modelcontextprotocol/sdk` from 1.25.3 to 1.26.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/modelcontextprotocol/typescript-sdk/releases"><code>@​modelcontextprotocol/sdk</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v1.26.0</h2>
<p>Addresses &quot;Sharing server/transport instances can leak
cross-client response data&quot; in this GHSA <a
href="https://github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-345p-7cg4-v4c7">https://github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-345p-7cg4-v4c7</a></p>
<h2>What's Changed</h2>
<ul>
<li>chore: bump v1.25.3 for backport fixes by <a
href="https://github.com/pcarleton"><code>@​pcarleton</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1412">modelcontextprotocol/typescript-sdk#1412</a></li>
<li>fix(deps): resolve npm audit vulnerabilities and bump dependencies
(v1.x backport) by <a
href="https://github.com/samuv"><code>@​samuv</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1382">modelcontextprotocol/typescript-sdk#1382</a></li>
<li>Fix <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1430">#1430</a>:
Client Credentials providers scopes support (backported) by <a
href="https://github.com/NSeydoux"><code>@​NSeydoux</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1442">modelcontextprotocol/typescript-sdk#1442</a></li>
<li>chore: bump version to 1.26.0 by <a
href="https://github.com/pcarleton"><code>@​pcarleton</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1479">modelcontextprotocol/typescript-sdk#1479</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/samuv"><code>@​samuv</code></a> made
their first contribution in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1382">modelcontextprotocol/typescript-sdk#1382</a></li>
<li><a href="https://github.com/NSeydoux"><code>@​NSeydoux</code></a>
made their first contribution in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1442">modelcontextprotocol/typescript-sdk#1442</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/modelcontextprotocol/typescript-sdk/compare/v1.25.3...v1.26.0">https://github.com/modelcontextprotocol/typescript-sdk/compare/v1.25.3...v1.26.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe9c07b465"><code>fe9c07b</code></a>
chore: bump version to 1.26.0 (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1479">#1479</a>)</li>
<li><a
href="4f01e7e070"><code>4f01e7e</code></a>
fix: add non-null assertions for optional setupServer fields in stateful
test</li>
<li><a
href="a05be176ca"><code>a05be17</code></a>
Merge commit from fork</li>
<li><a
href="50d9fa3cd1"><code>50d9fa3</code></a>
Fix <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1430">#1430</a>:
Client Credentials providers scopes support (backported) (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1442">#1442</a>)</li>
<li><a
href="aa81a66556"><code>aa81a66</code></a>
fix(deps): resolve npm audit vulnerabilities and bump dependencies (v1.x
back...</li>
<li><a
href="6aba065965"><code>6aba065</code></a>
chore: bump v1.25.3 for backport fixes (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1412">#1412</a>)</li>
<li>See full diff in <a
href="https://github.com/modelcontextprotocol/typescript-sdk/compare/v1.25.3...v1.26.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@modelcontextprotocol/sdk&package-manager=npm_and_yarn&previous-version=1.25.3&new-version=1.26.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 <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-code-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-02-04 21:57:57 +01:00
Elle Najt
e0cac12239 fix: Bash permission rules should only match Bash tool calls (#282)
## Summary
Fixes a bug where `Bash(...)` permission rules would incorrectly match
against non-Bash tools like Edit and Write.

## The Bug
In `matchesRule`, this check was the problem:

```typescript
const ruleAppliesToTool =
  rule.toolName === "Bash" ||  // <-- Only checks the RULE type, not the TOOL type
  (rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName)) ||
  (rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName));
```

Notice that Edit and Read rules correctly check BOTH the rule type AND
the tool type, but Bash only checked the rule type. This meant
`rule.toolName === "Bash"` returned true for ANY tool when the rule was
a Bash rule.

When a non-Bash tool (like `mcp__acp__Edit`) was invoked:
1. `rule.toolName === "Bash"` → `true`, so `ruleAppliesToTool = true`
2. The Bash-specific command matching was skipped (since `toolName !==
acpToolNames.bash`)
3. Code fell through to the glob matching at the end of `matchesRule`
4. The rule's argument was matched as a file glob against the file being
edited

## Evidence
With settings containing `Bash(./inbox:*)`, editing a file showed:

```
[PreToolUseHook] Tool: mcp__acp__Edit, Decision: allow, Rule: Bash(./inbox:*)
```

The Edit tool was being allowed by a Bash rule.

## The Fix
Add a check to ensure Bash rules only apply when the tool is actually
Bash:

```typescript
// Before (buggy)
rule.toolName === "Bash" ||

// After (fixed)  
(rule.toolName === "Bash" && toolName === acpToolNames.bash) ||
```

This makes the Bash check consistent with how Edit and Read rules work.

## Test plan
- [x] Verify `Bash(./script:*)` allows `mcp__acp__Bash` with command
`./script foo`
- [x] Verify `Bash(./script:*)` does NOT allow `mcp__acp__Edit` on file
`./script`

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:18:12 +01:00
dependabot[bot]
6b68ddf00e Bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 in the npm_and_yarn group across 1 directory (#281)
Bumps the npm_and_yarn group with 1 update in the / directory:
@isaacs/brace-expansion.

Updates `@isaacs/brace-expansion` from 5.0.0 to 5.0.1


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@isaacs/brace-expansion&package-manager=npm_and_yarn&previous-version=5.0.0&new-version=5.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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-code-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-02-03 21:54:29 +01:00
José Valim
34a617e20f Do not list keybindings-help as a command (#280)
This is actually a skill that comes as part of Claude Code,
which shouldn't be exposed as a command over ACP.
2026-02-03 15:41:50 +01:00
Railly Hugo
9016cba978 fix: respect user model preference from settings.json (#267)
- Integrates model into existing settings infrastructure
- Respects precedence: user < project < local < enterprise
- Removes duplicate file reading logic

Fixes #225
2026-02-02 17:20:08 +01:00
Ben Brandt
325c513f1b Prep 0.14.0 release (#278) 2026-02-02 15:16:39 +00:00
Tommy D. Rossi
87fa0a23c0 feat: implement unstable_listSessions for session/list RFD (#254)
Adds support for the draft session/list RFD spec by reading Claude
Code's local session files.

- Implement `unstable_listSessions` method that parses JSONL session
files from `~/.claude/projects/`
- Advertise `list` capability in `sessionCapabilities`
- Support filtering by `cwd` parameter
- Implement cursor-based pagination (50 sessions per page)
- Extract title from first user message, use file mtime as `updatedAt`

Related: https://agentclientprotocol.com/rfds/session-list

What do you think @benbrandt? Is it ok to do the json files parsing
ourselves? I also opened [an
issue](https://github.com/anthropics/claude-agent-sdk-typescript/issues/147)
in the claude agent sdk repo but I doubt they will add that
functionality in the sdk npm package

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-02-02 15:14:08 +00:00
Ben Brandt
c5a49e7481 Notify when we enter plan mode (#277)
Closes #274
2026-02-02 14:37:02 +00:00
Ben Brandt
c597cfae85 Support IS_SANDBOX env var (#276)
Closes #271
2026-02-02 14:20:06 +00:00
José Valim
a31f4534dd Update CLAUDE_CONFIG_DIR environment variable usage (#269)
According to the docs, that's the new of the env var:
https://code.claude.com/docs/en/settings#environment-variables
2026-02-02 14:13:28 +00:00
Ben Brandt
2e9bb8e82b Update to claude-agent-sdk 0.2.29 (#275) 2026-02-02 14:12:21 +00:00
Pointless
cfdb6463d6 Fix glob matching for file permissions on Windows (#249)
8 tests in settings.test.ts fail on Windows because `minimatch` expects
forward slashes but `path.normalize()` returns backslashes.

Converts paths to forward slashes before matching.
2026-02-02 09:57:41 +01:00
Joshua Carver
adb495d5d3 fix: Map Claude Code tool results to valid ACP content blocks (#270)
This PR fixes an issue with `claude-code-acp` where incoming tool
results from the Anthropic SDK would, in several cases, get mapped to
invalid ACP `ContentBlock`s inside of the `toAcpContentUpdate` method.
This prevents ACP clients from being able to properly render tool calls.

Per the [ACP
spec](https://agentclientprotocol.com/protocol/schema#contentblock)
`ContentBlock` can only have a `type` field with a value of: `text |
image | audio | resource | resource_link`. However, several of Claude
Code's tools return results with different `type`'s .

This PR adds a `toAcpContentBlock` method that maps tool call results to
valid ACP `ContentBlock`. It attempts to be defensive and will map
unknown types to a text content block. This avoids breakages if
Anthropic changes the types upstream, or introduces new tools.
2026-01-29 15:51:34 +00:00
Steffen Deusch
11ca660dec allow using /context command (#268)
I experimented with https://agentclientprotocol.com/rfds/session-usage
(see
https://github.com/agentclientprotocol/agent-client-protocol/pull/415),
but the Claude Agent SDK does not seem to return the information we need
for an accurate context indicator. For example, one request to explore a
project returned 500k+ cached read tokens in Claude's `result` message,
while the agent reported 64k tokens used. I can open a PR with those
changes for reference once the Typescript SDK is updated.

To allow users to still see the current context usage, allowing to run
`/context` seems to be the second best option. This PR changes the code
to handle the `<local-command-stdout>` message that the SDK generates
when sending `/context` and includes `/context` as allowed command.

Screenshot from Tidewave with this change:

<img width="460" height="1079" alt="image"
src="https://github.com/user-attachments/assets/a3796e46-4014-4988-a993-e13d38d38d96"
/>
2026-01-29 16:34:39 +01:00
Charles Covey-Brandt
32898580a5 feat: add rawOutput to tool call updates (#261)
## Summary
- Pass the raw tool result content as `rawOutput` in `tool_call_update`
notifications
- Allows ACP clients to access the unprocessed tool output alongside the
formatted content
- Adds tests using SDK types to document exact shapes for different tool
result types

## Test plan
- [x] `npm run build` passes
- [x] `npm test` passes (86 tests)
- [x] `npm run lint` passes
- [x] `npm run format:check` passes

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-28 09:47:36 +01:00
Ben Brandt
a7794b5ffb Prep 0.13.2 release (#266) 2026-01-28 08:45:01 +00:00
Ben Brandt
8802888e39 Renable _meta.terminal-auth support (#265) 2026-01-28 08:42:21 +00:00
Ben Brandt
e4cebeca96 Update to claude-agent-sdk 0.2.22 (#264) 2026-01-28 08:41:29 +00:00
dependabot[bot]
45a539257b Bump hono from 4.11.5 to 4.11.7 in the npm_and_yarn group across 1 directory (#263)
Bumps the npm_and_yarn group with 1 update in the / directory:
[hono](https://github.com/honojs/hono).

Updates `hono` from 4.11.5 to 4.11.7
<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.11.7</h2>
<h1>Security Release</h1>
<p>This release includes security fixes for multiple vulnerabilities in
Hono and related middleware. We recommend upgrading if you are using any
of the affected components.</p>
<h2>Components</h2>
<h3>IP Restriction Middleware</h3>
<p>Fixed an IPv4 address validation bypass that could allow IP-based
access control to be bypassed under certain configurations.</p>
<h3>Cache Middleware</h3>
<p>Fixed an issue where responses marked with <code>Cache-Control:
private</code> or <code>no-store</code> could be cached, potentially
leading to information disclosure on some runtimes.</p>
<h3>Serve Static Middleware (Cloudflare Workers adapter)</h3>
<p>Fixed an issue that could allow unintended access to internal asset
keys when serving static files with user-controlled paths.</p>
<h3>hono/jsx <code>ErrorBoundary</code></h3>
<p>Fixed a reflected Cross-Site Scripting (XSS) issue in the
<code>ErrorBoundary</code> component that could occur when untrusted
strings were rendered without proper escaping.</p>
<h2>Recommendation</h2>
<p>Users are encouraged to upgrade to this release, especially if
they:</p>
<ul>
<li>Use IP Restriction Middleware</li>
<li>Use Cache Middleware on Deno, Bun, or Node.js</li>
<li>Use Serve Static Middleware with user-controlled paths on Cloudflare
Workers</li>
<li>Render untrusted data inside <code>ErrorBoundary</code>
components</li>
</ul>
<h2>Security Advisories &amp; CVEs</h2>
<ul>
<li>
<p><strong>IP Restriction Middleware – IPv4 address validation
bypass</strong></p>
<ul>
<li>Advisory: <a
href="https://github.com/honojs/hono/security/advisories/GHSA-r354-f388-2fhh">https://github.com/honojs/hono/security/advisories/GHSA-r354-f388-2fhh</a></li>
<li>CVE: CVE-2026-24398</li>
</ul>
</li>
<li>
<p><strong>Cache Middleware ignores <code>Cache-Control:
private</code></strong></p>
<ul>
<li>Advisory: <a
href="https://github.com/honojs/hono/security/advisories/GHSA-6wqw-2p9w-4vw4">https://github.com/honojs/hono/security/advisories/GHSA-6wqw-2p9w-4vw4</a></li>
<li>CVE: CVE-2026-24472</li>
</ul>
</li>
<li>
<p><strong>Serve Static Middleware (Cloudflare Workers adapter) –
Arbitrary key read</strong></p>
<ul>
<li>Advisory: <a
href="https://github.com/honojs/hono/security/advisories/GHSA-w332-q679-j88p">https://github.com/honojs/hono/security/advisories/GHSA-w332-q679-j88p</a></li>
<li>CVE: CVE-2026-24473</li>
</ul>
</li>
<li>
<p><strong>hono/jsx <code>ErrorBoundary</code> – Cross-Site Scripting
(XSS)</strong></p>
<ul>
<li>Advisory: <a
href="https://github.com/honojs/hono/security/advisories/GHSA-9r54-q6cx-xmh5">https://github.com/honojs/hono/security/advisories/GHSA-9r54-q6cx-xmh5</a></li>
<li>CVE: Pending</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f7d272abe1"><code>f7d272a</code></a>
4.11.7</li>
<li><a
href="2cf60046d7"><code>2cf6004</code></a>
Merge commit from fork</li>
<li><a
href="cf9a78db4d"><code>cf9a78d</code></a>
Merge commit from fork</li>
<li><a
href="edbf6eea8e"><code>edbf6ee</code></a>
Merge commit from fork</li>
<li><a
href="12c511745b"><code>12c5117</code></a>
Merge commit from fork</li>
<li><a
href="7343487e62"><code>7343487</code></a>
4.11.6</li>
<li><a
href="b6e5a97cd4"><code>b6e5a97</code></a>
feat(bun): export getBunServer (<a
href="https://redirect.github.com/honojs/hono/issues/4626">#4626</a>)</li>
<li><a
href="2a9cd953b6"><code>2a9cd95</code></a>
fix(sse): handle <code>\r</code> and <code>\r\n</code> line endings in
writeSSE (<a
href="https://redirect.github.com/honojs/hono/issues/4644">#4644</a>)</li>
<li><a
href="8078bbf759"><code>8078bbf</code></a>
docs: align CODE_OF_CONDUCT.md wording with Contributor Covenant (<a
href="https://redirect.github.com/honojs/hono/issues/4630">#4630</a>)</li>
<li><a
href="a5be555b31"><code>a5be555</code></a>
refactor: use <code>unique symbol</code> for more accurate typing. (<a
href="https://redirect.github.com/honojs/hono/issues/4651">#4651</a>)</li>
<li>See full diff in <a
href="https://github.com/honojs/hono/compare/v4.11.5...v4.11.7">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.11.5&new-version=4.11.7)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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-code-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-01-27 22:53:21 +01:00
Ben Brandt
670fb18728 Update to claude-agent-sdk 0.2.19 (#260) 2026-01-26 10:15:54 +00:00
codeignus
36ea238d76 fix: return content from Write tool (#250)
## Problem
The Write tool was returning an empty content array, which causes errors
with some AI providers when using Claude Code through ACP.

Specifically, Z.AI GLM-4.7 returns error 1213 "The prompt parameter was
not received normally" when the Write tool returns empty content.
This error causes the API request to fail and halts the conversation
flow, even though the file write itself succeeds.

Note: The Claude Code CLI works fine - this issue is specific to the ACP
integration.

## Solution
Return a confirmation message from the Write tool, aligning it with
Read, Edit, and Bash tools which all return content.

## Changes
- Write tool now returns `content: [{type: "text", text: "Wrote file:
${input.file_path}"}]`

This change only adds a confirmation message - no existing functionality
is modified.

## Testing
Tested with Zed editor. Would appreciate others verifying it works as
expected.

Relates to zed-industries/zed#45704

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-01-19 15:27:32 +01:00
Charles Covey-Brandt
8366864daf Exclude tests from published package (#248)
## Summary
- Add `!dist/tests/` to package.json files array to prevent test files
from being included in npm package
- Add `.claude/*.local.*` to .gitignore for local config files

## Test plan
- [x] Verified with `npm pack --dry-run` that dist/tests/ is excluded
from package

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 17:33:43 +01:00
Ben Brandt
5917529f0d Prep 0.13.1 release (#246) 2026-01-15 21:10:52 +00:00
Ben Brandt
2597775ef0 Disable AskUserQuestion for now (#245)
This is a cool tool. But we don't have a great way to express it over
ACP at the moment.

Using RequestPermission _kind of_ works. But it conflates question
asking with a very security focused flow, which has problems as well.

Rather than have strange tool output, we'll just turn it off for now.
2026-01-15 22:03:09 +01:00
Charles Covey-Brandt
6572fcf978 Add TypeScript declaration files and integration tests (#237)
## Summary

- Enable TypeScript declaration file generation (`.d.ts` and
`.d.ts.map`)
- Add `types` field and proper `exports` configuration to package.json
- Add comprehensive integration test that verifies the full packaging
flow

## Changes

### Build Configuration
- **tsconfig.json**: Added `declaration: true` and `declarationMap:
true`
- **package.json**: Added `types` field and `exports` field with:
  - Main entry point with proper `types` and `import` conditions
- Wildcard `"./*": "./*"` to preserve backwards compatibility for deep
imports

### Integration Test
The new test at `src/tests/typescript-declarations.test.ts` validates:
- **Full packaging flow**: build → npm pack → install tarball →
type-check
- **Main exports**: All primary exports type-check correctly
- **Deep imports**: Backwards compatibility for `dist/*.js` imports
- **Type shapes**: Classes, interfaces, and function signatures match
expected types
- **Generic types**: Pushable<T> works correctly with type parameters
- **Invalid types**: TypeScript correctly rejects incorrect usage

The test creates temporary TypeScript projects, installs the actual
`.tgz` package, and runs `tsc --noEmit` to verify type-checking passes.

## Test plan
- [x] `npm run build` generates `.d.ts` and `.d.ts.map` files in `dist/`
- [x] All 8 integration tests pass: `npm run test:integration --
typescript-declarations`
- [x] Main exports type-check correctly
- [x] Deep imports continue to work (no breaking change)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 21:16:07 +01:00
Ben Brandt
5586ae0d2c Better error handling in custom MCP tools (#243)
Closes #229
2026-01-15 13:33:16 +01:00
Pointless
39ab0c248f Add MAX_THINKING_TOKENS env support and fix file-read-info format (#226)
PR for awareness and discussion.

1) claude-code-acp doesn't currently support configuring
"maxThinkingTokens"
(https://platform.claude.com/docs/en/agent-sdk/typescript) nor is it
configured in the query. Result, at least for me, is that agent thinking
chunks are never flowing through the chain. I added environment support
to my ACP host, added env variable to query init for maxThinkingTokens
following the pyton sdk env "MAX_THINKING_TOKENS". Result is now agent
thinking chunks DO flow. And I can see Claude reason. Before, no chunks
ever. This is perhaps based on configuration that Claude Agent SDK reads
but could be made more flexibel. Such as this suggestions.

2) Fix file-read-info message: was showing nonsensical range format
'Read lines 160-40', now shows 'Read 40 lines starting at line 160'. The
way this was written was confusing for myself and for Claude. If the
file-read-info is supposed to give information, then lines like "Read
lines 160-40" says absolutely nothing.

Reproduce:

Configure your ACP host to parse thinking tokens with no other external
configuration. Claude will not send any.
Enable maxThinkingTokens in ACP and set it to something like 8096. Try
your ACP implementation again, Claude now sends thinking chunks.

Bugs:

Anthropic has a meta issue. Don't talk about the "thinking" tag with
Claude. It will break output regardless of what client you use. (even on
Claude Code CLI)

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-01-15 12:21:35 +00:00
Ben Brandt
72a9cde888 Update to claude-agent-sdk 0.2.7 (#242) 2026-01-15 13:05:23 +01:00
33 changed files with 14025 additions and 4996 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: "daily"
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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: latest
node-version: "lts/*"
cache: "npm"
- name: Install dependencies

View File

@@ -1,19 +1,52 @@
name: Publish Package to npmjs
name: Publish and Release
on:
push:
tags:
- "v*.*.*"
branches:
- main
jobs:
publish-npm:
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@bcd2ba49218906704ab6c1aa796996da409d3eb1
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@45996ed1f6d02564a971a2fa1b5860e934307cf7
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 }}
publish-npm:
name: Publish to npm
runs-on: ubuntu-latest
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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
@@ -22,13 +55,3 @@ jobs:
- run: npm ci
- run: npm run build
- run: npm publish
release:
runs-on: ubuntu-latest
needs: [publish-npm]
permissions:
contents: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- name: Create Release
id: create_release
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
node_modules
dist
.DS_Store
.claude/*.local.*
CLAUDE.local.md

7
.prettierignore Normal file
View File

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

View File

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

View File

@@ -1,5 +1,410 @@
# Changelog
## [0.37.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.36.1...v0.37.0) (2026-05-21)
### Features
* add 'Default' option to effort level config ([#701](https://github.com/agentclientprotocol/claude-agent-acp/issues/701)) ([9e259d1](https://github.com/agentclientprotocol/claude-agent-acp/commit/9e259d128aa58dbb8107e53362781ca4e8ee071e))
* **deps:** bump the claude-agent-sdk to 0.3.146 ([#700](https://github.com/agentclientprotocol/claude-agent-acp/issues/700)) ([72875b2](https://github.com/agentclientprotocol/claude-agent-acp/commit/72875b248c7b90a89638de2f1709eec9e2153e7e))
* **deps:** bump the minor group with 13 updates ([#689](https://github.com/agentclientprotocol/claude-agent-acp/issues/689)) ([f66bc31](https://github.com/agentclientprotocol/claude-agent-acp/commit/f66bc31ae4bea73b48eeeb7f1db90c7d69cc0dac))
* Emit tool calls for memory recall events ([#703](https://github.com/agentclientprotocol/claude-agent-acp/issues/703)) ([a0bfb98](https://github.com/agentclientprotocol/claude-agent-acp/commit/a0bfb98ba73eaf37e9c071e886c054f90a5d5629)), closes [#650](https://github.com/agentclientprotocol/claude-agent-acp/issues/650)
### Bug Fixes
* Avoid cross-version model alias matches ([#702](https://github.com/agentclientprotocol/claude-agent-acp/issues/702)) ([e1e1c69](https://github.com/agentclientprotocol/claude-agent-acp/commit/e1e1c69029ef08579c841e6fbdffb32a5b94df06))
* Avoid redundant initial model sync ([#704](https://github.com/agentclientprotocol/claude-agent-acp/issues/704)) ([b275f6f](https://github.com/agentclientprotocol/claude-agent-acp/commit/b275f6ff7f0f2e21adedbd8e63a6fc3d63cbbb8d)), closes [#646](https://github.com/agentclientprotocol/claude-agent-acp/issues/646)
* Don't expose /clear in commands ([#705](https://github.com/agentclientprotocol/claude-agent-acp/issues/705)) ([cfce130](https://github.com/agentclientprotocol/claude-agent-acp/commit/cfce1307076e93f43a3ed8cc0134f9bb14a0f2d6))
* emit "cancelled" instead of "end_turn" when the session was interrupted. ([#694](https://github.com/agentclientprotocol/claude-agent-acp/issues/694)) ([2414a6f](https://github.com/agentclientprotocol/claude-agent-acp/commit/2414a6f98bec5bf50f3a13af528aa38d5a0fc974))
* Recover prompt stream after a failed turn ([#706](https://github.com/agentclientprotocol/claude-agent-acp/issues/706)) ([2711f50](https://github.com/agentclientprotocol/claude-agent-acp/commit/2711f506d5799f0ae25160de311a4459ffb46c49)), closes [#654](https://github.com/agentclientprotocol/claude-agent-acp/issues/654)
## [0.36.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.36.0...v0.36.1) (2026-05-18)
### Bug Fixes
* flaky authentication bypass for gateway ([#686](https://github.com/agentclientprotocol/claude-agent-acp/issues/686)) ([db852dc](https://github.com/agentclientprotocol/claude-agent-acp/commit/db852dcf7c8e3b461fabb1bdcf0c80a27d1da77d))
## [0.36.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.35.0...v0.36.0) (2026-05-18)
### Features
* Add experimental session delete support ([#682](https://github.com/agentclientprotocol/claude-agent-acp/issues/682)) ([2162d5a](https://github.com/agentclientprotocol/claude-agent-acp/commit/2162d5af62d493a82381bd88bc8fc67d376e358b))
* Support experimental additionalDirectories field ([#684](https://github.com/agentclientprotocol/claude-agent-acp/issues/684)) ([f37e9a0](https://github.com/agentclientprotocol/claude-agent-acp/commit/f37e9a0d47d8d201d98b2177083664a6781895cc))
## [0.35.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.34.1...v0.35.0) (2026-05-16)
### Features
* **deps:** bump actions/create-github-app-token from 3.1.1 to 3.2.0 ([#669](https://github.com/agentclientprotocol/claude-agent-acp/issues/669)) ([47df1f2](https://github.com/agentclientprotocol/claude-agent-acp/commit/47df1f2a0be57ddb8873ae8e341f748471c7bc53))
* **deps:** bump hono from 4.12.18 to 4.12.19 in the minor group ([#671](https://github.com/agentclientprotocol/claude-agent-acp/issues/671)) ([5d7165d](https://github.com/agentclientprotocol/claude-agent-acp/commit/5d7165d96158da2ddf3087676cdb0a19d1ff57aa))
* **deps:** update to claude-agent-sdk 0.3.143 ([#664](https://github.com/agentclientprotocol/claude-agent-acp/issues/664)) ([27ca2e5](https://github.com/agentclientprotocol/claude-agent-acp/commit/27ca2e5d40917887671cc4c39a854fd8f92c01e6))
* Use SDK settings resolution for defaults ([#677](https://github.com/agentclientprotocol/claude-agent-acp/issues/677)) ([eb1259c](https://github.com/agentclientprotocol/claude-agent-acp/commit/eb1259cf88375ca3c20a219ab99f12f5488fb360))
### Bug Fixes
* Add task hooks for plan state updates ([#676](https://github.com/agentclientprotocol/claude-agent-acp/issues/676)) ([5ff7d50](https://github.com/agentclientprotocol/claude-agent-acp/commit/5ff7d50f0ec7f34a7d9d901223aed73e2dbcce68))
* render local-command-stdout messages instead of dropping them ([#649](https://github.com/agentclientprotocol/claude-agent-acp/issues/649)) ([3b9b7d5](https://github.com/agentclientprotocol/claude-agent-acp/commit/3b9b7d5a56defd925eb2038fa97b6484ad951587))
## [0.34.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.34.0...v0.34.1) (2026-05-16)
### Bug Fixes
* load credential error for bedrock gateway ([#667](https://github.com/agentclientprotocol/claude-agent-acp/issues/667)) ([8d76be3](https://github.com/agentclientprotocol/claude-agent-acp/commit/8d76be356a3e74c58a7c93c3c201cca6a317d784))
## [0.34.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.33.1...v0.34.0) (2026-05-15)
### Features
* add bedrock gateway authentication ([#665](https://github.com/agentclientprotocol/claude-agent-acp/issues/665)) ([002c63a](https://github.com/agentclientprotocol/claude-agent-acp/commit/002c63a78b844c168d3dfc744cf408362a6adf97))
## [0.33.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.33.0...v0.33.1) (2026-05-07)
### Bug Fixes
* Honor availableModels settings allowlist ([#637](https://github.com/agentclientprotocol/claude-agent-acp/issues/637)) ([867a3a0](https://github.com/agentclientprotocol/claude-agent-acp/commit/867a3a0de2a050592d79aa76d7dd3dd5b478162d)), closes [#620](https://github.com/agentclientprotocol/claude-agent-acp/issues/620)
## [0.33.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.32.0...v0.33.0) (2026-05-07)
### Features
* **deps:** bump the minor group with 14 updates ([#631](https://github.com/agentclientprotocol/claude-agent-acp/issues/631)) ([8b43ee8](https://github.com/agentclientprotocol/claude-agent-acp/commit/8b43ee813f05f5087a213a7f42154e39d6bc4a5a))
* **deps:** Update to claude-agent-sdk 0.2.132 ([#636](https://github.com/agentclientprotocol/claude-agent-acp/issues/636)) ([0c8ff27](https://github.com/agentclientprotocol/claude-agent-acp/commit/0c8ff277f2af8d3085cc1b5cf33891630dede0b1))
### Bug Fixes
* Handle result origins in ACP agent ([#627](https://github.com/agentclientprotocol/claude-agent-acp/issues/627)) ([dba1998](https://github.com/agentclientprotocol/claude-agent-acp/commit/dba199839a25ba405f04b9d4409e647150fe0290))
## [0.32.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.4...v0.32.0) (2026-05-03)
### Features
* **deps-dev:** Bump nanoid from 3.3.11 to 3.3.12 ([#622](https://github.com/agentclientprotocol/claude-agent-acp/issues/622)) ([c78ac62](https://github.com/agentclientprotocol/claude-agent-acp/commit/c78ac62d05283e5683b87b198923818f9f556a03))
* **deps:** Bump the minor group with 2 updates ([#619](https://github.com/agentclientprotocol/claude-agent-acp/issues/619)) ([6ccd37c](https://github.com/agentclientprotocol/claude-agent-acp/commit/6ccd37ce947fbd55691f676344b15ef1266191ad))
* **deps:** update to @anthropic-ai/claude-agent-sdk 0.2.126 ([#621](https://github.com/agentclientprotocol/claude-agent-acp/issues/621)) ([becc3b8](https://github.com/agentclientprotocol/claude-agent-acp/commit/becc3b86e60eb33e7823a0ef27d5aa99758750d7))
* **deps:** Update to @anthropic-ai/claude-agent-sdk@0.2.123 ([#614](https://github.com/agentclientprotocol/claude-agent-acp/issues/614)) ([5b93119](https://github.com/agentclientprotocol/claude-agent-acp/commit/5b9311938d97f47400debd66f2b4792e50639c6b))
### Bug Fixes
* emit a real diff when Write overwrites an existing file ([#618](https://github.com/agentclientprotocol/claude-agent-acp/issues/618)) ([8d7e220](https://github.com/agentclientprotocol/claude-agent-acp/commit/8d7e22026e15d54208414bd9ad128eb86d41b451))
## [0.31.4](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.3...v0.31.4) (2026-04-28)
### Bug Fixes
* gate auto mode on model support ([#604](https://github.com/agentclientprotocol/claude-agent-acp/issues/604)) ([ec47d34](https://github.com/agentclientprotocol/claude-agent-acp/commit/ec47d3446fa22e5895621f57c0a4497dbe044505))
## [0.31.3](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.2...v0.31.3) (2026-04-28)
### Bug Fixes
* Rename effort config category to thought_level ([#609](https://github.com/agentclientprotocol/claude-agent-acp/issues/609)) ([76b4e96](https://github.com/agentclientprotocol/claude-agent-acp/commit/76b4e9650832e59a6b4915ad898fc66a065022fa))
## [0.31.2](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.1...v0.31.2) (2026-04-28)
### Bug Fixes
* tolerate invalid values in settings.json ([#601](https://github.com/agentclientprotocol/claude-agent-acp/issues/601)) ([67af018](https://github.com/agentclientprotocol/claude-agent-acp/commit/67af018d0216238d8f3cd5bad04a55200518239b))
## [0.31.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.0...v0.31.1) (2026-04-27)
### Bug Fixes
* detect glibc and use correct binary ([#599](https://github.com/agentclientprotocol/claude-agent-acp/issues/599)) ([f0801d5](https://github.com/agentclientprotocol/claude-agent-acp/commit/f0801d50b2390a3c48150b9b8507d30a70c18b84))
## [0.31.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.30.0...v0.31.0) (2026-04-24)
### Features
* allow configuring models through env vars ([#586](https://github.com/agentclientprotocol/claude-agent-acp/issues/586)) ([1e15f3d](https://github.com/agentclientprotocol/claude-agent-acp/commit/1e15f3d8b0a06076ee62764ab576ac29fe056a38))
* Support effort levels ([#464](https://github.com/agentclientprotocol/claude-agent-acp/issues/464)) ([9e1185b](https://github.com/agentclientprotocol/claude-agent-acp/commit/9e1185bfd55cbf83a653a0ff8c194f986cbd1574))
* Update to acp sdk v0.20 ([#589](https://github.com/agentclientprotocol/claude-agent-acp/issues/589)) ([92adcbd](https://github.com/agentclientprotocol/claude-agent-acp/commit/92adcbd1ace2f2103742ffcf5c589eb1ca41b9b8))
* Update to claude-agent-sdk 0.2.119 ([#587](https://github.com/agentclientprotocol/claude-agent-acp/issues/587)) ([ef1dbd1](https://github.com/agentclientprotocol/claude-agent-acp/commit/ef1dbd1cb457f0524d221ea07235abf49dc941a0))
### Bug Fixes
* Forward full systemPrompt preset options from _meta ([#591](https://github.com/agentclientprotocol/claude-agent-acp/issues/591)) ([b3ddfc3](https://github.com/agentclientprotocol/claude-agent-acp/commit/b3ddfc3b86703c23fe99d93611885c12b1e4812c))
* Session Replay and Permission rendering ([#593](https://github.com/agentclientprotocol/claude-agent-acp/issues/593)) ([5faefab](https://github.com/agentclientprotocol/claude-agent-acp/commit/5faefab8ab9b725f7a3374808bf5579e411884bc)), closes [#579](https://github.com/agentclientprotocol/claude-agent-acp/issues/579)
## [0.30.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.29.2...v0.30.0) (2026-04-20)
### Features
* Update to claude-agent-sdk 0.2.114 ([#572](https://github.com/agentclientprotocol/claude-agent-acp/issues/572)) ([e9dd452](https://github.com/agentclientprotocol/claude-agent-acp/commit/e9dd45207d396302f20de82561135bf9558c0e76))
## [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
## 0.22.0
- Use stable list sessions method (#429)
- Use correct Claude CLI path for static binaries (#428)
- Update claude-agent-sdk to 0.2.76 (#427)
- fix: resolve model aliases in setSessionConfigOption (#401) (#403)
- Reuse existing sessions for load/resume if possible (#426)
- Remove interrupt flag from deny responses (#425)
- Allow Bypass permissions mode after Exiting plan (#410)
- Don't get out of sync when background task creates new init/result (try 2) (#400)
- Add session/close support (#409)
## 0.21.0
- Update to claude-agent-sdk 0.2.71
- show project-relative paths in tool call titles
- Lib: pass through tools array to control built-in tool availability
- fix: skip user replay
- fix: handle renamed Agent tool in toolInfoFromToolUse
## 0.20.2
- Update to @anthropic-ai/claude-agent-sdk@0.2.68
## 0.20.1
- fix: inherit process.env when spawning agent subprocess
## 0.20.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.63
- Respect user settings for permission mode and model selection
- Better handling of concurrent prompts
- Support --cli for node as well
- Propagate max_tokens stop reason instead of throwing internal error
- fix: throw resourceNotFound when loadSession fails to resume
- fix: add missing zod dependency
- Surface better error message when Claude Code process exits unexpectedly
## 0.19.2
- Fix for broken notifications when reloading session messages
## 0.19.1
- Support windows arm builds and clean up artifact files
## 0.19.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.62
- Use SDK functions for listing and loading session history
- Build single-file executables using bun.
- Fix for overwritten disallowed tools.
## 0.18.0
- Switch over to built-in Claude tools. We no longer replicate specific ACP tools and just rely on sending updates based on Claude's internal tools. This means it won't use client capabilities for files or terminals, but also means there will be less difference and hopefully issues arising from the differences in behavior.
- Support ACP session config options: https://agentclientprotocol.com/protocol/session-config-options
- Fix for image output from tool calls.
## 0.17.1
- Update to @anthropic-ai/claude-agent-sdk@0.2.45 to add access to Sonnet 4.6
## 0.17.0
Rename from `@zed-industries/claude-code-acp` to `@zed-industries/claude-agent-acp` to align with the current [branding guidelines](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines)
## 0.16.2
- Update to @anthropic-ai/claude-agent-sdk@0.2.44
- fix: Replace all non-alphanumeric characters for session loading in encodeProjectPath (#307)
- don't include /login slash command in login command (#315)
## 0.16.1
- Update to @anthropic-ai/claude-agent-sdk@0.2.38
- Fix incorrect paths for session/list
- Fix available commands after loading a session
- Make loading session more permissive for finding events
- Fix overriding user-provided disallowedTools
## 0.16.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.34
- Experimental support for session loading
## 0.15.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.32 (adds support for Opus 4.6 and 1M context Opus)
## 0.14.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.29
- Update to using the recommended `CLAUDE_CONFIG_DIR` env variable for setting where config files are kept
- Support /context command
- Fix incorrect context type mapping for tool calls
- Fix glob metching for file permissions on Windows
- Support the `IS_SANDBOX` env var for supporting bypass permissions in root mode
- Fix missing notification for entering plan mode
- Experimental unstable support for listing sessions
## 0.13.2
- Update to @anthropic-ai/claude-agent-sdk@0.2.22
- Fix: return content from ACP write tool to help with issues with alternate providers.
## 0.13.1
- Update to @anthropic-ai/claude-agent-sdk@0.2.7
- Add TypeScript declaration files for library users
- Fixed error handling in custom ACP focused MCP tools
## 0.13.0
- Update to @anthropic-ai/claude-agent-sdk@0.2.6

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 Claude Code
# ACP adapter for the Claude Agent SDK
[![npm](https://img.shields.io/npm/v/%40zed-industries%2Fclaude-code-acp)](https://www.npmjs.com/package/@zed-industries/claude-code-acp)
[![npm](https://img.shields.io/npm/v/%40agentclientprotocol%2Fclaude-agent-acp)](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp)
Use [Claude Code](https://www.anthropic.com/claude-code) from [ACP-compatible](https://agentclientprotocol.com) clients such as [Zed](https://zed.dev)!
Use [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines) from [ACP-compatible](https://agentclientprotocol.com) clients!
This tool implements an ACP agent by using the official [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), supporting:
@@ -18,36 +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 Code, open the Agent Panel and click "New Claude Code 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-code-acp
```
You can then use `claude-code-acp` as a regular ACP agent:
```
ANTHROPIC_API_KEY=sk-... claude-code-acp
```
## 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).

View File

@@ -0,0 +1,56 @@
# Model Configuration
When using claude-agent-acp with alternative providers (e.g. AWS Bedrock), model IDs differ from the direct Anthropic API. The `CLAUDE_MODEL_CONFIG` environment variable lets you configure model overrides and availability at the deployment level.
## `CLAUDE_MODEL_CONFIG`
A JSON string with two optional fields:
| Field | Type | Description |
| ----------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `modelOverrides` | `Record<string, string>` | Maps Anthropic model IDs to provider-specific model IDs (e.g. Bedrock model IDs or ARNs) |
| `availableModels` | `string[]` | Restricts which models are offered to users. Accepts aliases (`"opus"`), prefixes (`"opus-4-5"`), or full IDs |
### Examples
**Bedrock model overrides:**
```bash
CLAUDE_MODEL_CONFIG='{"modelOverrides":{"claude-opus-4-6":"us.anthropic.claude-opus-4-6-v1","claude-sonnet-4-5":"us.anthropic.claude-sonnet-4-5-v1"}}'
```
**Restrict available models:**
```bash
CLAUDE_MODEL_CONFIG='{"availableModels":["opus","sonnet"]}'
```
**Both together:**
```bash
CLAUDE_MODEL_CONFIG='{"modelOverrides":{"claude-opus-4-6":"us.anthropic.claude-opus-4-6-v1","claude-sonnet-4-5":"us.anthropic.claude-sonnet-4-5-v1"},"availableModels":["opus","sonnet"]}'
```
**Full Bedrock example:**
```bash
CLAUDE_CODE_USE_BEDROCK=1 \
AWS_REGION=us-west-2 \
CLAUDE_MODEL_CONFIG='{"modelOverrides":{"claude-opus-4-6":"us.anthropic.claude-opus-4-6-v1"}}' \
node dist/index.js
```
## Precedence
When an ACP caller provides `settings` via `_meta.claudeCode.options.settings` in the `sessions/create` request, `CLAUDE_MODEL_CONFIG` is ignored entirely. The env var is a deployment-level fallback for cases where the caller does not configure model settings itself.
| Source | Priority |
| -------------------------------------------- | ----------------------------------------------------- |
| `_meta.claudeCode.options.settings` (caller) | Highest — used if present |
| `CLAUDE_MODEL_CONFIG` (env var) | Fallback — used only when caller provides no settings |
## Format details
- The value must be valid JSON. Invalid JSON will cause session creation to fail with a parse error.
- Only `modelOverrides` and `availableModels` keys are read; other keys in the JSON are ignored.
- Both fields map directly to the Claude Agent SDK's `Settings` type.

2939
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,26 @@
{
"name": "@zed-industries/claude-code-acp",
"name": "@agentclientprotocol/claude-agent-acp",
"publishConfig": {
"access": "public"
},
"version": "0.13.0",
"description": "An ACP-compatible coding agent powered by the Claude Code SDK (TypeScript)",
"version": "0.37.0",
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
"main": "dist/lib.js",
"types": "dist/lib.d.ts",
"bin": {
"claude-code-acp": "./dist/index.js"
"claude-agent-acp": "dist/index.js"
},
"type": "module",
"exports": {
".": {
"types": "./dist/lib.d.ts",
"import": "./dist/lib.js"
},
"./*": "./*"
},
"files": [
"dist/",
"!dist/tests/",
"README.md",
"LICENSE",
"package.json"
@@ -40,34 +49,33 @@
"sdk",
"code"
],
"homepage": "https://github.com/zed-industries/claude-code-acp#readme",
"homepage": "https://github.com/agentclientprotocol/claude-agent-acp#readme",
"bugs": {
"url": "https://github.com/zed-industries/claude-code-acp/issues"
"url": "https://github.com/agentclientprotocol/claude-agent-acp/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zed-industries/claude-code-acp.git"
"url": "git+https://github.com/agentclientprotocol/claude-agent-acp.git"
},
"author": "Zed Industries",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "0.13.0",
"@anthropic-ai/claude-agent-sdk": "0.2.6",
"@modelcontextprotocol/sdk": "1.25.2",
"diff": "8.0.3",
"minimatch": "10.1.1"
"@agentclientprotocol/sdk": "0.22.1",
"@anthropic-ai/claude-agent-sdk": "0.3.146",
"zod": "^3.25.0 || ^4.0.0"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.71.2",
"@types/node": "25.0.7",
"@typescript-eslint/eslint-plugin": "8.53.0",
"@typescript-eslint/parser": "8.53.0",
"eslint": "9.39.2",
"@anthropic-ai/sdk": "0.97.1",
"@eslint/js": "10.0.1",
"@types/node": "25.9.1",
"@typescript-eslint/eslint-plugin": "8.59.4",
"@typescript-eslint/parser": "8.59.4",
"eslint": "10.4.0",
"eslint-config-prettier": "10.1.8",
"globals": "17.0.0",
"prettier": "3.7.4",
"globals": "17.6.0",
"prettier": "3.8.3",
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vitest": "4.0.17"
"typescript": "6.0.3",
"vitest": "4.1.7"
}
}

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"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,76 @@
#!/usr/bin/env node
// Load managed settings and apply environment variables
import { loadManagedSettings, applyEnvironmentSettings } from "./utils.js";
import { resolveSettings } from "@anthropic-ai/claude-agent-sdk";
import { claudeCliPath, runAcp } from "./acp-agent.js";
const managedSettings = loadManagedSettings();
if (managedSettings) {
applyEnvironmentSettings(managedSettings);
if (process.argv.includes("--cli")) {
const { spawn } = await import("node:child_process");
const args = process.argv.slice(2).filter((arg) => arg !== "--cli");
const child = spawn(await claudeCliPath(), args, { stdio: "inherit" });
const signals =
process.platform === "win32"
? (["SIGINT", "SIGTERM"] as const)
: (["SIGINT", "SIGTERM", "SIGHUP"] as const);
for (const sig of signals) {
process.on(sig, () => {
if (!child.killed) child.kill(sig);
});
}
child.on("exit", (code, signal) => {
if (signal && process.platform !== "win32") {
// Remove our listener so re-raising actually terminates instead of
// re-entering the no-op handler, which would let us exit with code 0
// instead of the signal's conventional 128+N.
process.removeAllListeners(signal);
process.kill(process.pid, signal);
} else {
process.exit(code ?? 1);
}
});
child.on("error", (err) => {
console.error(err);
process.exit(1);
});
} else {
// Apply env vars from the managed-policy tier before any SDK call so the
// SDK subprocess inherits them. Going through resolveSettings (vs. a raw
// read of managed-settings.json) also picks up MDM sources on macOS and
// HKLM/HKCU on Windows.
const policy = await resolveSettings({ settingSources: [] });
for (const [key, value] of Object.entries(policy.effective.env ?? {})) {
process.env[key] = value;
}
// stdout is used to send messages to the client
// we redirect everything else to stderr to make sure it doesn't interfere with ACP
console.log = console.error;
console.info = console.error;
console.warn = console.error;
console.debug = console.error;
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
});
const { connection, agent } = runAcp();
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();
}
// stdout is used to send messages to the client
// we redirect everything else to stderr to make sure it doesn't interfere with ACP
console.log = console.error;
console.info = console.error;
console.warn = console.error;
console.debug = console.error;
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
});
import { runAcp } from "./acp-agent.js";
runAcp();
// Keep process alive
process.stdin.resume();

View File

@@ -1,36 +1,23 @@
// Export the main agent class and utilities for library usage
export {
ClaudeAcpAgent,
isLocalCommandMetadata,
stripLocalCommandMetadata,
runAcp,
toAcpNotifications,
streamEventToAcpNotifications,
type ToolUpdateMeta,
type NewSessionMeta,
type SDKMessageFilter,
} from "./acp-agent.js";
export {
loadManagedSettings,
applyEnvironmentSettings,
nodeToWebReadable,
nodeToWebWritable,
Pushable,
unreachable,
} from "./utils.js";
export { createMcpServer } from "./mcp-server.js";
export { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
export {
toolInfoFromToolUse,
toDisplayPath,
planEntries,
toolUpdateFromToolResult,
createPreToolUseHook,
acpToolNames as toolNames,
} from "./tools.js";
export {
SettingsManager,
type ClaudeCodeSettings,
type PermissionSettings,
type PermissionDecision,
type PermissionCheckResult,
type SettingsManagerOptions,
} from "./settings.js";
export { SettingsManager, type SettingsManagerOptions } from "./settings.js";
// Export types
export type { ClaudePlanEntry } from "./tools.js";

View File

@@ -1,806 +0,0 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {
BashInput,
FileEditInput,
FileReadInput,
FileWriteInput,
KillShellInput,
} from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
import { z } from "zod";
import { CLAUDE_CONFIG_DIR, ClaudeAcpAgent } from "./acp-agent.js";
import {
ClientCapabilities,
ReadTextFileResponse,
TerminalOutputResponse,
} from "@agentclientprotocol/sdk";
import * as diff from "diff";
import * as path from "node:path";
import * as fs from "node:fs/promises";
import { sleep, unreachable, extractLinesWithByteLimit } from "./utils.js";
import { acpToolNames } from "./tools.js";
export const SYSTEM_REMINDER = `
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>`;
const defaults = { maxFileSize: 50000, linesToRead: 2000 };
const unqualifiedToolNames = {
read: "Read",
edit: "Edit",
write: "Write",
bash: "Bash",
killShell: "KillShell",
bashOutput: "BashOutput",
};
export function createMcpServer(
agent: ClaudeAcpAgent,
sessionId: string,
clientCapabilities: ClientCapabilities | undefined,
): McpServer {
/**
* This checks if a given path is related to internal agent persistence and if the agent should be allowed to read/write from here.
* We let the agent do normal fs operations on these paths so that it can persist its state.
* However, we block access to settings files for security reasons.
*/
function internalPath(file_path: string) {
return (
file_path.startsWith(CLAUDE_CONFIG_DIR) &&
!file_path.startsWith(path.join(CLAUDE_CONFIG_DIR, "settings.json")) &&
!file_path.startsWith(path.join(CLAUDE_CONFIG_DIR, "session-env"))
);
}
async function readTextFile(input: FileReadInput): Promise<ReadTextFileResponse> {
if (internalPath(input.file_path)) {
const content = await fs.readFile(input.file_path, "utf8");
// eslint-disable-next-line eqeqeq
if (input.offset != null || input.limit != null) {
const lines = content.split("\n");
// Apply offset and limit if provided
const offset = input.offset ?? 1;
const limit = input.limit ?? lines.length;
// Extract the requested lines (offset is 1-based)
const startIndex = Math.max(0, offset - 1);
const endIndex = Math.min(lines.length, startIndex + limit);
const selectedLines = lines.slice(startIndex, endIndex);
return { content: selectedLines.join("\n") };
} else {
return { content };
}
}
return agent.readTextFile({
sessionId,
path: input.file_path,
line: input.offset,
limit: input.limit,
});
}
async function writeTextFile(input: FileWriteInput): Promise<void> {
if (internalPath(input.file_path)) {
await fs.writeFile(input.file_path, input.content, "utf8");
} else {
await agent.writeTextFile({
sessionId,
path: input.file_path,
content: input.content,
});
}
}
// Create MCP server
const server = new McpServer({ name: "acp", version: "1.0.0" }, { capabilities: { tools: {} } });
if (clientCapabilities?.fs?.readTextFile) {
server.registerTool(
unqualifiedToolNames.read,
{
title: unqualifiedToolNames.read,
description: `Reads the content of the given file in the project.
In sessions with ${acpToolNames.read} always use it instead of Read as it contains the most up-to-date contents.
Reads a file from the local filesystem. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.
Usage:
- The file_path parameter must be an absolute path, not a relative path
- By default, it reads up to ${defaults.linesToRead} lines starting from the beginning of the file
- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters
- Any files larger than ${defaults.maxFileSize} bytes will be truncated
- This tool allows Claude Code to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Claude Code is a multimodal LLM.
- This tool can only read files, not directories. To read a directory, use an ls command via the ${acpToolNames.bash} tool.
- You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.`,
inputSchema: {
file_path: z.string().describe("The absolute path to the file to read"),
offset: z
.number()
.optional()
.default(1)
.describe(
"The line number to start reading from. Only provide if the file is too large to read at once",
),
limit: z
.number()
.optional()
.default(defaults.linesToRead)
.describe(
`The number of lines to read. Only provide if the file is too large to read at once.`,
),
},
annotations: {
title: "Read file",
readOnlyHint: true,
destructiveHint: false,
openWorldHint: false,
idempotentHint: false,
},
},
async (input: FileReadInput) => {
try {
const session = agent.sessions[sessionId];
if (!session) {
return {
content: [
{
type: "text",
text: "The user has left the building",
},
],
};
}
const readResponse = await readTextFile(input);
if (typeof readResponse?.content !== "string") {
throw new Error(`No file contents for ${input.file_path}.`);
}
// Extract lines with byte limit enforcement
const result = extractLinesWithByteLimit(readResponse.content, defaults.maxFileSize);
// Construct informative message about what was read
let readInfo = "";
if ((input.offset && input.offset > 1) || result.wasLimited) {
readInfo = "\n\n<file-read-info>";
if (result.wasLimited) {
readInfo += `Read ${result.linesRead} lines (hit 50KB limit). `;
} else {
readInfo += `Read lines ${input.offset}-${result.linesRead}. `;
}
if (result.wasLimited) {
readInfo += `Continue with offset=${result.linesRead}.`;
}
readInfo += "</file-read-info>";
}
return {
content: [
{
type: "text",
text: result.content + readInfo + SYSTEM_REMINDER,
},
],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: "Reading file failed: " + error.message,
},
],
};
}
},
);
}
if (clientCapabilities?.fs?.writeTextFile) {
server.registerTool(
unqualifiedToolNames.write,
{
title: unqualifiedToolNames.write,
description: `Writes a file to the local filesystem..
In sessions with ${acpToolNames.write} always use it instead of Write as it will
allow the user to conveniently review changes.
Usage:
- This tool will overwrite the existing file if there is one at the provided path.
- If this is an existing file, you MUST use the ${acpToolNames.read} tool first to read the file's contents. This tool will fail if you did not read the file first.
- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`,
inputSchema: {
file_path: z
.string()
.describe("The absolute path to the file to write (must be absolute, not relative)"),
content: z.string().describe("The content to write to the file"),
},
annotations: {
title: "Write file",
readOnlyHint: false,
destructiveHint: false,
openWorldHint: false,
idempotentHint: false,
},
},
async (input: FileWriteInput) => {
try {
const session = agent.sessions[sessionId];
if (!session) {
return {
content: [
{
type: "text",
text: "The user has left the building",
},
],
};
}
await writeTextFile(input);
return {
content: [],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: "Writing file failed: " + error.message,
},
],
};
}
},
);
server.registerTool(
unqualifiedToolNames.edit,
{
title: unqualifiedToolNames.edit,
description: `Performs exact string replacements in files.
In sessions with ${acpToolNames.edit} always use it instead of Edit as it will
allow the user to conveniently review changes.
Usage:
- You must use your \`${acpToolNames.read}\` tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.
- When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears.
- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
- Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.
- The edit will FAIL if \`old_string\` is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use \`replace_all\` to change every instance of \`old_string\`.
- Use \`replace_all\` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.`,
inputSchema: {
file_path: z.string().describe("The absolute path to the file to modify"),
old_string: z.string().describe("The text to replace"),
new_string: z
.string()
.describe("The text to replace it with (must be different from old_string)"),
replace_all: z
.boolean()
.default(false)
.optional()
.describe("Replace all occurrences of old_string (default false)"),
},
annotations: {
title: "Edit file",
readOnlyHint: false,
destructiveHint: false,
openWorldHint: false,
idempotentHint: false,
},
},
async (input: FileEditInput) => {
try {
const session = agent.sessions[sessionId];
if (!session) {
return {
content: [
{
type: "text",
text: "The user has left the building",
},
],
};
}
const readResponse = await readTextFile({
file_path: input.file_path,
});
if (typeof readResponse?.content !== "string") {
throw new Error(`No file contents for ${input.file_path}.`);
}
const { newContent } = replaceAndCalculateLocation(readResponse.content, [
{
oldText: input.old_string,
newText: input.new_string,
replaceAll: input.replace_all,
},
]);
const patch = diff.createPatch(input.file_path, readResponse.content, newContent);
await writeTextFile({ file_path: input.file_path, content: newContent });
return {
content: [
{
type: "text",
text: patch,
},
],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: "Editing file failed: " + (error?.message ?? String(error)),
},
],
};
}
},
);
}
if (agent.clientCapabilities?.terminal) {
server.registerTool(
unqualifiedToolNames.bash,
{
title: unqualifiedToolNames.bash,
description: `Executes a bash command
In sessions with ${acpToolNames.bash} always use it instead of Bash`,
inputSchema: {
command: z.string().describe("The command to execute"),
timeout: z.number().describe(`Optional timeout in milliseconds (max ${2 * 60 * 1000})`),
description: z.string().optional()
.describe(`Clear, concise description of what this command does in 5-10 words, in active voice. Examples:
Input: ls
Output: List files in current directory
Input: git status
Output: Show working tree status
Input: npm install
Output: Install package dependencies
Input: mkdir foo
Output: Create directory 'foo'`),
run_in_background: z
.boolean()
.default(false)
.describe(
`Set to true to run this command in the background. The tool returns an \`id\` that can be used with the \`${acpToolNames.bashOutput}\` tool to retrieve the current output, or the \`${acpToolNames.killShell}\` tool to stop it early.`,
),
},
},
async (input: BashInput, extra) => {
const session = agent.sessions[sessionId];
if (!session) {
return {
content: [
{
type: "text",
text: "The user has left the building",
},
],
};
}
const toolCallId = extra._meta?.["claudecode/toolUseId"];
if (typeof toolCallId !== "string") {
throw new Error("No tool call ID found");
}
if (!agent.clientCapabilities?.terminal || !agent.client.createTerminal) {
throw new Error("unreachable");
}
const handle = await agent.client.createTerminal({
command: input.command,
env: [{ name: "CLAUDECODE", value: "1" }],
sessionId,
outputByteLimit: 32_000,
});
await agent.client.sessionUpdate({
sessionId,
update: {
sessionUpdate: "tool_call_update",
toolCallId,
status: "in_progress",
title: input.description,
content: [{ type: "terminal", terminalId: handle.id }],
},
});
const abortPromise = new Promise((resolve) => {
if (extra.signal.aborted) {
resolve(null);
} else {
extra.signal.addEventListener("abort", () => {
resolve(null);
});
}
});
const statusPromise = Promise.race([
handle.waitForExit().then((exitStatus) => ({ status: "exited" as const, exitStatus })),
abortPromise.then(() => ({ status: "aborted" as const, exitStatus: null })),
sleep(input.timeout ?? 2 * 60 * 1000).then(async () => {
if (agent.backgroundTerminals[handle.id]?.status === "started") {
await handle.kill();
}
return { status: "timedOut" as const, exitStatus: null };
}),
]);
if (input.run_in_background) {
agent.backgroundTerminals[handle.id] = {
handle,
lastOutput: null,
status: "started",
};
statusPromise.then(async ({ status, exitStatus }) => {
const bgTerm = agent.backgroundTerminals[handle.id];
if (bgTerm.status !== "started") {
return;
}
const currentOutput = await handle.currentOutput();
agent.backgroundTerminals[handle.id] = {
status,
pendingOutput: {
...currentOutput,
output: stripCommonPrefix(bgTerm.lastOutput?.output ?? "", currentOutput.output),
exitStatus: exitStatus ?? currentOutput.exitStatus,
},
};
return handle.release();
});
return {
content: [
{
type: "text",
text: `Command started in background with id: ${handle.id}`,
},
],
};
}
await using terminal = handle;
const { status } = await statusPromise;
if (status === "aborted") {
return {
content: [{ type: "text", text: "Tool cancelled by user" }],
};
}
const output = await terminal.currentOutput();
return {
content: [{ type: "text", text: toolCommandOutput(status, output) }],
};
},
);
server.registerTool(
unqualifiedToolNames.bashOutput,
{
title: unqualifiedToolNames.bashOutput,
description: `- Retrieves output from a running or completed background bash shell
- Takes a bash_id parameter identifying the shell
- Always returns only new output since the last check
- Returns stdout and stderr output along with shell status
- Use this tool when you need to monitor or check the output of a long-running shell
In sessions with ${acpToolNames.bashOutput} always use it for output from Bash commands instead of TaskOutput.`,
inputSchema: {
bash_id: z
.string()
.describe(
`The id of the background bash command as returned by \`${acpToolNames.bash}\``,
),
},
},
async (input) => {
const bgTerm = agent.backgroundTerminals[input.bash_id];
if (!bgTerm) {
throw new Error(`Unknown shell ${input.bash_id}`);
}
if (bgTerm.status === "started") {
const newOutput = await bgTerm.handle.currentOutput();
const strippedOutput = stripCommonPrefix(
bgTerm.lastOutput?.output ?? "",
newOutput.output,
);
bgTerm.lastOutput = newOutput;
return {
content: [
{
type: "text",
text: toolCommandOutput(bgTerm.status, {
...newOutput,
output: strippedOutput,
}),
},
],
};
} else {
return {
content: [
{
type: "text",
text: toolCommandOutput(bgTerm.status, bgTerm.pendingOutput),
},
],
};
}
},
);
server.registerTool(
unqualifiedToolNames.killShell,
{
title: unqualifiedToolNames.killShell,
description: `- Kills a running background bash shell by its ID
- Takes a shell_id parameter identifying the shell to kill
- Returns a success or failure status
- Use this tool when you need to terminate a long-running shell
In sessions with ${acpToolNames.killShell} always use it instead of KillShell.`,
inputSchema: {
shell_id: z
.string()
.describe(
`The id of the background bash command as returned by \`${acpToolNames.bash}\``,
),
},
},
async (input: KillShellInput) => {
const bgTerm = agent.backgroundTerminals[input.shell_id];
if (!bgTerm) {
throw new Error(`Unknown shell ${input.shell_id}`);
}
switch (bgTerm.status) {
case "started": {
await bgTerm.handle.kill();
const currentOutput = await bgTerm.handle.currentOutput();
agent.backgroundTerminals[bgTerm.handle.id] = {
status: "killed",
pendingOutput: {
...currentOutput,
output: stripCommonPrefix(bgTerm.lastOutput?.output ?? "", currentOutput.output),
},
};
await bgTerm.handle.release();
return {
content: [{ type: "text", text: "Command killed successfully." }],
};
}
case "aborted":
return {
content: [{ type: "text", text: "Command aborted by user." }],
};
case "exited":
return {
content: [{ type: "text", text: "Command had already exited." }],
};
case "killed":
return {
content: [{ type: "text", text: "Command was already killed." }],
};
case "timedOut":
return {
content: [{ type: "text", text: "Command killed by timeout." }],
};
default: {
unreachable(bgTerm);
throw new Error("Unexpected background terminal status");
}
}
},
);
}
return server;
}
function stripCommonPrefix(a: string, b: string): string {
let i = 0;
while (i < a.length && i < b.length && a[i] === b[i]) {
i++;
}
return b.slice(i);
}
function toolCommandOutput(
status: "started" | "aborted" | "exited" | "killed" | "timedOut",
output: TerminalOutputResponse,
): string {
const { exitStatus, output: commandOutput, truncated } = output;
let toolOutput = "";
switch (status) {
case "started":
case "exited": {
if (exitStatus && (exitStatus.exitCode ?? null) === null) {
toolOutput += `Interrupted by the user. `;
}
break;
}
case "killed":
toolOutput += `Killed. `;
break;
case "timedOut":
toolOutput += `Timed out. `;
break;
case "aborted":
break;
default: {
const unreachable: never = status;
return unreachable;
}
}
if (exitStatus) {
if (typeof exitStatus.exitCode === "number") {
toolOutput += `Exited with code ${exitStatus.exitCode}.`;
}
if (typeof exitStatus.signal === "string") {
toolOutput += `Signal \`${exitStatus.signal}\`. `;
}
toolOutput += "Final output:\n\n";
} else {
toolOutput += "New output:\n\n";
}
toolOutput += commandOutput;
if (truncated) {
toolOutput += `\n\nCommand output was too long, so it was truncated to ${commandOutput.length} bytes.`;
}
return toolOutput;
}
/**
* Replace text in a file and calculate the line numbers where the edits occurred.
*
* @param fileContent - The full file content
* @param edits - Array of edit operations to apply sequentially
* @returns the new content and the line numbers where replacements occurred in the final content
*/
export function replaceAndCalculateLocation(
fileContent: string,
edits: Array<{
oldText: string;
newText: string;
replaceAll?: boolean;
}>,
): { newContent: string; lineNumbers: number[] } {
let currentContent = fileContent;
// Use unique markers to track where replacements happen
const markerPrefix = `__REPLACE_MARKER_${Math.random().toString(36).substr(2, 9)}_`;
let markerCounter = 0;
const markers: string[] = [];
// Apply edits sequentially, inserting markers at replacement positions
for (const edit of edits) {
// Skip empty oldText
if (edit.oldText === "") {
throw new Error(`The provided \`old_string\` is empty.\n\nNo edits were applied.`);
}
if (edit.replaceAll) {
// Replace all occurrences with marker + newText
const parts: string[] = [];
let lastIndex = 0;
let searchIndex = 0;
while (true) {
const index = currentContent.indexOf(edit.oldText, searchIndex);
if (index === -1) {
if (searchIndex === 0) {
throw new Error(
`The provided \`old_string\` does not appear in the file: "${edit.oldText}".\n\nNo edits were applied.`,
);
}
break;
}
// Add content before the match
parts.push(currentContent.substring(lastIndex, index));
// Add marker and replacement
const marker = `${markerPrefix}${markerCounter++}__`;
markers.push(marker);
parts.push(marker + edit.newText);
lastIndex = index + edit.oldText.length;
searchIndex = lastIndex;
}
// Add remaining content
parts.push(currentContent.substring(lastIndex));
currentContent = parts.join("");
} else {
// Replace first occurrence only
const index = currentContent.indexOf(edit.oldText);
if (index === -1) {
throw new Error(
`The provided \`old_string\` does not appear in the file: "${edit.oldText}".\n\nNo edits were applied.`,
);
} else {
const marker = `${markerPrefix}${markerCounter++}__`;
markers.push(marker);
currentContent =
currentContent.substring(0, index) +
marker +
edit.newText +
currentContent.substring(index + edit.oldText.length);
}
}
}
// Find line numbers where markers appear in the content
const lineNumbers: number[] = [];
for (const marker of markers) {
const index = currentContent.indexOf(marker);
if (index !== -1) {
const lineNumber = Math.max(
0,
currentContent.substring(0, index).split(/\r\n|\r|\n/).length - 1,
);
lineNumbers.push(lineNumber);
}
}
// Remove all markers from the final content
let finalContent = currentContent;
for (const marker of markers) {
finalContent = finalContent.replace(marker, "");
}
// Dedupe and sort line numbers
const uniqueLineNumbers = [...new Set(lineNumbers)].sort();
return { newContent: finalContent, lineNumbers: uniqueLineNumbers };
}

View File

@@ -1,8 +1,12 @@
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import { minimatch } from "minimatch";
import { ACP_TOOL_NAME_PREFIX, acpToolNames } from "./tools.js";
// resolveSettings and filterEscalatingDefaultMode are marked @alpha in the
// SDK; API may shift in a future release.
import {
filterEscalatingDefaultMode,
resolveSettings,
type Settings,
} from "@anthropic-ai/claude-agent-sdk";
import { CLAUDE_CONFIG_DIR } from "./acp-agent.js";
/**
@@ -17,217 +21,10 @@ import { CLAUDE_CONFIG_DIR } from "./acp-agent.js";
* Docs: https://code.claude.com/docs/en/iam#tool-specific-permission-rules
*/
export interface PermissionSettings {
allow?: string[];
deny?: string[];
ask?: string[];
additionalDirectories?: string[];
defaultMode?: string;
}
export interface ClaudeCodeSettings {
permissions?: PermissionSettings;
env?: Record<string, string>;
}
export type PermissionDecision = "allow" | "deny" | "ask";
export interface PermissionCheckResult {
decision: PermissionDecision;
rule?: string;
source?: "allow" | "deny" | "ask";
}
interface ParsedRule {
toolName: string;
argument?: string;
isWildcard?: boolean;
}
/**
* Shell operators that can be used for command chaining/injection
* These should cause a prefix match to fail to prevent bypasses like:
* - "safe-cmd && malicious-cmd"
* - "safe-cmd; malicious-cmd"
* - "safe-cmd | malicious-cmd"
* - "safe-cmd || malicious-cmd"
* - "$(malicious-cmd)"
* - "`malicious-cmd`"
*/
const SHELL_OPERATORS = ["&&", "||", ";", "|", "$(", "`", "\n"];
/**
* Checks if a string contains shell operators that could allow command chaining
*/
function containsShellOperator(str: string): boolean {
return SHELL_OPERATORS.some((op) => str.includes(op));
}
/*
* Tools that modify files. Per Claude Code docs:
* "Edit rules apply to all built-in tools that edit files."
* This means an Edit(...) rule should match Write, MultiEdit, etc.
*/
const FILE_EDITING_TOOLS = [acpToolNames.edit, acpToolNames.write];
/**
* Tools that read files. Per Claude Code docs:
* "Claude will make a best-effort attempt to apply Read rules to all built-in tools
* that read files like Grep and Glob."
* This means a Read(...) rule should match Grep, Glob, etc.
*/
const FILE_READING_TOOLS = [acpToolNames.read];
/**
* Functions to extract the relevant argument from tool input for permission matching
*/
const TOOL_ARG_ACCESSORS: Record<string, (input: unknown) => string | undefined> = {
mcp__acp__Read: (input) => (input as { file_path?: string })?.file_path,
mcp__acp__Edit: (input) => (input as { file_path?: string })?.file_path,
mcp__acp__Write: (input) => (input as { file_path?: string })?.file_path,
mcp__acp__Bash: (input) => (input as { command?: string })?.command,
};
/**
* Parses a permission rule string into its components
* Examples:
* "Read" -> { toolName: "Read" }
* "Read(./.env)" -> { toolName: "Read", argument: "./.env" }
* "Bash(npm run:*)" -> { toolName: "Bash", argument: "npm run", isWildcard: true }
*/
function parseRule(rule: string): ParsedRule {
const match = rule.match(/^(\w+)(?:\((.+)\))?$/);
if (!match) {
return { toolName: rule };
}
const [, toolName, argument] = match;
if (argument && argument.endsWith(":*")) {
return {
toolName,
argument: argument.slice(0, -2),
isWildcard: true,
};
}
return { toolName, argument };
}
/**
* Normalizes a path for comparison:
* - Expands ~ to home directory
* - Resolves relative paths against cwd
* - Normalizes path separators
*/
function normalizePath(filePath: string, cwd: string): string {
if (filePath.startsWith("~/")) {
filePath = path.join(os.homedir(), filePath.slice(2));
} else if (filePath.startsWith("./")) {
filePath = path.join(cwd, filePath.slice(2));
} else if (!path.isAbsolute(filePath)) {
filePath = path.join(cwd, filePath);
}
return path.normalize(filePath);
}
/**
* Checks if a file path matches a glob pattern
*/
function matchesGlob(pattern: string, filePath: string, cwd: string): boolean {
const normalizedPattern = normalizePath(pattern, cwd);
const normalizedPath = normalizePath(filePath, cwd);
return minimatch(normalizedPath, normalizedPattern, {
dot: true,
matchBase: false,
nocase: process.platform === "win32",
});
}
/**
* Checks if a tool invocation matches a parsed permission rule
*/
function matchesRule(rule: ParsedRule, toolName: string, toolInput: unknown, cwd: string): boolean {
// Per Claude Code docs:
// - "Edit rules apply to all built-in tools that edit files."
// - "Claude will make a best-effort attempt to apply Read rules to all built-in tools
// that read files like Grep, Glob, and LS."
const ruleAppliesToTool =
rule.toolName === "Bash" ||
(rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName)) ||
(rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName));
if (!ruleAppliesToTool) {
return false;
}
if (!rule.argument) {
return true;
}
const argAccessor = TOOL_ARG_ACCESSORS[toolName];
if (!argAccessor) {
return true;
}
const actualArg = argAccessor(toolInput);
if (!actualArg) {
return false;
}
if (toolName === acpToolNames.bash) {
// Per Claude Code docs: https://code.claude.com/docs/en/iam#tool-specific-permission-rules
// - Bash(npm run build) matches the EXACT command "npm run build"
// - Bash(npm run test:*) matches commands STARTING WITH "npm run test"
// The :* suffix enables prefix matching, without it the match is exact
//
// Also from docs: "Claude Code is aware of shell operators (like &&) so a prefix match
// rule like Bash(safe-cmd:*) won't give it permission to run the command safe-cmd && other-cmd"
if (rule.isWildcard) {
if (!actualArg.startsWith(rule.argument)) {
return false;
}
// Check that the matched prefix isn't followed by shell operators that could
// allow command chaining/injection
const remainder = actualArg.slice(rule.argument.length);
if (containsShellOperator(remainder)) {
return false;
}
return true;
}
return actualArg === rule.argument;
}
// For file-based tools (Read, Edit, Write), use glob matching
return matchesGlob(rule.argument, actualArg, cwd);
}
/**
* Reads and parses a JSON settings file, returning an empty object if not found or invalid
*/
async function loadSettingsFile(filePath: string | null): Promise<ClaudeCodeSettings> {
if (!filePath) {
return {};
}
try {
const content = await fs.promises.readFile(filePath, "utf-8");
return JSON.parse(content) as ClaudeCodeSettings;
} catch {
return {};
}
}
/**
* Gets the enterprise settings path based on the current platform
*/
export function getManagedSettingsPath(): string {
function getManagedSettingsPath(): string {
switch (process.platform) {
case "darwin":
return "/Library/Application Support/ClaudeCode/managed-settings.json";
case "linux":
return "/etc/claude-code/managed-settings.json";
case "win32":
return "C:\\Program Files\\ClaudeCode\\managed-settings.json";
default:
@@ -241,28 +38,24 @@ export interface SettingsManagerOptions {
}
/**
* Manages Claude Code settings from multiple sources with proper precedence.
* Manages Claude Code settings using the SDK's `resolveSettings` merge engine
* so the values we see match what `query()` would observe.
*
* Settings are loaded from (in order of increasing precedence):
* 1. User settings (~/.claude/settings.json)
* 2. Project settings (<cwd>/.claude/settings.json)
* 3. Local project settings (<cwd>/.claude/settings.local.json)
* 4. Enterprise managed settings (platform-specific path)
*
* The manager watches all settings files for changes and automatically reloads.
* Watches the user/project/local/managed settings files for changes and
* re-resolves through the SDK on update. Escalating `permissions.defaultMode`
* values from repo-committed sources are filtered out via
* `filterEscalatingDefaultMode`, matching the CLI's trust policy.
*/
export class SettingsManager {
private cwd: string;
private userSettings: ClaudeCodeSettings = {};
private projectSettings: ClaudeCodeSettings = {};
private localSettings: ClaudeCodeSettings = {};
private enterpriseSettings: ClaudeCodeSettings = {};
private mergedSettings: ClaudeCodeSettings = {};
private effective: Settings = {};
private watchers: fs.FSWatcher[] = [];
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;
@@ -277,117 +70,53 @@ export class SettingsManager {
if (this.initialized) {
return;
}
await this.loadAllSettings();
this.setupWatchers();
this.initialized = true;
}
/**
* Returns the path to the user settings file
*/
private getUserSettingsPath(): string {
return path.join(CLAUDE_CONFIG_DIR, "settings.json");
}
/**
* Returns the path to the project settings file
*/
private getProjectSettingsPath(): string {
return path.join(this.cwd, ".claude", "settings.json");
}
/**
* Returns the path to the local project settings file
*/
private getLocalSettingsPath(): string {
return path.join(this.cwd, ".claude", "settings.local.json");
}
/**
* Loads settings from all sources
*/
private async loadAllSettings(): Promise<void> {
const [userSettings, projectSettings, localSettings, enterpriseSettings] = await Promise.all([
loadSettingsFile(this.getUserSettingsPath()),
loadSettingsFile(this.getProjectSettingsPath()),
loadSettingsFile(this.getLocalSettingsPath()),
loadSettingsFile(getManagedSettingsPath()),
]);
this.userSettings = userSettings;
this.projectSettings = projectSettings;
this.localSettings = localSettings;
this.enterpriseSettings = enterpriseSettings;
this.mergeSettings();
}
/**
* Merges all settings sources with proper precedence.
* For permissions, rules from all sources are combined.
* Deny rules always take precedence during permission checks.
*/
private mergeSettings(): void {
const allSettings = [
this.userSettings,
this.projectSettings,
this.localSettings,
this.enterpriseSettings,
];
const merged: ClaudeCodeSettings = {
permissions: {
allow: [],
deny: [],
ask: [],
},
};
for (const settings of allSettings) {
if (settings.permissions) {
if (settings.permissions.allow) {
merged.permissions!.allow!.push(...settings.permissions.allow);
}
if (settings.permissions.deny) {
merged.permissions!.deny!.push(...settings.permissions.deny);
}
if (settings.permissions.ask) {
merged.permissions!.ask!.push(...settings.permissions.ask);
}
if (settings.permissions.additionalDirectories) {
merged.permissions!.additionalDirectories = [
...(merged.permissions!.additionalDirectories || []),
...settings.permissions.additionalDirectories,
];
}
if (settings.permissions.defaultMode) {
merged.permissions!.defaultMode = settings.permissions.defaultMode;
}
}
if (settings.env) {
merged.env = { ...merged.env, ...settings.env };
}
if (this.initPromise) {
return this.initPromise;
}
this.mergedSettings = merged;
this.disposed = false;
this.initPromise = this.loadAllSettings().then(() => {
if (!this.disposed) {
this.setupWatchers();
this.initialized = true;
}
this.initPromise = null;
});
return this.initPromise;
}
/**
* Paths the SDK reads when resolving settings for this cwd. Watching the
* containing directories means we pick up file creation as well as edits.
*/
private getWatchedPaths(): string[] {
return [
path.join(CLAUDE_CONFIG_DIR, "settings.json"),
path.join(this.cwd, ".claude", "settings.json"),
path.join(this.cwd, ".claude", "settings.local.json"),
getManagedSettingsPath(),
];
}
/**
* Resolves the effective settings via the SDK and applies the CLI's trust
* filter for escalating `permissions.defaultMode` values.
*/
private async loadAllSettings(): Promise<void> {
try {
const resolved = await resolveSettings({ cwd: this.cwd });
this.effective = filterEscalatingDefaultMode(resolved);
} catch (error) {
this.logger.error("Failed to resolve settings:", error);
this.effective = {};
}
}
/**
* Sets up file watchers for all settings files
*/
private setupWatchers(): void {
const paths = [
this.getUserSettingsPath(),
this.getProjectSettingsPath(),
this.getLocalSettingsPath(),
getManagedSettingsPath(),
];
for (const filePath of paths) {
if (!filePath) continue;
for (const filePath of this.getWatchedPaths()) {
try {
const dir = path.dirname(filePath);
const filename = path.basename(filePath);
@@ -421,66 +150,25 @@ 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);
}
}, 100);
}
/**
* Checks if a tool invocation is allowed based on the loaded settings.
*
* @param toolName - The tool name (can be ACP-prefixed like mcp__acp__Read or plain like Read)
* @param toolInput - The tool input object
* @returns The permission decision and matching rule info
*/
checkPermission(toolName: string, toolInput: unknown): PermissionCheckResult {
if (!toolName.startsWith(ACP_TOOL_NAME_PREFIX)) {
return { decision: "ask" };
}
const permissions = this.mergedSettings.permissions;
if (!permissions) {
return { decision: "ask" };
}
// Check deny rules first (highest priority)
for (const rule of permissions.deny || []) {
const parsed = parseRule(rule);
if (matchesRule(parsed, toolName, toolInput, this.cwd)) {
return { decision: "deny", rule, source: "deny" };
}
}
// Check allow rules
for (const rule of permissions.allow || []) {
const parsed = parseRule(rule);
if (matchesRule(parsed, toolName, toolInput, this.cwd)) {
return { decision: "allow", rule, source: "allow" };
}
}
// Check ask rules
for (const rule of permissions.ask || []) {
const parsed = parseRule(rule);
if (matchesRule(parsed, toolName, toolInput, this.cwd)) {
return { decision: "ask", rule, source: "ask" };
}
}
// No matching rule - default to ask
return { decision: "ask" };
}
/**
* Returns the current merged settings
*/
getSettings(): ClaudeCodeSettings {
return this.mergedSettings;
getSettings(): Settings {
return this.effective;
}
/**
@@ -500,7 +188,6 @@ export class SettingsManager {
this.dispose();
this.cwd = cwd;
this.initialized = false;
await this.initialize();
}
@@ -508,6 +195,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;
@@ -517,6 +208,5 @@ export class SettingsManager {
watcher.close();
}
this.watchers = [];
this.initialized = false;
}
}

View File

@@ -0,0 +1,782 @@
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import type { AgentSideConnection } from "@agentclientprotocol/sdk";
import type { ClaudeAcpAgent as ClaudeAcpAgentType } from "../acp-agent.js";
const { querySpy } = vi.hoisted(() => ({
querySpy: vi.fn(),
}));
vi.mock("@anthropic-ai/claude-agent-sdk", async () => {
const actual = await vi.importActual<any>("@anthropic-ai/claude-agent-sdk");
return {
...actual,
query: querySpy,
};
});
describe("ClaudeAcpAgent settings", () => {
let tempDir: string;
let originalClaudeConfigDir: string | undefined;
function createMockClient(): AgentSideConnection {
return {
sessionUpdate: async () => {},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection;
}
function mockQuery() {
let capturedOptions: any;
const setModelSpy = vi.fn();
querySpy.mockImplementation(({ options }: any) => {
capturedOptions = options;
return {
initializationResult: async () => ({
models: [
{
value: "claude-sonnet-4-6",
displayName: "Claude Sonnet 4.5",
description: "Default",
},
],
}),
setModel: setModelSpy,
supportedCommands: async () => [],
} as any;
});
return { getCapturedOptions: () => capturedOptions, setModelSpy };
}
beforeEach(async () => {
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "acp-agent-settings-"));
originalClaudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
process.env.CLAUDE_CONFIG_DIR = tempDir;
querySpy.mockReset();
vi.resetModules();
});
afterEach(async () => {
if (originalClaudeConfigDir) {
process.env.CLAUDE_CONFIG_DIR = originalClaudeConfigDir;
} else {
delete process.env.CLAUDE_CONFIG_DIR;
}
await fs.promises.rm(tempDir, { recursive: true, force: true });
});
it("uses permissions.defaultMode for new sessions", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
permissions: {
defaultMode: "dontAsk",
},
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(getCapturedOptions().permissionMode).toBe("dontAsk");
expect(getCapturedOptions().settingSources).toEqual(["user", "project", "local"]);
expect(response.modes.currentModeId).toBe("dontAsk");
});
it("supports acceptEdits mode defaults", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
permissions: {
defaultMode: "acceptEdits",
},
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(getCapturedOptions().permissionMode).toBe("acceptEdits");
expect(response.modes.currentModeId).toBe("acceptEdits");
});
it("drops escalating defaultMode when it comes from project-tier settings", async () => {
// bypassPermissions in .claude/settings.json (a repo-committed tier) is
// filtered by the SDK's trust policy and clamps to 'default'.
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(path.join(projectDir, ".claude"), { recursive: true });
await fs.promises.writeFile(
path.join(projectDir, ".claude", "settings.json"),
JSON.stringify({ permissions: { defaultMode: "bypassPermissions" } }),
);
const { getCapturedOptions } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(getCapturedOptions().permissionMode).toBe("default");
expect(response.modes.currentModeId).toBe("default");
});
it("defaults to 'default' when no permissions.defaultMode is set", async () => {
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(getCapturedOptions().permissionMode).toBe("default");
expect(response.modes.currentModeId).toBe("default");
});
it("falls back to 'default' when permissions.defaultMode is invalid", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
permissions: {
defaultMode: "not-a-real-mode",
},
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
// Bad mode is ignored at the usage site; session creation must not throw.
expect(getCapturedOptions().permissionMode).toBe("default");
expect(response.modes.currentModeId).toBe("default");
});
it("ignores model from settings when it is not a string", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
model: 123,
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { setModelSpy } = mockQuery();
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
// Bad model is ignored at the usage site; falls back to the first SDK model.
// No setModel call is needed because no override was applied — the SDK is
// already on its own default.
expect(setModelSpy).not.toHaveBeenCalled();
expect(response.models.currentModelId).toBe("claude-sonnet-4-6");
});
describe("auto mode availability per model", () => {
function mockQueryWithModels(models: any[]): {
getCapturedOptions: () => any;
setModelSpy: ReturnType<typeof vi.fn>;
setPermissionModeSpy: ReturnType<typeof vi.fn>;
} {
let capturedOptions: any;
const setModelSpy = vi.fn();
const setPermissionModeSpy = vi.fn();
querySpy.mockImplementation(({ options }: any) => {
capturedOptions = options;
return {
initializationResult: async () => ({ models }),
setModel: setModelSpy,
setPermissionMode: setPermissionModeSpy,
supportedCommands: async () => [],
} as any;
});
return {
getCapturedOptions: () => capturedOptions,
setModelSpy,
setPermissionModeSpy,
};
}
it("omits `auto` from availableModes when the resolved model lacks supportsAutoMode", async () => {
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{
value: "claude-haiku-4-5",
displayName: "Claude Haiku",
description: "Fast",
// supportsAutoMode intentionally omitted
},
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modeIds: string[] = response.modes.availableModes.map((m: any) => m.id);
expect(modeIds).not.toContain("auto");
expect(modeIds).toEqual(
expect.arrayContaining(["default", "acceptEdits", "plan", "dontAsk"]),
);
});
it("includes `auto` when the resolved model has supportsAutoMode: true", async () => {
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{
value: "claude-opus-4-5",
displayName: "Claude Opus",
description: "Most capable",
supportsAutoMode: true,
},
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modeIds: string[] = response.modes.availableModes.map((m: any) => m.id);
expect(modeIds).toContain("auto");
});
it("clamps permissions.defaultMode='auto' to 'default' on a model that lacks supportsAutoMode", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({ permissions: { defaultMode: "auto" } }),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions, setPermissionModeSpy } = mockQueryWithModels([
{
value: "claude-haiku-4-5",
displayName: "Claude Haiku",
description: "Fast",
// supportsAutoMode intentionally omitted
},
]);
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
try {
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
// Options.permissionMode is built before init resolves, so it still
// carries the user-typed value; the SDK was synced via
// setPermissionMode after we discovered the model can't honor it.
expect(getCapturedOptions().permissionMode).toBe("auto");
expect(setPermissionModeSpy).toHaveBeenCalledWith("default");
expect(response.modes.currentModeId).toBe("default");
expect(response.modes.availableModes.map((m: any) => m.id)).not.toContain("auto");
// A descriptive warning was logged so operators see the clamp.
const messages = errorSpy.mock.calls.map((c) => c.join(" "));
expect(messages.some((m) => m.includes("auto") && m.includes("claude-haiku-4-5"))).toBe(
true,
);
} finally {
errorSpy.mockRestore();
}
});
it("does not clamp permissions.defaultMode='auto' on a model that supports auto", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({ permissions: { defaultMode: "auto" } }),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { getCapturedOptions, setPermissionModeSpy } = mockQueryWithModels([
{
value: "claude-opus-4-5",
displayName: "Claude Opus",
description: "Most capable",
supportsAutoMode: true,
},
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(getCapturedOptions().permissionMode).toBe("auto");
expect(setPermissionModeSpy).not.toHaveBeenCalled();
expect(response.modes.currentModeId).toBe("auto");
});
});
describe("availableModels allowlist from settings", () => {
function mockQueryWithModels(models: any[]): {
setModelSpy: ReturnType<typeof vi.fn>;
} {
const setModelSpy = vi.fn();
querySpy.mockImplementation(() => {
return {
initializationResult: async () => ({ models }),
setModel: setModelSpy,
supportedCommands: async () => [],
} as any;
});
return { setModelSpy };
}
it("restricts configOptions to the user's allowlist using their exact IDs", async () => {
// Reproduces the scenario from
// https://github.com/agentclientprotocol/claude-agent-acp/issues/620:
// user lists `claude-haiku-4-5` (no date pin) in availableModels, but
// the SDK still surfaces its `haiku` alias which resolves to a
// date-pinned variant the user doesn't have access to.
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
availableModels: [
"claude-sonnet-4-6[1m]",
"claude-opus-4-6[1m]",
"claude-haiku-4-5",
"claude-opus-4-7[1m]",
],
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{
value: "sonnet[1m]",
displayName: "Sonnet (1M context)",
description: "Sonnet 4.6 long context",
},
{
value: "opus[1m]",
displayName: "Opus (1M context)",
description: "Opus 1M context",
},
{ value: "haiku", displayName: "Haiku", description: "Fast" },
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modelOption = response.configOptions.find((o: any) => o.id === "model");
expect(modelOption.options.map((o: any) => o.value)).toEqual([
"default",
"claude-sonnet-4-6[1m]",
"claude-opus-4-6[1m]",
"claude-haiku-4-5",
"claude-opus-4-7[1m]",
]);
});
it("unions availableModels across user and project settings", async () => {
// https://code.claude.com/docs/en/model-config#merge-behavior
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({ availableModels: ["claude-haiku-4-5"] }),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(path.join(projectDir, ".claude"), { recursive: true });
await fs.promises.writeFile(
path.join(projectDir, ".claude", "settings.json"),
JSON.stringify({
availableModels: ["claude-haiku-4-5", "claude-opus-4-7[1m]"],
}),
);
mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{ value: "haiku", displayName: "Haiku", description: "Fast" },
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modelOption = response.configOptions.find((o: any) => o.id === "model");
// User and project entries are unioned and deduplicated.
expect(modelOption.options.map((o: any) => o.value)).toEqual([
"default",
"claude-haiku-4-5",
"claude-opus-4-7[1m]",
]);
});
it("returns only the default entry when availableModels is an empty array", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({ availableModels: [] }),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{ value: "haiku", displayName: "Haiku", description: "Fast" },
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modelOption = response.configOptions.find((o: any) => o.id === "model");
expect(modelOption.options.map((o: any) => o.value)).toEqual(["default"]);
});
it("does not filter when availableModels is absent from settings", async () => {
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{ value: "haiku", displayName: "Haiku", description: "Fast" },
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modelOption = response.configOptions.find((o: any) => o.id === "model");
expect(modelOption.options.map((o: any) => o.value)).toEqual(["default", "haiku"]);
});
it("passes the user's exact ID to setModel when it matches an SDK alias", async () => {
// Without the allowlist, the SDK would resolve `haiku` to a
// date-pinned variant. Forcing setModel to receive `claude-haiku-4-5`
// is exactly what the issue's workaround
// (`ANTHROPIC_DEFAULT_HAIKU_MODEL`) achieves manually.
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
availableModels: ["claude-haiku-4-5"],
model: "claude-haiku-4-5",
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const { setModelSpy } = mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{ value: "haiku", displayName: "Haiku", description: "Fast" },
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(setModelSpy).toHaveBeenCalledWith("claude-haiku-4-5");
expect(response.models.currentModelId).toBe("claude-haiku-4-5");
});
it("does not inherit display info across mismatched model family versions", async () => {
// https://github.com/agentclientprotocol/claude-agent-acp/issues/639:
// when the SDK's `opus` alias resolves to Opus 4.7, an allowlist entry
// of `claude-opus-4-6` (or `claude-opus-4-6[1m]`) used to substring-match
// `opus` and inherit the "Opus 4.7" display info. With version-aware
// matching, these entries fall back to showing their literal ID rather
// than a misleading newer name.
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
availableModels: [
"claude-opus-4-6",
"claude-opus-4-6[1m]",
"claude-opus-4-7",
"claude-opus-4-7[1m]",
],
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
mockQueryWithModels([
{ value: "default", displayName: "Default", description: "Default model" },
{
value: "opus",
displayName: "Opus 4.7",
description: "Claude Opus 4.7 — complex tasks, higher cost",
},
{
value: "opus[1m]",
displayName: "Opus 4.7 (1M context)",
description: "Opus 4.7 with 1M context",
},
]);
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
const modelOption = response.configOptions.find((o: any) => o.id === "model");
const byValue: Record<string, { name: string; description?: string }> = {};
for (const opt of modelOption.options) {
byValue[opt.value] = { name: opt.name, description: opt.description };
}
// 4-6 entries must NOT inherit the 4.7 SDK alias display info.
expect(byValue["claude-opus-4-6"].name).toBe("claude-opus-4-6");
expect(byValue["claude-opus-4-6"].description).toBe("");
expect(byValue["claude-opus-4-6[1m]"].name).toBe("claude-opus-4-6[1m]");
expect(byValue["claude-opus-4-6[1m]"].description).toBe("");
// 4-7 entries continue to inherit display info from a 4.7 SDK alias.
expect(byValue["claude-opus-4-7"].name).toBe("Opus 4.7");
expect(byValue["claude-opus-4-7[1m]"].name).toMatch(/Opus 4\.7/);
});
});
it("resolves model aliases like opus[1m] to the correct model", async () => {
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
model: "opus[1m]",
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const setModelSpy = vi.fn();
querySpy.mockImplementation(({ options: _options }: any) => {
return {
initializationResult: async () => ({
models: [
{
value: "claude-opus-4-6",
displayName: "Claude Opus 4.6",
description: "Base",
},
{
value: "claude-opus-4-6-1m",
displayName: "Claude Opus 4.6 (1M)",
description: "Long context",
},
],
}),
setModel: setModelSpy,
supportedCommands: async () => [],
} as any;
});
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(setModelSpy).toHaveBeenCalledWith("claude-opus-4-6-1m");
expect(response.models.currentModelId).toBe("claude-opus-4-6-1m");
});
it("skips the initial setModel when the resolved value matches the SDK's model list verbatim", async () => {
// Covers the launcher case from PR #646: the launcher bakes the model into
// ANTHROPIC_MODEL, the SDK already starts on that model, and a second
// setModel call would be a redundant round-trip (and on some launcher
// setups, more fragile than launch-time selection).
const originalEnv = process.env.ANTHROPIC_MODEL;
process.env.ANTHROPIC_MODEL = "claude-opus-4-6";
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const setModelSpy = vi.fn();
querySpy.mockImplementation(() => {
return {
initializationResult: async () => ({
models: [
{ value: "default", displayName: "Default", description: "" },
{ value: "claude-sonnet-4-6", displayName: "Claude Sonnet 4.6", description: "" },
{ value: "claude-opus-4-6", displayName: "Claude Opus 4.6", description: "" },
],
}),
setModel: setModelSpy,
supportedCommands: async () => [],
} as any;
});
try {
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(setModelSpy).not.toHaveBeenCalled();
expect(response.models.currentModelId).toBe("claude-opus-4-6");
} finally {
if (originalEnv === undefined) {
delete process.env.ANTHROPIC_MODEL;
} else {
process.env.ANTHROPIC_MODEL = originalEnv;
}
}
});
it("still calls setModel when the allowlist synthesizes a value the SDK has not surfaced", async () => {
// The allowlist may rewrite a model's `value` to the user's literal ID
// (e.g., `claude-haiku-4-5`) even when the SDK only exposed an alias
// (`haiku`). In that case the SDK has not independently arrived at the
// user's preferred ID, so we must sync via setModel.
await fs.promises.writeFile(
path.join(tempDir, "settings.json"),
JSON.stringify({
availableModels: ["claude-haiku-4-5"],
model: "claude-haiku-4-5",
}),
);
const projectDir = path.join(tempDir, "project");
await fs.promises.mkdir(projectDir, { recursive: true });
const setModelSpy = vi.fn();
querySpy.mockImplementation(() => {
return {
initializationResult: async () => ({
models: [
{ value: "default", displayName: "Default", description: "" },
{ value: "haiku", displayName: "Haiku", description: "Fast" },
],
}),
setModel: setModelSpy,
supportedCommands: async () => [],
} as any;
});
const { ClaudeAcpAgent } = await import("../acp-agent.js");
const agent: ClaudeAcpAgentType = new ClaudeAcpAgent(createMockClient());
const response = await (agent as any).createSession({
cwd: projectDir,
mcpServers: [],
_meta: { disableBuiltInTools: true },
});
expect(setModelSpy).toHaveBeenCalledWith("claude-haiku-4-5");
expect(response.models.currentModelId).toBe("claude-haiku-4-5");
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
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-6",
displayName: "Claude Sonnet",
description: "Fast",
supportsAutoMode: true,
},
],
}),
setModel: async () => {},
setPermissionMode: 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]);
});
it("prefers the official ACP additionalDirectories field over _meta.additionalRoots", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
additionalDirectories: ["/from/official"],
_meta: { additionalRoots: ["/from/meta"] },
});
expect(capturedOptions!.additionalDirectories).toEqual(["/from/official"]);
});
it("merges official ACP additionalDirectories with claudeCode SDK additionalDirectories", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
additionalDirectories: ["/from/official"],
_meta: { claudeCode: { options: { additionalDirectories: ["/from/sdk"] } } },
});
expect(capturedOptions!.additionalDirectories).toEqual(["/from/sdk", "/from/official"]);
});
it("falls back to _meta.additionalRoots when the official field is omitted", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: { additionalRoots: ["/from/meta"] },
});
expect(capturedOptions!.additionalDirectories).toEqual(["/from/meta"]);
});
});

View File

@@ -0,0 +1,296 @@
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", supportsAutoMode: true },
],
}),
setModel: vi.fn(),
setPermissionMode: vi.fn(),
supportedCommands: vi.fn().mockResolvedValue([]),
})),
);
vi.mock("@anthropic-ai/claude-agent-sdk", () => ({
query: mockQuery,
}));
describe("authorization", () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
//await all pending events like
vi.runAllTimers();
vi.useRealTimers();
vi.unstubAllGlobals();
vi.resetAllMocks();
});
async function createAgentMock(): Promise<[ClaudeAcpAgent, Mock]> {
const connectionMock = {
sessionUpdate: async (_: any) => {},
} as AgentSideConnection;
const agent = new ClaudeAcpAgent(connectionMock);
return [agent, mockQuery];
}
it("gateway auth not offered without capability", async () => {
const [agent] = await createAgentMock();
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {},
});
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "gateway" }),
);
expect(initializeResponse.authMethods).not.toContainEqual(
expect.objectContaining({ id: "gateway-bedrock" }),
);
});
it("gateway auth offered when client advertises auth._meta.gateway capability", async () => {
const [agent] = await createAgentMock();
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
auth: { _meta: { gateway: true } },
} as any,
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({
id: "gateway",
_meta: { gateway: { protocol: "anthropic" } },
}),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({
id: "gateway-bedrock",
_meta: { gateway: { protocol: "bedrock" } },
}),
);
});
it("uses gateway env after anthropic gateway auth", async () => {
const [agent, mockQuery] = await createAgentMock();
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
auth: { terminal: true, _meta: { gateway: true } },
} as any,
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "gateway" }),
);
await agent.authenticate({
methodId: "gateway",
_meta: { gateway: { baseUrl: "https://gateway.example", headers: { "x-api-key": "test" } } },
});
await agent.newSession({
cwd: "testRoot",
mcpServers: [],
_meta: {
claudeCode: {
options: {
env: {
userEnv: "userEnv",
},
},
},
},
});
expect(mockQuery).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({
env: expect.objectContaining({
ANTHROPIC_AUTH_TOKEN: " ",
ANTHROPIC_BASE_URL: "https://gateway.example",
ANTHROPIC_CUSTOM_HEADERS: "x-api-key: test",
userEnv: "userEnv",
}),
}),
}),
);
});
it("uses gateway env after gateway auth", async () => {
const [agent, mockQuery] = await createAgentMock();
await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
auth: { terminal: true, _meta: { gateway: true } },
} as any,
});
await agent.authenticate({
methodId: "gateway-bedrock",
_meta: {
gateway: { baseUrl: "https://gateway.example", headers: { "custom-header": "test" } },
},
});
await agent.newSession({
cwd: "testRoot",
mcpServers: [],
});
expect(mockQuery).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({
env: expect.objectContaining({
CLAUDE_CODE_USE_BEDROCK: "1",
AWS_BEARER_TOKEN_BEDROCK: " ",
ANTHROPIC_BEDROCK_BASE_URL: "https://gateway.example",
ANTHROPIC_CUSTOM_HEADERS: "custom-header: test",
}),
}),
}),
);
});
it("hide claude authentication without terminal-auth", async () => {
const [agent] = await createAgentMock();
vi.stubGlobal("process", { ...process, argv: ["--hide-claude-auth"] });
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
auth: { _meta: { gateway: true } },
} as any,
});
expect(initializeResponse.authMethods).not.toContainEqual(
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 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"] });
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: {
_meta: { "terminal-auth": true },
},
});
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 () => {
const [agent] = await createAgentMock();
const initializeResponse = await agent.initialize({
protocolVersion: 1,
clientCapabilities: { auth: { terminal: true } },
});
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "claude-ai-login" }),
);
expect(initializeResponse.authMethods).toContainEqual(
expect.objectContaining({ id: "console-login" }),
);
});
});

View File

@@ -0,0 +1,476 @@
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { AgentSideConnection, SessionNotification } from "@agentclientprotocol/sdk";
import type { Options } from "@anthropic-ai/claude-agent-sdk";
import type { ClaudeAcpAgent as ClaudeAcpAgentType } from "../acp-agent.js";
let capturedOptions: Options | undefined;
vi.mock("@anthropic-ai/claude-agent-sdk", async () => {
const actual = await vi.importActual<typeof import("@anthropic-ai/claude-agent-sdk")>(
"@anthropic-ai/claude-agent-sdk",
);
return {
...actual,
query: (args: { prompt: unknown; options: Options }) => {
capturedOptions = args.options;
return {
initializationResult: async () => ({
models: [
{
value: "claude-sonnet-4-6",
displayName: "Claude Sonnet",
description: "Fast",
supportsAutoMode: true,
},
],
}),
setModel: async () => {},
setPermissionMode: async () => {},
supportedCommands: async () => [],
[Symbol.asyncIterator]: async function* () {},
};
},
};
});
vi.mock("../tools.js", async () => {
const actual = await vi.importActual<typeof import("../tools.js")>("../tools.js");
return {
...actual,
registerHookCallback: vi.fn(),
};
});
describe("createSession options merging", () => {
let agent: ClaudeAcpAgentType;
let ClaudeAcpAgent: typeof ClaudeAcpAgentType;
function createMockClient(): AgentSideConnection {
return {
sessionUpdate: async (_notification: SessionNotification) => {},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection;
}
beforeEach(async () => {
capturedOptions = undefined;
vi.resetModules();
const acpAgent = await import("../acp-agent.js");
ClaudeAcpAgent = acpAgent.ClaudeAcpAgent;
agent = new ClaudeAcpAgent(createMockClient());
});
it("merges user-provided disallowedTools with ACP internal list", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
disallowedTools: ["WebSearch", "WebFetch"],
},
},
},
});
// User-provided tools should be present
expect(capturedOptions!.disallowedTools).toContain("WebSearch");
expect(capturedOptions!.disallowedTools).toContain("WebFetch");
// ACP's internal disallowed tool should also be present
expect(capturedOptions!.disallowedTools).toContain("AskUserQuestion");
});
it("works when user provides no disallowedTools", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
});
expect(capturedOptions!.disallowedTools).toContain("AskUserQuestion");
});
it("works when user provides empty disallowedTools", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
disallowedTools: [],
},
},
},
});
expect(capturedOptions!.disallowedTools).toContain("AskUserQuestion");
});
it("sets tools to empty array when disableBuiltInTools is true", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
disableBuiltInTools: true,
claudeCode: {
options: {
disallowedTools: ["CustomTool"],
},
},
},
});
// disableBuiltInTools removes all built-in tools from context
expect(capturedOptions!.tools).toEqual([]);
// User-provided and ACP disallowedTools still apply
expect(capturedOptions!.disallowedTools).toContain("CustomTool");
expect(capturedOptions!.disallowedTools).toContain("AskUserQuestion");
});
it("merges user-provided hooks with ACP hooks", async () => {
const userPreToolUseHook = { hooks: [{ command: "echo pre" }] };
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
hooks: {
PreToolUse: [userPreToolUseHook],
PostToolUse: [{ hooks: [{ command: "echo user-post" }] }],
},
},
},
},
});
// User's PreToolUse hooks should be preserved
expect(capturedOptions!.hooks?.PreToolUse).toEqual([userPreToolUseHook]);
// PostToolUse should contain both user and ACP hooks
expect(capturedOptions!.hooks?.PostToolUse).toHaveLength(2);
});
it("inherits HOME and PATH from process.env when no env is provided", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
});
expect(capturedOptions?.env?.HOME).toBe(process.env.HOME);
expect(capturedOptions?.env?.PATH).toBe(process.env.PATH);
});
it("merges user-provided env vars on top of process.env", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
env: {
CUSTOM_VAR: "custom-value",
},
},
},
},
});
expect(capturedOptions?.env?.HOME).toBe(process.env.HOME);
expect(capturedOptions?.env?.PATH).toBe(process.env.PATH);
expect(capturedOptions?.env?.CUSTOM_VAR).toBe("custom-value");
});
it("allows user-provided env vars to override process.env entries", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
env: {
HOME: "/custom/home",
},
},
},
},
});
expect(capturedOptions?.env?.HOME).toBe("/custom/home");
});
it("defaults tools to claude_code preset when not provided", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
});
expect(capturedOptions!.tools).toEqual({ type: "preset", preset: "claude_code" });
});
it("passes through user-provided tools string array", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
tools: ["Read", "Glob"],
},
},
},
});
expect(capturedOptions!.tools).toEqual(["Read", "Glob"]);
});
it("explicit tools array takes precedence over disableBuiltInTools", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
disableBuiltInTools: true,
claudeCode: {
options: {
tools: ["Read", "Glob"],
},
},
},
});
expect(capturedOptions!.tools).toEqual(["Read", "Glob"]);
});
it("passes through empty tools array to disable all built-in tools", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
tools: [],
},
},
},
});
expect(capturedOptions!.tools).toEqual([]);
});
describe("systemPrompt via _meta", () => {
it("defaults to the claude_code preset when not provided", async () => {
await agent.newSession({ cwd: "/test", mcpServers: [] });
expect(capturedOptions!.systemPrompt).toEqual({
type: "preset",
preset: "claude_code",
});
});
it("replaces the preset when a string is provided", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: { systemPrompt: "custom prompt" },
});
expect(capturedOptions!.systemPrompt).toBe("custom prompt");
});
it("forwards append", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: { systemPrompt: { append: "extra instructions" } },
});
expect(capturedOptions!.systemPrompt).toEqual({
type: "preset",
preset: "claude_code",
append: "extra instructions",
});
});
it("forwards excludeDynamicSections", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: { systemPrompt: { excludeDynamicSections: true } },
});
expect(capturedOptions!.systemPrompt).toEqual({
type: "preset",
preset: "claude_code",
excludeDynamicSections: true,
});
});
it("forwards append and excludeDynamicSections together", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
systemPrompt: {
append: "extra instructions",
excludeDynamicSections: true,
},
},
});
expect(capturedOptions!.systemPrompt).toEqual({
type: "preset",
preset: "claude_code",
append: "extra instructions",
excludeDynamicSections: true,
});
});
it("ignores caller-provided type/preset overrides", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
systemPrompt: {
type: "something-else",
preset: "other-preset",
append: "extra",
},
},
});
expect(capturedOptions!.systemPrompt).toEqual({
type: "preset",
preset: "claude_code",
append: "extra",
});
});
});
describe("CLAUDE_MODEL_CONFIG", () => {
let originalModelConfig: string | undefined;
beforeEach(() => {
originalModelConfig = process.env.CLAUDE_MODEL_CONFIG;
delete process.env.CLAUDE_MODEL_CONFIG;
});
afterEach(() => {
if (originalModelConfig !== undefined) {
process.env.CLAUDE_MODEL_CONFIG = originalModelConfig;
} else {
delete process.env.CLAUDE_MODEL_CONFIG;
}
});
it("passes modelOverrides as settings", async () => {
process.env.CLAUDE_MODEL_CONFIG = JSON.stringify({
modelOverrides: { "claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1" },
});
await agent.newSession({ cwd: "/test", mcpServers: [] });
expect(capturedOptions!.settings).toEqual({
modelOverrides: { "claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1" },
});
});
it("passes availableModels as settings", async () => {
process.env.CLAUDE_MODEL_CONFIG = JSON.stringify({
availableModels: ["opus", "sonnet"],
});
await agent.newSession({ cwd: "/test", mcpServers: [] });
expect(capturedOptions!.settings).toEqual({
availableModels: ["opus", "sonnet"],
});
});
it("passes both modelOverrides and availableModels", async () => {
process.env.CLAUDE_MODEL_CONFIG = JSON.stringify({
modelOverrides: { "claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1" },
availableModels: ["opus"],
});
await agent.newSession({ cwd: "/test", mcpServers: [] });
expect(capturedOptions!.settings).toEqual({
modelOverrides: { "claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1" },
availableModels: ["opus"],
});
});
it("does not add settings when env var is not set", async () => {
await agent.newSession({ cwd: "/test", mcpServers: [] });
expect(capturedOptions!.settings).toBeUndefined();
});
it("ignores env var when _meta provides settings", async () => {
process.env.CLAUDE_MODEL_CONFIG = JSON.stringify({
modelOverrides: { "claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1" },
});
await agent.newSession({
cwd: "/test",
mcpServers: [],
_meta: {
claudeCode: {
options: {
settings: {
model: "claude-sonnet-4-6",
modelOverrides: { "claude-opus-4-6": "meta-value" },
},
},
},
},
});
// _meta settings take precedence; env var is ignored entirely
expect(capturedOptions!.settings).toEqual({
model: "claude-sonnet-4-6",
modelOverrides: { "claude-opus-4-6": "meta-value" },
});
});
it("throws on invalid JSON", async () => {
process.env.CLAUDE_MODEL_CONFIG = "not-json";
await expect(agent.newSession({ cwd: "/test", mcpServers: [] })).rejects.toThrow();
});
});
it("merges user-provided mcpServers with ACP mcpServers", async () => {
await agent.newSession({
cwd: "/test",
mcpServers: [
{
name: "acp-server",
command: "node",
args: ["acp-server.js"],
env: [],
},
],
_meta: {
claudeCode: {
options: {
mcpServers: {
"user-server": {
type: "stdio",
command: "node",
args: ["server.js"],
},
},
},
},
},
});
// User-provided MCP server should be present
expect(capturedOptions!.mcpServers).toHaveProperty("user-server");
// ACP-provided MCP server should also be present
expect(capturedOptions!.mcpServers).toHaveProperty("acp-server");
});
});

View File

@@ -1,103 +0,0 @@
import { describe, it, expect } from "vitest";
import { extractLinesWithByteLimit } from "../utils.js";
describe("extractLinesWithByteLimit", () => {
const simpleContent = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5";
it("should extract all lines when under byte limit", () => {
const result = extractLinesWithByteLimit(simpleContent, 1000);
expect(result.content).toBe(simpleContent);
expect(result.wasLimited).toBe(false);
expect(result.linesRead).toBe(5);
});
it("should limit output when exceeding byte limit", () => {
// Create content that will exceed byte limit
const longLine = "x".repeat(100);
const manyLines = Array(10).fill(longLine).join("\n");
const result = extractLinesWithByteLimit(manyLines, 250);
expect(result.wasLimited).toBe(true);
expect(result.linesRead).toBe(2);
});
it("should handle empty content", () => {
const result = extractLinesWithByteLimit("", 1000);
expect(result.content).toBe("");
expect(result.wasLimited).toBe(false);
expect(result.linesRead).toBe(1); // We read the one empty line
});
it("should handle single line file", () => {
const singleLine = "This is a single line without newline";
const result = extractLinesWithByteLimit(singleLine, 1000);
expect(result.content).toBe(singleLine);
expect(result.wasLimited).toBe(false);
expect(result.linesRead).toBe(1);
});
it("should correctly count bytes with multi-byte characters", () => {
const unicodeContent = "Hello 世界\n你好 World\nEmoji: 🌍\nNormal line";
const result = extractLinesWithByteLimit(unicodeContent, 1000);
expect(result.content).toBe(unicodeContent);
expect(result.linesRead).toBe(4);
});
it("should stop at byte limit even with one more line available", () => {
// Create lines where adding one more would exceed limit
const line1 = "a".repeat(40);
const line2 = "b".repeat(40);
const line3 = "c".repeat(40);
const content = `${line1}\n${line2}\n${line3}`;
const result = extractLinesWithByteLimit(content, 85);
expect(result.content).toBe(`${line1}\n${line2}\n`);
expect(result.wasLimited).toBe(true);
expect(result.linesRead).toBe(2);
});
it("should read exactly to limit when possible", () => {
const exactContent = "12345\n67890\n12345"; // 17 bytes total
const result = extractLinesWithByteLimit(exactContent, 17);
expect(result.content).toBe(exactContent);
expect(result.wasLimited).toBe(false);
expect(result.linesRead).toBe(3);
});
it("should handle Windows-style line endings", () => {
const windowsContent = "Line 1\r\nLine 2\r\nLine 3";
const result = extractLinesWithByteLimit(windowsContent, 1000);
// Note: split("\n") will keep the \r characters
expect(result.content).toBe("Line 1\r\nLine 2\r\nLine 3");
expect(result.linesRead).toBe(3);
});
it("should handle very large files efficiently", () => {
// Create a 100KB file
const largeLine = "x".repeat(1000);
const largeContent = Array(110).fill(largeLine).join("\n");
const result = extractLinesWithByteLimit(largeContent, 50000);
expect(result.wasLimited).toBe(true);
});
it("should allow at least one line even if it exceeds byte limit", () => {
const veryLongLine = "x".repeat(100000); // 100KB line
const result = extractLinesWithByteLimit(veryLongLine, 50000);
// Should return the line even though it exceeds the byte limit
// because we always allow at least one line if no lines have been added yet
expect(result.content).toBe(veryLongLine);
expect(result.linesRead).toBe(1);
expect(result.wasLimited).toBe(false);
});
});

View File

@@ -1,334 +0,0 @@
import { describe, it, expect } from "vitest";
import { replaceAndCalculateLocation } from "../mcp-server.js";
describe("replaceAndCalculateLocation", () => {
it("should replace first occurrence and return correct line number", () => {
const content = "line 1\nline 2 with text\nline 3 with text\nline 4";
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe("line 1\nline 2 with replaced\nline 3 with text\nline 4");
expect(result.lineNumbers).toEqual([1]); // Line 2 (0-based indexing)
});
it("should replace all occurrences when replaceAll is true", () => {
const content = "line 1\nline 2 with text\nline 3 with text\nline 4";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe("line 1\nline 2 with replaced\nline 3 with replaced\nline 4");
expect(result.lineNumbers).toEqual([1, 2]); // Lines 2 and 3 (0-based)
});
it("should return empty line numbers array when no match found", () => {
const content = "line 1\nline 2\nline 3";
expect(() => {
replaceAndCalculateLocation(content, [{ oldText: "notfound", newText: "replaced" }]);
}).toThrow('The provided `old_string` does not appear in the file: "notfound"');
});
it("should handle Windows line endings (CRLF)", () => {
const content = "line 1\r\nline 2 with text\r\nline 3 with text\r\nline 4";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe(
"line 1\r\nline 2 with replaced\r\nline 3 with replaced\r\nline 4",
);
expect(result.lineNumbers).toEqual([1, 2]);
});
it("should handle old Mac line endings (CR)", () => {
const content = "line 1\rline 2 with text\rline 3 with text\rline 4";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe("line 1\rline 2 with replaced\rline 3 with replaced\rline 4");
expect(result.lineNumbers).toEqual([1, 2]);
});
it("should handle mixed line endings", () => {
const content = "line 1\nline 2 with text\r\nline 3 with text\rline 4";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe("line 1\nline 2 with replaced\r\nline 3 with replaced\rline 4");
expect(result.lineNumbers).toEqual([1, 2]);
});
it("should handle text at the beginning of file", () => {
const content = "text at start\nline 2\nline 3";
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe("replaced at start\nline 2\nline 3");
expect(result.lineNumbers).toEqual([0]); // First line (0-based)
});
it("should handle text at the end of file", () => {
const content = "line 1\nline 2\nlast line with text";
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe("line 1\nline 2\nlast line with replaced");
expect(result.lineNumbers).toEqual([2]); // Last line (0-based)
});
it("should handle multiple occurrences on the same line", () => {
const content = "line 1\ntext text text\nline 3";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe("line 1\nreplaced replaced replaced\nline 3");
expect(result.lineNumbers).toEqual([1]); // All on line 2 (0-based), deduplicated
});
it("should handle empty file content", () => {
expect(() => {
replaceAndCalculateLocation("", [{ oldText: "text", newText: "replaced" }]);
}).toThrowError(
'The provided `old_string` does not appear in the file: "text".\n\nNo edits were applied.',
);
});
it("should handle empty search text", () => {
// Test with replaceAll false (default)
const content1 = "line 1\nline 2\nline 3";
expect(() => {
replaceAndCalculateLocation(content1, [{ oldText: "", newText: "replaced" }]);
}).toThrowError("The provided `old_string` is empty.\n\nNo edits were applied.");
// Test with replaceAll true on single line
const content2 = "abc";
expect(() => {
replaceAndCalculateLocation(content2, [{ oldText: "", newText: "X", replaceAll: true }]);
}).toThrowError("The provided `old_string` is empty.\n\nNo edits were applied.");
// Test with replaceAll true on multiline content
const content3 = "ab\ncd";
expect(() => {
replaceAndCalculateLocation(content3, [{ oldText: "", newText: "X", replaceAll: true }]);
}).toThrowError("The provided `old_string` is empty.\n\nNo edits were applied.");
});
it("should handle single line content", () => {
const content = "single line with text here";
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe("single line with replaced here");
expect(result.lineNumbers).toEqual([0]); // Line 1 (0-based)
});
it("should handle special characters in search text", () => {
const content = "line 1\nline with $special.chars*\nline 3";
const result = replaceAndCalculateLocation(content, [
{ oldText: "$special.chars*", newText: "replaced" },
]);
expect(result.newContent).toBe("line 1\nline with replaced\nline 3");
expect(result.lineNumbers).toEqual([1]);
});
it("should handle newlines in search text", () => {
const content = "line 1\nline 2\nline 3";
const result = replaceAndCalculateLocation(content, [
{ oldText: "1\nline", newText: "1\nmodified line" },
]);
expect(result.newContent).toBe("line 1\nmodified line 2\nline 3");
expect(result.lineNumbers).toEqual([0]); // Match starts at line 1 (0-based)
});
it("should handle newlines in replacement text", () => {
const content = "line 1\nline 2\nline 3";
const result = replaceAndCalculateLocation(content, [
{ oldText: "line 2", newText: "line 2a\nline 2b" },
]);
expect(result.newContent).toBe("line 1\nline 2a\nline 2b\nline 3");
expect(result.lineNumbers).toEqual([1]);
});
it("should handle very long lines", () => {
const longLine = "a".repeat(10000) + "text" + "b".repeat(10000);
const content = `line 1\n${longLine}\nline 3`;
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe(
`line 1\n${"a".repeat(10000)}replaced${"b".repeat(10000)}\nline 3`,
);
expect(result.lineNumbers).toEqual([1]);
});
it("should handle many lines", () => {
const lines = Array.from({ length: 1000 }, (_, i) => `line ${i}`);
lines[500] = "line with text";
const content = lines.join("\n");
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.lineNumbers).toEqual([500]);
expect(result.newContent).includes("line with replaced");
});
it("should handle overlapping matches correctly", () => {
const content = "aaaa\nbbbb\ncccc";
const result = replaceAndCalculateLocation(content, [
{ oldText: "aa", newText: "xx", replaceAll: true },
]);
// Should replace non-overlapping occurrences
expect(result.newContent).toBe("xxxx\nbbbb\ncccc");
expect(result.lineNumbers).toEqual([0]); // Two matches on first line, deduplicated
});
it("should preserve content after replacement with different lengths", () => {
const content = "short\nmedium line\nlong line here";
// Replacing with longer text
const result1 = replaceAndCalculateLocation(content, [
{ oldText: "short", newText: "very very long text" },
]);
expect(result1.newContent).toBe("very very long text\nmedium line\nlong line here");
expect(result1.lineNumbers).toEqual([0]);
// Replacing with shorter text
const result2 = replaceAndCalculateLocation(content, [
{ oldText: "medium line", newText: "m" },
]);
expect(result2.newContent).toBe("short\nm\nlong line here");
expect(result2.lineNumbers).toEqual([1]);
});
it("should handle consecutive replacements", () => {
const content = "text1 text2 text3";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
expect(result.newContent).toBe("replaced1 replaced2 replaced3");
expect(result.lineNumbers).toEqual([0]); // All on first line, deduplicated
});
it("should handle case-sensitive replacements", () => {
const content = "Text TEXT text";
const result = replaceAndCalculateLocation(content, [
{ oldText: "text", newText: "replaced", replaceAll: true },
]);
// Should only replace exact matches
expect(result.newContent).toBe("Text TEXT replaced");
expect(result.lineNumbers).toEqual([0]); // Only lowercase "text" matched
});
it("should handle replacement at exact end of line", () => {
const content = "line ends with text\nnext line";
const result = replaceAndCalculateLocation(content, [{ oldText: "text", newText: "replaced" }]);
expect(result.newContent).toBe("line ends with replaced\nnext line");
expect(result.lineNumbers).toEqual([0]);
});
it("should handle replacement spanning multiple lines", () => {
const content = "line 1\nspan\nacross\nlines\nline 5";
const result = replaceAndCalculateLocation(content, [
{ oldText: "span\nacross\nlines", newText: "single" },
]);
expect(result.newContent).toBe("line 1\nsingle\nline 5");
expect(result.lineNumbers).toEqual([1]); // Match starts at line 2 (0-based)
});
it("should default replaceAll to false", () => {
const content = "match match match";
// Without passing replaceAll parameter
const result = replaceAndCalculateLocation(content, [
{ oldText: "match", newText: "replaced" },
]);
expect(result.newContent).toBe("replaced match match");
expect(result.lineNumbers).toEqual([0]); // Only first match
});
it("should handle multiple edits with correct line numbers", () => {
const content = "line 1\nfoo bar\nline 3\nfoo baz\nline 5\nbar foo\nline 7";
const result = replaceAndCalculateLocation(content, [
{ oldText: "foo", newText: "FOO", replaceAll: true },
{ oldText: "bar", newText: "BAR", replaceAll: false },
{ oldText: "line 3", newText: "LINE THREE" },
]);
// Should replace:
// - All "foo" occurrences (lines 1, 3, 5 in original)
// - First "bar" occurrence (line 1 after first edit)
// - "line 3" (line 2 after previous edits)
expect(result.newContent).toBe("line 1\nFOO BAR\nLINE THREE\nFOO baz\nline 5\nbar FOO\nline 7");
// Line numbers reflect position in final content, deduplicated and sorted
expect(result.lineNumbers).toEqual([
1, // FOO and BAR on line 1
2, // LINE THREE on line 2
3, // FOO on line 3
5, // FOO on line 5
]);
});
it("should handle multiple edits with overlapping text", () => {
const content = "hello world\nhello hello\nworld hello world";
const result = replaceAndCalculateLocation(content, [
{ oldText: "hello", newText: "hi", replaceAll: false },
{ oldText: "world", newText: "earth", replaceAll: true },
{ oldText: "hello", newText: "greetings", replaceAll: true },
]);
// First edit replaces first "hello" only
// Second edit replaces all "world" in the modified content
// Third edit replaces remaining "hello"s in the modified content
expect(result.newContent).toBe("hi earth\ngreetings greetings\nearth greetings earth");
// Line numbers reflect position in final content, deduplicated and sorted
expect(result.lineNumbers).toEqual([
0, // hi and earth on line 0
1, // greetings (multiple) on line 1
2, // earth and greetings on line 2
]);
});
it("should handle complex scenarios with marker-like text", () => {
// Test that our marker approach doesn't get confused by similar text
const content = "line 1\n__MARKER__text\nline 3\n__REPLACE_MARKER_abc__\nline 5";
const result = replaceAndCalculateLocation(content, [
{ oldText: "__MARKER__", newText: "REPLACED", replaceAll: true },
{ oldText: "text", newText: "content" },
{ oldText: "__REPLACE_MARKER_abc__", newText: "DONE" },
]);
expect(result.newContent).toBe("line 1\nREPLACEDcontent\nline 3\nDONE\nline 5");
// Line numbers should be correct even with marker-like text
expect(result.lineNumbers).toEqual([
1, // REPLACED on line 1
3, // DONE on line 3
]);
});
it("should handle edits where newText matches subsequent oldText", () => {
const content = "foo\nbar\nbaz";
const result = replaceAndCalculateLocation(content, [
{ oldText: "foo", newText: "bar" },
{ oldText: "bar", newText: "baz", replaceAll: true },
{ oldText: "baz", newText: "qux", replaceAll: true },
]);
// First edit: foo -> bar
// Second edit: both original bar and new bar -> baz
// Third edit: all baz instances -> qux
expect(result.newContent).toBe("qux\nqux\nqux");
// All replacements end up on their respective lines
expect(result.lineNumbers).toEqual([0, 1, 2]);
});
});

View File

@@ -0,0 +1,57 @@
import { describe, it, expect, vi } from "vitest";
import { resolvePermissionMode, type Logger } from "../acp-agent.js";
function mockLogger() {
const error = vi.fn<(...args: any[]) => void>();
const log = vi.fn<(...args: any[]) => void>();
const logger: Logger = { log, error };
return { logger, error, log };
}
describe("resolvePermissionMode", () => {
it("returns 'default' when no mode is provided", () => {
expect(resolvePermissionMode()).toBe("default");
expect(resolvePermissionMode(undefined)).toBe("default");
});
it("resolves exact canonical modes", () => {
expect(resolvePermissionMode("default")).toBe("default");
expect(resolvePermissionMode("acceptEdits")).toBe("acceptEdits");
expect(resolvePermissionMode("dontAsk")).toBe("dontAsk");
expect(resolvePermissionMode("plan")).toBe("plan");
expect(resolvePermissionMode("bypassPermissions")).toBe("bypassPermissions");
});
it("resolves case-insensitive aliases", () => {
expect(resolvePermissionMode("DontAsk")).toBe("dontAsk");
expect(resolvePermissionMode("DONTASK")).toBe("dontAsk");
expect(resolvePermissionMode("AcceptEdits")).toBe("acceptEdits");
expect(resolvePermissionMode("bypass")).toBe("bypassPermissions");
});
it("trims whitespace", () => {
expect(resolvePermissionMode(" dontAsk ")).toBe("dontAsk");
});
it("falls back to 'default' and logs on non-string values", () => {
for (const value of [123, true, {}]) {
const { logger, error } = mockLogger();
expect(resolvePermissionMode(value, logger)).toBe("default");
expect(error).toHaveBeenCalledWith(expect.stringContaining("expected a string"));
}
});
it("falls back to 'default' and logs on empty string", () => {
for (const value of ["", " "]) {
const { logger, error } = mockLogger();
expect(resolvePermissionMode(value, logger)).toBe("default");
expect(error).toHaveBeenCalledWith(expect.stringContaining("expected a non-empty string"));
}
});
it("falls back to 'default' and logs on unknown mode", () => {
const { logger, error } = mockLogger();
expect(resolvePermissionMode("yolo", logger)).toBe("default");
expect(error).toHaveBeenCalledWith(expect.stringContaining("yolo"));
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,333 @@
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.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.resumeSession({
sessionId,
cwd: process.cwd(),
mcpServers: [],
}),
).rejects.toThrow(RequestError);
} finally {
await agentB.dispose();
}
}, 30000);
// Regression test for https://github.com/zed-industries/claude-code-acp/issues/579
// The client (Zed) renders its own local slash commands — e.g. `/model` —
// by injecting user-message prompts whose text is wrapped in
// `<command-name>` / `<local-command-stdout>` markers. The Claude SDK
// persists those messages verbatim in the session transcript. Without
// filtering, `loadSession` replays the markers as user_message_chunks
// ahead of the real prompt, leaking CLI internals into the transcript.
it("ACP: loadSession does not replay local-command metadata user messages", async () => {
const recordedUserChunks: string[] = [];
const client = {
sessionUpdate: async (notification: SessionNotification) => {
if (notification.update.sessionUpdate === "user_message_chunk") {
const content = notification.update.content;
if (content.type === "text") recordedUserChunks.push(content.text);
}
},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection;
const commandName =
"<command-name>/model</command-name>\n <command-message>model</command-message>\n <command-args>opus</command-args>";
const commandStdout =
"<local-command-stdout>Set model to opus (claude-opus-4-7)</local-command-stdout>";
// Step 1: create a session via the SDK, push the marker user messages
// followed by a real "hi" prompt. We bypass the ACP agent's prompt loop
// so we're only testing what the loadSession replay path does, not how
// prompts get routed.
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,
},
});
await q.initializationResult();
// Zed renders its local slash commands by mixing the marker blocks into
// the user's prompt content array alongside the real text. The Claude
// SDK persists the message verbatim — including the marker blocks —
// which is what loadSession must filter when it replays.
input.push({
type: "user",
message: {
role: "user",
content: [
{ type: "text", text: commandName },
{ type: "text", text: commandStdout },
{ type: "text", text: "hi" },
],
},
session_id: sessionId,
parent_tool_use_id: null,
});
for await (const msg of q) {
if (msg.type === "result") break;
}
input.end();
q.return(undefined);
// Sanity check: the SDK transcript contains the metadata we're filtering.
const sdkMessages = await getSessionMessages(sessionId);
const sdkTexts = sdkMessages
.map((m) => {
const c = (m as { message?: { content?: unknown } }).message?.content;
if (typeof c === "string") return c;
if (Array.isArray(c))
return c
.map((b) =>
b && typeof b === "object" && "text" in b
? String((b as { text: unknown }).text)
: "",
)
.join("");
return "";
})
.join("\n");
expect(sdkTexts).toContain("<command-name>");
expect(sdkTexts).toContain("<local-command-stdout>");
expect(sdkTexts).toContain("hi");
// Step 2: load the session through the ACP agent and confirm the markers
// never reach the client as user_message_chunks, while the real "hi"
// prompt does.
const agent = new ClaudeAcpAgent(client);
try {
await agent.loadSession({
sessionId,
cwd: process.cwd(),
mcpServers: [],
});
} finally {
await agent.dispose();
}
for (const chunk of recordedUserChunks) {
expect(chunk).not.toContain("<command-name>");
expect(chunk).not.toContain("<command-message>");
expect(chunk).not.toContain("<command-args>");
expect(chunk).not.toContain("<local-command-stdout>");
expect(chunk).not.toContain("<local-command-stderr>");
}
expect(recordedUserChunks.some((c) => c.includes("hi"))).toBe(true);
}, 60000);
// Second regression: the original issue showed the markers and the real
// "hi" prompt all concatenated into a single string ending with "hi".
// loadSession must strip the marker tags in-place rather than dropping the
// whole message.
it("ACP: loadSession strips marker tags from a concatenated single-string prompt", async () => {
const recordedUserChunks: string[] = [];
const client = {
sessionUpdate: async (notification: SessionNotification) => {
if (notification.update.sessionUpdate === "user_message_chunk") {
const content = notification.update.content;
if (content.type === "text") recordedUserChunks.push(content.text);
}
},
requestPermission: async () => ({ outcome: { outcome: "cancelled" } }),
readTextFile: async () => ({ content: "" }),
writeTextFile: async () => ({}),
} as unknown as AgentSideConnection;
// Exact shape from https://github.com/zed-industries/claude-code-acp/issues/579.
const concatenated =
"<command-name>/model</command-name>\n <command-message>model</command-message>\n <command-args>opus</command-args>" +
"<local-command-stdout>Set model to opus (claude-opus-4-7)</local-command-stdout>\n" +
"<command-name>/model</command-name>\n <command-message>model</command-message>\n <command-args>opus[1m]</command-args>" +
"<local-command-stdout>Set model to opus[1m] (claude-opus-4-7[1m])</local-command-stdout>" +
"hi";
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,
},
});
await q.initializationResult();
input.push({
type: "user",
message: { role: "user", content: concatenated },
session_id: sessionId,
parent_tool_use_id: null,
});
for await (const msg of q) {
if (msg.type === "result") break;
}
input.end();
q.return(undefined);
const agent = new ClaudeAcpAgent(client);
try {
await agent.loadSession({
sessionId,
cwd: process.cwd(),
mcpServers: [],
});
} finally {
await agent.dispose();
}
expect(recordedUserChunks.length).toBeGreaterThan(0);
for (const chunk of recordedUserChunks) {
expect(chunk).not.toContain("<command-name>");
expect(chunk).not.toContain("<command-message>");
expect(chunk).not.toContain("<command-args>");
expect(chunk).not.toContain("<local-command-stdout>");
expect(chunk).not.toContain("<local-command-stderr>");
}
expect(recordedUserChunks.some((c) => c.includes("hi"))).toBe(true);
}, 60000);
});

View File

@@ -17,548 +17,50 @@ describe("SettingsManager", () => {
await fs.promises.rm(tempDir, { recursive: true, force: true });
});
describe("permission checking", () => {
it("should return 'ask' when no settings exist", async () => {
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const result = settingsManager.checkPermission("mcp__acp__Read", {
file_path: "/some/file.txt",
});
expect(result.decision).toBe("ask");
});
it("should return 'ask' for non-ACP tools (permission checks only apply to mcp__acp__* tools)", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Read"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// Non-ACP tools should always return 'ask' regardless of rules
const result = settingsManager.checkPermission("Read", { file_path: "/some/file.txt" });
expect(result.decision).toBe("ask");
});
it("should allow tool use when matching allow rule exists", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const result = settingsManager.checkPermission("mcp__acp__Read", {
file_path: "/some/file.txt",
});
expect(result.decision).toBe("allow");
expect(result.rule).toBe("Read");
});
it("should deny tool use when matching deny rule exists", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Read(./.env)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const result = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env"),
});
expect(result.decision).toBe("deny");
expect(result.rule).toBe("Read(./.env)");
});
it("should prioritize deny rules over allow rules", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read"],
deny: ["Read(./.env)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// .env should be denied
const envResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env"),
});
expect(envResult.decision).toBe("deny");
// other files should be allowed
const otherResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, "other.txt"),
});
expect(otherResult.decision).toBe("allow");
});
it("should handle ACP-prefixed tool names", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const result = settingsManager.checkPermission("mcp__acp__Read", {
file_path: "/some/file.txt",
});
expect(result.decision).toBe("allow");
});
});
describe("Bash permission rules", () => {
it("should match exact Bash commands without :* wildcard", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
// Per docs: Bash(npm run build) matches the EXACT command "npm run build"
allow: ["Bash(npm run lint)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// Exact match should be allowed
const exactResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run lint",
});
expect(exactResult.decision).toBe("allow");
// Command with extra arguments should NOT match (exact match only)
const withArgsResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run lint --fix",
});
expect(withArgsResult.decision).toBe("ask");
// Similar command should NOT match (exact match only)
const similarResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run linting",
});
expect(similarResult.decision).toBe("ask");
// Different command should not match
const differentResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run test",
});
expect(differentResult.decision).toBe("ask");
});
it("should match Bash commands with :* wildcard suffix (prefix matching)", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
// The :* suffix is a convention to make prefix matching explicit
allow: ["Bash(npm run:*)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// Any command starting with "npm run" should match (prefix matching with :*)
const lintResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run lint",
});
expect(lintResult.decision).toBe("allow");
const testResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run test",
});
expect(testResult.decision).toBe("allow");
// Commands with additional args also match
const withArgsResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm run test --watch",
});
expect(withArgsResult.decision).toBe("allow");
// Non-matching command
const installResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "npm install",
});
expect(installResult.decision).toBe("ask");
});
it("should not allow shell operators to bypass prefix matching", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Bash(safe-cmd:*)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// Normal prefix match should work
const normalResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd --flag",
});
expect(normalResult.decision).toBe("allow");
// Shell operators should NOT be allowed (per docs: Claude Code is aware of shell operators)
const andResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd && malicious-cmd",
});
expect(andResult.decision).toBe("ask");
const orResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd || malicious-cmd",
});
expect(orResult.decision).toBe("ask");
const semicolonResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd; malicious-cmd",
});
expect(semicolonResult.decision).toBe("ask");
const pipeResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd | malicious-cmd",
});
expect(pipeResult.decision).toBe("ask");
const subshellResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd $(malicious-cmd)",
});
expect(subshellResult.decision).toBe("ask");
const backtickResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd `malicious-cmd`",
});
expect(backtickResult.decision).toBe("ask");
const newlineResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "safe-cmd\nmalicious-cmd",
});
expect(newlineResult.decision).toBe("ask");
});
it("should deny dangerous Bash commands", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Bash(curl:*)", "Bash(wget:*)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const curlResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "curl https://example.com",
});
expect(curlResult.decision).toBe("deny");
const wgetResult = settingsManager.checkPermission("mcp__acp__Bash", {
command: "wget https://example.com",
});
expect(wgetResult.decision).toBe("deny");
const lsResult = settingsManager.checkPermission("mcp__acp__Bash", { command: "ls -la" });
expect(lsResult.decision).toBe("ask");
});
});
describe("file path glob matching", () => {
it("should match exact file paths", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Read(./.env)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const envResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env"),
});
expect(envResult.decision).toBe("deny");
const otherResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".envrc"),
});
expect(otherResult.decision).toBe("ask");
});
it("should match glob patterns with single wildcard", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Read(./.env.*)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const envLocalResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env.local"),
});
expect(envLocalResult.decision).toBe("deny");
const envProdResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env.production"),
});
expect(envProdResult.decision).toBe("deny");
// Plain .env should not match .env.*
const plainEnvResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env"),
});
expect(plainEnvResult.decision).toBe("ask");
});
it("should match glob patterns with double wildcard (recursive)", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Read(./secrets/**)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const secretResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, "secrets", "api-key.txt"),
});
expect(secretResult.decision).toBe("deny");
const nestedSecretResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, "secrets", "deep", "nested", "key.txt"),
});
expect(nestedSecretResult.decision).toBe("deny");
const otherResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, "public", "file.txt"),
});
expect(otherResult.decision).toBe("ask");
});
it("should handle home directory expansion", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read(~/.zshrc)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const zshrcResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(os.homedir(), ".zshrc"),
});
expect(zshrcResult.decision).toBe("allow");
});
});
describe("settings merging", () => {
it("should merge project and local settings", async () => {
it("should merge model setting with later sources taking precedence", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
// Project settings
// Project settings with one model
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read"],
},
model: "claude-3-5-sonnet",
}),
);
// Local settings
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
let settings = settingsManager.getSettings();
expect(settings.model).toBe("claude-3-5-sonnet");
// Add local settings that override the model
await fs.promises.writeFile(
path.join(claudeDir, "settings.local.json"),
JSON.stringify({
permissions: {
deny: ["Read(./.env)"],
},
model: "claude-3-5-haiku",
}),
);
// Re-initialize to pick up local settings
settingsManager.dispose();
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
// Read should be allowed in general
const readResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, "file.txt"),
});
expect(readResult.decision).toBe("allow");
// But .env should be denied (local settings take precedence)
const envResult = settingsManager.checkPermission("mcp__acp__Read", {
file_path: path.join(tempDir, ".env"),
});
expect(envResult.decision).toBe("deny");
settings = settingsManager.getSettings();
expect(settings.model).toBe("claude-3-5-haiku");
});
});
describe("ask rules", () => {
it("should return 'ask' for matching ask rules", async () => {
it("should expose availableModels from settings", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
ask: ["Bash(git push:*)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const result = settingsManager.checkPermission("mcp__acp__Bash", {
command: "git push origin main",
});
expect(result.decision).toBe("ask");
expect(result.rule).toBe("Bash(git push:*)");
});
});
describe("Edit and Write tools", () => {
it("should handle Edit tool permissions", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
deny: ["Edit(./package-lock.json)"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const lockFileResult = settingsManager.checkPermission("mcp__acp__Edit", {
file_path: path.join(tempDir, "package-lock.json"),
});
expect(lockFileResult.decision).toBe("deny");
const otherResult = settingsManager.checkPermission("mcp__acp__Edit", {
file_path: path.join(tempDir, "package.json"),
});
expect(otherResult.decision).toBe("ask");
});
it("should handle mcp__acp__Edit and mcp__acp__Write tool names", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Edit", "Write"],
},
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const editResult = settingsManager.checkPermission("mcp__acp__Edit", {
file_path: "/some/file.ts",
});
expect(editResult.decision).toBe("allow");
const writeResult = settingsManager.checkPermission("mcp__acp__Write", {
file_path: "/some/file.ts",
});
expect(writeResult.decision).toBe("allow");
});
});
describe("getSettings", () => {
it("should return merged settings", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read", "Bash(npm:*)"],
deny: ["Read(./.env)"],
},
env: {
FOO: "bar",
},
availableModels: ["claude-haiku-4-5", "claude-opus-4-7[1m]"],
}),
);
@@ -566,22 +68,51 @@ describe("SettingsManager", () => {
await settingsManager.initialize();
const settings = settingsManager.getSettings();
expect(settings.permissions?.allow).toContain("Read");
expect(settings.permissions?.allow).toContain("Bash(npm:*)");
expect(settings.permissions?.deny).toContain("Read(./.env)");
expect(settings.env?.FOO).toBe("bar");
expect(settings.availableModels).toEqual(["claude-haiku-4-5", "claude-opus-4-7[1m]"]);
});
});
describe("setCwd", () => {
it("should reload settings when cwd changes", async () => {
const claudeDir1 = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir1, { recursive: true });
it("should union and dedupe availableModels across sources", async () => {
// Per Claude Code docs: "When `availableModels` is set at multiple
// levels, such as user settings and project settings, arrays are
// merged and deduplicated."
// https://code.claude.com/docs/en/model-config#merge-behavior
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir1, "settings.json"),
path.join(claudeDir, "settings.json"),
JSON.stringify({
availableModels: ["claude-haiku-4-5", "claude-opus-4-7[1m]"],
}),
);
await fs.promises.writeFile(
path.join(claudeDir, "settings.local.json"),
JSON.stringify({
// claude-opus-4-7[1m] overlaps with project; should be deduped.
availableModels: ["claude-opus-4-7[1m]", "claude-sonnet-4-6[1m]"],
}),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
const settings = settingsManager.getSettings();
expect(settings.availableModels).toEqual([
"claude-haiku-4-5",
"claude-opus-4-7[1m]",
"claude-sonnet-4-6[1m]",
]);
});
it("should merge permissions.defaultMode with later sources taking precedence", async () => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({
permissions: {
allow: ["Read"],
defaultMode: "dontAsk",
},
}),
);
@@ -589,29 +120,87 @@ describe("SettingsManager", () => {
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
let result = settingsManager.checkPermission("mcp__acp__Read", { file_path: "/file.txt" });
expect(result.decision).toBe("allow");
let settings = settingsManager.getSettings();
expect(settings.permissions?.defaultMode).toBe("dontAsk");
// Create a new temp directory with different settings
const tempDir2 = await fs.promises.mkdtemp(path.join(os.tmpdir(), "settings-test-2-"));
const claudeDir2 = path.join(tempDir2, ".claude");
await fs.promises.mkdir(claudeDir2, { recursive: true });
// Local settings override the mode
await fs.promises.writeFile(
path.join(claudeDir2, "settings.json"),
path.join(claudeDir, "settings.local.json"),
JSON.stringify({
permissions: {
deny: ["Read"],
defaultMode: "plan",
},
}),
);
await settingsManager.setCwd(tempDir2);
settingsManager.dispose();
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
result = settingsManager.checkPermission("mcp__acp__Read", { file_path: "/file.txt" });
expect(result.decision).toBe("deny");
settings = settingsManager.getSettings();
expect(settings.permissions?.defaultMode).toBe("plan");
});
});
// Cleanup second temp dir
await fs.promises.rm(tempDir2, { recursive: true, force: true });
describe("escalating defaultMode trust filter", () => {
// The SDK's filterEscalatingDefaultMode drops escalating values
// (bypassPermissions / auto / acceptEdits) that came from a repo-committed
// tier (.claude/settings.json), preventing a checked-in file from
// silently escalating permissions. Local (.claude/settings.local.json)
// and user-tier sources are not committed by convention, so escalating
// values from those tiers are preserved.
it.each(["bypassPermissions", "auto", "acceptEdits"] as const)(
"drops %s when set in project-tier settings",
async (mode) => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({ permissions: { defaultMode: mode } }),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
expect(settingsManager.getSettings().permissions?.defaultMode).toBeUndefined();
},
);
it.each(["plan", "dontAsk"] as const)(
"preserves non-escalating %s from project-tier settings",
async (mode) => {
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.json"),
JSON.stringify({ permissions: { defaultMode: mode } }),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
expect(settingsManager.getSettings().permissions?.defaultMode).toBe(mode);
},
);
it("preserves escalating defaultMode when it comes from local-tier settings", async () => {
// settings.local.json is git-ignored by convention, so the trust
// filter does not apply.
const claudeDir = path.join(tempDir, ".claude");
await fs.promises.mkdir(claudeDir, { recursive: true });
await fs.promises.writeFile(
path.join(claudeDir, "settings.local.json"),
JSON.stringify({ permissions: { defaultMode: "acceptEdits" } }),
);
settingsManager = new SettingsManager(tempDir);
await settingsManager.initialize();
expect(settingsManager.getSettings().permissions?.defaultMode).toBe("acceptEdits");
});
});
});

1950
src/tests/tools.test.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,7 @@
import { Readable, Writable } from "node:stream";
import { WritableStream, ReadableStream } from "node:stream/web";
import { readFileSync } from "node:fs";
import { Logger } from "./acp-agent.js";
import { ClaudeCodeSettings, getManagedSettingsPath } from "./settings.js";
// Useful for bridging push-based and async-iterator-based code.
export class Pushable<T> implements AsyncIterable<T> {
@@ -89,83 +87,3 @@ export function unreachable(value: never, logger: Logger = console) {
export function sleep(time: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, time));
}
export function loadManagedSettings(): ClaudeCodeSettings | null {
try {
return JSON.parse(readFileSync(getManagedSettingsPath(), "utf8")) as ClaudeCodeSettings;
} catch {
return null;
}
}
export function applyEnvironmentSettings(settings: ClaudeCodeSettings): void {
if (settings.env) {
for (const [key, value] of Object.entries(settings.env)) {
process.env[key] = value;
}
}
}
export interface ExtractLinesResult {
content: string;
wasLimited: boolean;
linesRead: number;
}
/**
* Extracts lines from file content with byte limit enforcement.
*
* @param fullContent - The complete file content
* @param maxContentLength - Maximum number of UTF-16 Code Units to return
* @returns Object containing extracted content and metadata
*/
export function extractLinesWithByteLimit(
fullContent: string,
maxContentLength: number,
): ExtractLinesResult {
if (fullContent === "") {
return {
content: "",
wasLimited: false,
linesRead: 1,
};
}
let linesSeen = 0;
let index = 0;
linesSeen = 0;
let contentLength = 0;
let wasLimited = false;
while (true) {
const nextIndex = fullContent.indexOf("\n", index);
if (nextIndex < 0) {
// Last line in file (no trailing newline)
if (linesSeen > 0 && fullContent.length > maxContentLength) {
wasLimited = true;
break;
}
linesSeen += 1;
contentLength = fullContent.length;
break;
} else {
// Line with newline - include up to the newline
const newContentLength = nextIndex + 1;
if (linesSeen > 0 && newContentLength > maxContentLength) {
wasLimited = true;
break;
}
linesSeen += 1;
contentLength = newContentLength;
index = newContentLength;
}
}
return {
content: fullContent.slice(0, contentLength),
wasLimited,
linesRead: linesSeen,
};
}

View File

@@ -1,15 +1,17 @@
{
"compilerOptions": {
"target": "ES2020",
"target": "ES2021",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2020"],
"lib": ["ES2021"],
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src"
"rootDir": "src",
"declaration": true,
"declarationMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]