Files
claude-agent-acp/src/session-model.ts
dependabot[bot] 49858b5273 feat(deps): Bump @anthropic-ai/claude-agent-sdk to 0.3.283 (#1186)
Bumps the minor group with 38 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@anthropic-ai/claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-typescript)
| `0.3.280` | `0.3.282` |
|
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
| `0.127.0` | `0.128.0` |
| [prettier](https://github.com/prettier/prettier) | `3.9.8` | `3.9.9` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `5.0.1` | `5.0.2` |
| @anthropic-ai/claude-agent-sdk-darwin-arm64 | `0.3.280` | `0.3.282` |
| @anthropic-ai/claude-agent-sdk-darwin-x64 | `0.3.280` | `0.3.282` |
| @anthropic-ai/claude-agent-sdk-linux-arm64 | `0.3.280` | `0.3.282` |
| @anthropic-ai/claude-agent-sdk-linux-arm64-musl | `0.3.280` |
`0.3.282` |
| @anthropic-ai/claude-agent-sdk-linux-x64 | `0.3.280` | `0.3.282` |
| @anthropic-ai/claude-agent-sdk-linux-x64-musl | `0.3.280` | `0.3.282`
|
| @anthropic-ai/claude-agent-sdk-win32-arm64 | `0.3.280` | `0.3.282` |
| @anthropic-ai/claude-agent-sdk-win32-x64 | `0.3.280` | `0.3.282` |
|
[@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk)
| `1.30.0` | `1.30.1` |
|
[@oxc-project/types](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types)
| `0.150.0` | `0.151.0` |
|
[@rolldown/binding-android-arm-eabi](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-android-arm64](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-darwin-arm64](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-darwin-x64](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-freebsd-x64](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-arm-gnueabihf](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-arm64-gnu](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-arm64-musl](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-ppc64-gnu](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-s390x-gnu](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-x64-gnu](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-linux-x64-musl](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-openharmony-arm64](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-win32-arm64-msvc](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@rolldown/binding-win32-x64-msvc](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
|
[@vitest/mocker](https://github.com/vitest-dev/vitest/tree/HEAD/packages/mocker)
| `5.0.1` | `5.0.2` |
|
[@vitest/spy](https://github.com/vitest-dev/vitest/tree/HEAD/packages/spy)
| `5.0.1` | `5.0.2` |
| [hono](https://github.com/honojs/hono) | `4.13.8` | `4.13.10` |
| [magic-string](https://github.com/Rich-Harris/magic-string) | `1.4.1`
| `1.4.2` |
|
[rolldown](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)
| `1.2.9` | `1.2.11` |
| [tinybench](https://github.com/tinylibs/tinybench) | `6.1.4` | `6.2.0`
|
| [tinyexec](https://github.com/tinylibs/tinyexec) | `1.3.0` | `1.3.1` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.3.0` | `8.3.1` |
|
[why-is-node-running](https://github.com/mafintosh/why-is-node-running)
| `2.3.0` | `3.2.2` |


Updates `@anthropic-ai/claude-agent-sdk` from 0.3.280 to 0.3.282
<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.282</h2>
<h2>What's changed</h2>
<ul>
<li>Added support for <code>strictKnownMarketplaces</code> and
<code>blockedMarketplaces</code> in host-supplied
<code>managedSettings</code>: the allowlist applies only where admin
policy sets none; the blocklist adds to the admin's</li>
<li>Added <code>@anthropic-ai/claude-agent-sdk/core</code>, a smaller
entry point for apps that bundle the SDK (query, MCP tool helpers,
session mutations, <code>resolveSettings</code>); it uses your installed
zod and MCP SDK</li>
<li>Added <code>prewarm()</code> and <code>SpareProcess.claim()</code>
(alpha): start a Claude Code process before its session is known and
bind it to a folder and its per-session options later</li>
<li>Fixed <code>readMcpResource()</code> relaying content
<code>_meta</code> keys under the CLI-reserved
<code>com.anthropic/</code> prefix; they are now dropped, as for tool
results</li>
<li>Updated to parity with Claude Code v2.1.282</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.282
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.282
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.282
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.282
</code></pre>
<h2>v0.3.281</h2>
<h2>What's changed</h2>
<ul>
<li>Added optional <code>trigger</code>, <code>user_message_uuid</code>
and <code>timestamp</code> fields to the <code>conversation_reset</code>
message so clients can tell what reset the conversation, match a /clear
to its message, and show when the reset happened</li>
<li>Fixed permission and dialog callbacks still being invoked for
requests that arrived after <code>close()</code></li>
<li>Fixed control requests issued after a query closed hanging or
leaking, and permission prompts that could not be cancelled after a
cancelled request was redelivered</li>
<li>Fixed <code>session_state_changed</code> staying at
<code>requires_action</code> after an overlapping permission prompt and
sandbox network-access prompt were both answered</li>
<li>Improved SDK package size and load time: <code>sdk.mjs</code> no
longer bundles unused dependencies (1.47 MB → 0.97 MB)</li>
<li>Improved startup time for <code>query()</code> sessions with
in-process MCP servers (<code>createSdkMcpServer</code>) by running
their handshake inside the SDK; <code>initialize</code> may now wait up
to 250 ms for them</li>
<li>Improved SDK session start-up: the CLI now answers the host's
initialize request before starting its background start-up work</li>
<li>Changed the <code>Settings</code> type's <code>attribution</code>
field to <code>boolean | {...}</code>; TypeScript code that reads
<code>attribution.commit</code> from returned settings needs a type
narrow</li>
<li>Updated to parity with Claude Code v2.1.281</li>
</ul>
<h2>Update</h2>
<pre lang="sh"><code>npm install @anthropic-ai/claude-agent-sdk@0.3.281
# or
yarn add @anthropic-ai/claude-agent-sdk@0.3.281
# or
pnpm add @anthropic-ai/claude-agent-sdk@0.3.281
# or
bun add @anthropic-ai/claude-agent-sdk@0.3.281
</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">@​anthropic-ai/claude-agent-sdk's
changelog</a>.</em></p>
<blockquote>
<h2>0.3.282</h2>
<ul>
<li>Added support for <code>strictKnownMarketplaces</code> and
<code>blockedMarketplaces</code> in host-supplied
<code>managedSettings</code>: the allowlist applies only where admin
policy sets none; the blocklist adds to the admin's</li>
<li>Added <code>@anthropic-ai/claude-agent-sdk/core</code>, a smaller
entry point for apps that bundle the SDK (query, MCP tool helpers,
session mutations, <code>resolveSettings</code>); it uses your installed
zod and MCP SDK</li>
<li>Added <code>prewarm()</code> and <code>SpareProcess.claim()</code>
(alpha): start a Claude Code process before its session is known and
bind it to a folder and its per-session options later</li>
<li>Fixed <code>readMcpResource()</code> relaying content
<code>_meta</code> keys under the CLI-reserved
<code>com.anthropic/</code> prefix; they are now dropped, as for tool
results</li>
<li>Updated to parity with Claude Code v2.1.282</li>
</ul>
<h2>0.3.281</h2>
<ul>
<li>Added optional <code>trigger</code>, <code>user_message_uuid</code>
and <code>timestamp</code> fields to the <code>conversation_reset</code>
message so clients can tell what reset the conversation, match a /clear
to its message, and show when the reset happened</li>
<li>Fixed permission and dialog callbacks still being invoked for
requests that arrived after <code>close()</code></li>
<li>Fixed control requests issued after a query closed hanging or
leaking, and permission prompts that could not be cancelled after a
cancelled request was redelivered</li>
<li>Fixed <code>session_state_changed</code> staying at
<code>requires_action</code> after an overlapping permission prompt and
sandbox network-access prompt were both answered</li>
<li>Improved SDK package size and load time: <code>sdk.mjs</code> no
longer bundles unused dependencies (1.47 MB → 0.97 MB)</li>
<li>Improved startup time for <code>query()</code> sessions with
in-process MCP servers (<code>createSdkMcpServer</code>) by running
their handshake inside the SDK; <code>initialize</code> may now wait up
to 250 ms for them</li>
<li>Improved SDK session start-up: the CLI now answers the host's
initialize request before starting its background start-up work</li>
<li>Changed the <code>Settings</code> type's <code>attribution</code>
field to <code>boolean | {...}</code>; TypeScript code that reads
<code>attribution.commit</code> from returned settings needs a type
narrow</li>
<li>Updated to parity with Claude Code v2.1.281</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9e477a178c"><code>9e477a1</code></a>
chore: Update CHANGELOG.md</li>
<li><a
href="fb04f66354"><code>fb04f66</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.280...v0.3.282">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/sdk` from 0.127.0 to 0.128.0
<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.128.0</h2>
<h2>0.128.0 (2026-09-22)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.127.0...sdk-v0.128.0">sdk-v0.127.0...sdk-v0.128.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add support for claude-opus-5-5, inline tool
definitions and MCP tool-list pinning (beta) (<a
href="eff27483d2">eff2748</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> share one evaluated_permission enum across
Managed Agents events (<a
href="0c1cc0fdf8">0c1cc0f</a>)</li>
<li><strong>tools:</strong> addTools() takes effect straight away (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/773">#773</a>)
(<a
href="1ccdad0d1b">1ccdad0</a>)</li>
<li><strong>tools:</strong> leave reply-only params off the tool
runner's compaction request (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/769">#769</a>)
(<a
href="8afc3364dc">8afc336</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>docs:</strong> add descriptions to the Dreams API reference
(<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> add descriptions to the User Profiles API
reference (<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> add memory store descriptions to the Managed
Agents API reference (<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> improve descriptions in the Dreams API
reference (<a
href="971c54a5dd">971c54a</a>)</li>
<li><strong>docs:</strong> simplify the session thread agent type
description (<a
href="ccf71a27bd">ccf71a2</a>)</li>
<li><strong>docs:</strong> update diagnostics field descriptions on beta
messages (<a
href="c0b8746679">c0b8746</a>)</li>
<li><strong>internal:</strong> add property-based tests for partial JSON
parsing (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/776">#776</a>)
(<a
href="3ffac0927f">3ffac09</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.128.0 (2026-09-22)</h2>
<p>Full Changelog: <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.127.0...sdk-v0.128.0">sdk-v0.127.0...sdk-v0.128.0</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> add support for claude-opus-5-5, inline tool
definitions and MCP tool-list pinning (beta) (<a
href="eff27483d2">eff2748</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>api:</strong> share one evaluated_permission enum across
Managed Agents events (<a
href="0c1cc0fdf8">0c1cc0f</a>)</li>
<li><strong>tools:</strong> addTools() takes effect straight away (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/773">#773</a>)
(<a
href="1ccdad0d1b">1ccdad0</a>)</li>
<li><strong>tools:</strong> leave reply-only params off the tool
runner's compaction request (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/769">#769</a>)
(<a
href="8afc3364dc">8afc336</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>docs:</strong> add descriptions to the Dreams API reference
(<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> add descriptions to the User Profiles API
reference (<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> add memory store descriptions to the Managed
Agents API reference (<a
href="ea4ddd1ee3">ea4ddd1</a>)</li>
<li><strong>docs:</strong> improve descriptions in the Dreams API
reference (<a
href="971c54a5dd">971c54a</a>)</li>
<li><strong>docs:</strong> simplify the session thread agent type
description (<a
href="ccf71a27bd">ccf71a2</a>)</li>
<li><strong>docs:</strong> update diagnostics field descriptions on beta
messages (<a
href="c0b8746679">c0b8746</a>)</li>
<li><strong>internal:</strong> add property-based tests for partial JSON
parsing (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/776">#776</a>)
(<a
href="3ffac0927f">3ffac09</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1926adb4d2"><code>1926adb</code></a>
Merge pull request <a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/1208">#1208</a>
from anthropics/release-please--branches--main--chan...</li>
<li><a
href="162c8b125d"><code>162c8b1</code></a>
chore: release main</li>
<li><a
href="3ffac0927f"><code>3ffac09</code></a>
chore(internal): add property-based tests for partial JSON parsing (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/776">#776</a>)</li>
<li><a
href="e40ce277c2"><code>e40ce27</code></a>
test(ecosystem): check that unused imports tree-shake to nothing</li>
<li><a
href="1ccdad0d1b"><code>1ccdad0</code></a>
fix(tools): addTools() takes effect straight away (<a
href="https://redirect.github.com/anthropics/anthropic-sdk-typescript/issues/773">#773</a>)</li>
<li><a
href="8afc3364dc"><code>8afc336</code></a>
fix(tools): leave reply-only params off the tool runner's compaction
request ...</li>
<li><a
href="eff27483d2"><code>eff2748</code></a>
feat(api): add support for claude-opus-5-5, inline tool definitions and
MCP t...</li>
<li><a
href="06e5f9b5d1"><code>06e5f9b</code></a>
codegen metadata</li>
<li><a
href="0c1cc0fdf8"><code>0c1cc0f</code></a>
fix(api): share one evaluated_permission enum across Managed Agents
events</li>
<li><a
href="c0b8746679"><code>c0b8746</code></a>
chore(docs): update diagnostics field descriptions on beta messages</li>
<li>Additional commits viewable in <a
href="https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.127.0...sdk-v0.128.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `prettier` from 3.9.8 to 3.9.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>3.9.9</h2>
<ul>
<li>Markdown: Fix text with <code>$</code> been incorrectly parsed as
math syntax (<a
href="https://redirect.github.com/prettier/prettier/pull/20140">#20140</a>
by <a href="https://github.com/fisker"><code>@​fisker</code></a>)</li>
</ul>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/3.9.9/CHANGELOG.md#399">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>3.9.9</h1>
<p><a
href="https://github.com/prettier/prettier/compare/3.9.8...3.9.9">diff</a></p>
<h4>Markdown: Fix text with <code>$</code> been incorrectly parsed as
math syntax (<a
href="https://redirect.github.com/prettier/prettier/pull/20140">#20140</a>
by <a href="https://github.com/fisker"><code>@​fisker</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="md"><code>&lt;!-- Input --&gt;
**Uses $FOO** from `a.sh` and `b.sh`, plus `$BAR` from `c.sh`, before
anything else runs here.
<p>&lt;!-- Prettier 3.9.8 --&gt;<br />
<strong>Uses $FOO</strong> from <code>a.sh</code> and <code>b.sh</code>,
plus <code>$BAR</code>from<code>c.sh</code>, before anything else runs
here.</p>
<p>&lt;!-- Prettier 3.9.9 --&gt;<br />
<strong>Uses $FOO</strong> from <code>a.sh</code> and <code>b.sh</code>,
plus <code>$BAR</code> from <code>c.sh</code>, before anything else runs
here.<br />
</code></pre></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="cdd17f2288"><code>cdd17f2</code></a>
Release 3.9.9</li>
<li><a
href="dc7b8968e6"><code>dc7b896</code></a>
Disable <code>singleDollarTextMath</code> in
<code>mdast-util-math</code> (<a
href="https://redirect.github.com/prettier/prettier/issues/20140">#20140</a>)</li>
<li><a
href="f9be58fb8e"><code>f9be58f</code></a>
Git blame ignore 3.9.8</li>
<li><a
href="88470cb79c"><code>88470cb</code></a>
Bump Prettier dependency to 3.9.8</li>
<li><a
href="9559cab39e"><code>9559cab</code></a>
Clean changelog_unreleased</li>
<li><a
href="4fc8ee8746"><code>4fc8ee8</code></a>
Update dependents count</li>
<li>See full diff in <a
href="https://github.com/prettier/prettier/compare/3.9.8...3.9.9">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 5.0.1 to 5.0.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>v5.0.2</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Bind <code>process</code> in case global is overwritten  -  by <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11343">vitest-dev/vitest#11343</a>
<a href="https://github.com/vitest-dev/vitest/commit/0b79231ad"><!-- raw
HTML omitted -->(0b792)<!-- raw HTML omitted --></a></li>
<li><strong>detect-async-leaks</strong>:
<ul>
<li>Ignore <code>process.stdio</code> handles  -  by <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11333">vitest-dev/vitest#11333</a>
<a href="https://github.com/vitest-dev/vitest/commit/0fd6b9790"><!-- raw
HTML omitted -->(0fd6b)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>expect</strong>:
<ul>
<li>Fix <code>toMatchObject</code> with asymmetric matchers  -  by <a
href="https://github.com/ShreeBohara"><code>@​ShreeBohara</code></a>,
<strong>Claude Opus 5</strong>, <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>Codex (GPT-5)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11100">vitest-dev/vitest#11100</a>
<a href="https://github.com/vitest-dev/vitest/commit/42523289e"><!-- raw
HTML omitted -->(42523)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>jsdom</strong>:
<ul>
<li>Fix <code>Request</code> with <code>Blob</code> body on jsdom 28+
 -  by <a
href="https://github.com/harshit-d3v"><code>@​harshit-d3v</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/11295">vitest-dev/vitest#11295</a>
<a href="https://github.com/vitest-dev/vitest/commit/d1c3ecc93"><!-- raw
HTML omitted -->(d1c3e)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>reporter</strong>:
<ul>
<li><code>agent</code> to respect <code>--silent</code>  -  by <a
href="https://github.com/Raj4478"><code>@​Raj4478</code></a> and <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11271">vitest-dev/vitest#11271</a>
<a href="https://github.com/vitest-dev/vitest/commit/5b95efb6d"><!-- raw
HTML omitted -->(5b95e)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>reporters</strong>:
<ul>
<li>Handle concurrent <code>createReport</code> calls  -  by <a
href="https://github.com/7rulnik"><code>@​7rulnik</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11278">vitest-dev/vitest#11278</a>
<a href="https://github.com/vitest-dev/vitest/commit/e8e556ff7"><!-- raw
HTML omitted -->(e8e55)<!-- raw HTML omitted --></a></li>
<li><code>hanging-process</code> to use ESM entrypoint  -  by <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11316">vitest-dev/vitest#11316</a>
<a href="https://github.com/vitest-dev/vitest/commit/4e91e5668"><!-- raw
HTML omitted -->(4e91e)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>spy</strong>:
<ul>
<li>Fix stack overflow when spying <code>Set.prototype.add</code>  -  by
<a href="https://github.com/fengmk2"><code>@​fengmk2</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11299">vitest-dev/vitest#11299</a>
<a href="https://github.com/vitest-dev/vitest/commit/a0a939653"><!-- raw
HTML omitted -->(a0a93)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>ui</strong>:
<ul>
<li>Persist authentication cookie beyond current browser session  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode
(gpt-5.6-sol)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/11066">vitest-dev/vitest#11066</a>
<a href="https://github.com/vitest-dev/vitest/commit/f88195e16"><!-- raw
HTML omitted -->(f8819)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v5.0.1...v5.0.2">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="428e2e5043"><code>428e2e5</code></a>
chore: release v5.0.2 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11357">#11357</a>)</li>
<li><a
href="0b79231ad7"><code>0b79231</code></a>
fix: bind <code>process</code> in case global is overwritten (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11343">#11343</a>)</li>
<li><a
href="597df569ab"><code>597df56</code></a>
docs: correct stale config defaults (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11354">#11354</a>)</li>
<li><a
href="ea1c44fb58"><code>ea1c44f</code></a>
docs: <code>sequence.setupFiles</code> default is <code>'list'</code>
(<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11351">#11351</a>)</li>
<li><a
href="0fd6b97902"><code>0fd6b97</code></a>
fix(detect-async-leaks): ignore <code>process.stdio</code> handles (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11333">#11333</a>)</li>
<li><a
href="4e91e56687"><code>4e91e56</code></a>
fix(reporters): <code>hanging-process</code> to use ESM entrypoint (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11316">#11316</a>)</li>
<li><a
href="1a57929a49"><code>1a57929</code></a>
docs(browser): fix locators.exact default (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11338">#11338</a>)</li>
<li><a
href="5b95efb6df"><code>5b95efb</code></a>
fix(reporter): <code>agent</code> to respect <code>--silent</code> (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11271">#11271</a>)</li>
<li><a
href="f58a209779"><code>f58a209</code></a>
docs: correct benchmark.exclude and watch defaults (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11268">#11268</a>)</li>
<li><a
href="d1c3ecc932"><code>d1c3ecc</code></a>
fix(jsdom): fix <code>Request</code> with <code>Blob</code> body on
jsdom 28+ (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/11295">#11295</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitest-dev/vitest/commits/v5.0.2/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Updates `@anthropic-ai/claude-agent-sdk-darwin-arm64` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-darwin-x64` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-linux-arm64-musl` from 0.3.280
to 0.3.282

Updates `@anthropic-ai/claude-agent-sdk-linux-x64` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-linux-x64-musl` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-win32-arm64` from 0.3.280 to
0.3.282

Updates `@anthropic-ai/claude-agent-sdk-win32-x64` from 0.3.280 to
0.3.282

Updates `@modelcontextprotocol/sdk` from 1.30.0 to 1.30.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/modelcontextprotocol/typescript-sdk/releases">@​modelcontextprotocol/sdk's
releases</a>.</em></p>
<blockquote>
<h2>1.30.1</h2>
<h2>What's Changed</h2>
<ul>
<li>[v1.x] fix(server): read HTTP request bodies with a size limit and
bound JSON-RPC batch length by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/2717">modelcontextprotocol/typescript-sdk#2717</a></li>
<li>fix(auth): preserve resource URI without trailing slash (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1968">#1968</a>)
by <a
href="https://github.com/MukundaKatta"><code>@​MukundaKatta</code></a>
in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1972">modelcontextprotocol/typescript-sdk#1972</a></li>
<li>chore: bump version to 1.30.1 by <a
href="https://github.com/claude"><code>@​claude</code></a>[bot] in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/2848">modelcontextprotocol/typescript-sdk#2848</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/MukundaKatta"><code>@​MukundaKatta</code></a>
made their first contribution in <a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/pull/1972">modelcontextprotocol/typescript-sdk#1972</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/modelcontextprotocol/typescript-sdk/compare/1.30.0...1.30.1">https://github.com/modelcontextprotocol/typescript-sdk/compare/1.30.0...1.30.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="289ac2c3af"><code>289ac2c</code></a>
chore: bump version to 1.30.1 (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/2848">#2848</a>)</li>
<li><a
href="12b425678a"><code>12b4256</code></a>
fix(auth): preserve resource URI without trailing slash (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1968">#1968</a>)
(<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1972">#1972</a>)</li>
<li><a
href="a9f6eb709b"><code>a9f6eb7</code></a>
[v1.x] fix(server): read HTTP request bodies with a size limit and bound
JSON...</li>
<li>See full diff in <a
href="https://github.com/modelcontextprotocol/typescript-sdk/compare/1.30.0...1.30.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `@oxc-project/types` from 0.150.0 to 0.151.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.151.0</h2>
<h3>🚀 Features</h3>
<ul>
<li>1fac655 coverage: Support new TypeScript fixture layout (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26226">#26226</a>)
(camc314)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>cd7228f minifier: Add missing negation for boolean literal (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26847">#26847</a>)
(Armano)</li>
<li>32305e2 transformer: Skip enum reverse mappings for syntactic string
initializers (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26724">#26724</a>)
(Dunqing)</li>
<li>7811f0a parser: Preserve reparsed <code>await</code> tokens (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26619">#26619</a>)
(camc314)</li>
<li>9220158 transformer: Skip recovered using loop patterns (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26722">#26722</a>)
(camc314)</li>
<li>3130405 parser: Recover await using object binding patterns (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26721">#26721</a>)
(camc314)</li>
<li>827fdbd parser: Reject invalid modifiers on import aliases (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26622">#26622</a>)
(camc314)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>3f1e3aa minifier: Preallocate stmts vec size to avoid excesive
reallocs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26856">#26856</a>)
(Armano)</li>
<li>bd3f69e semantic: Reuse identifier hashes in enum member lookups (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26773">#26773</a>)
(camc314)</li>
<li>5f72954 minifier: Reduce allocations when processing if statements
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26666">#26666</a>)
(Armano)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bec650f15b"><code>bec650f</code></a>
release(crates): oxc v0.151.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxc-types/issues/26875">#26875</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/crates_v0.151.0/npm/oxc-types">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-android-arm-eabi` from 1.2.9 to 1.2.11
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rolldown/rolldown/releases">@​rolldown/binding-android-arm-eabi's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.11</h2>
<h2>[1.2.11] - 2026-09-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>watch: report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>sourcemap: preserve names through <code>collapse_sourcemaps</code>
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9486">#9486</a>)
by <a href="https://github.com/eoin"><code>@​eoin</code></a></li>
<li>watch: map metadata events by kind and missing paths as deleted (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10973">#10973</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_fs_watcher: hand the handler file events instead of notify
results (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10980">#10980</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: share one event handler adapter between the
notify watchers (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10979">#10979</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: register every path with one watch mode (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10978">#10978</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: tweak the backend traits and the event mapping
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10977">#10977</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: translate notify events inside FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10972">#10972</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>watch: update the fs watcher layout and the dev coordinator message
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10981">#10981</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: document the event translation in FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10975">#10975</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>◀️ Revert</h3>
<ul>
<li>&quot;perf(dev/lazy): fetch a lazy route in one request&quot; (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>❤️ New Contributors</h3>
<ul>
<li><a href="https://github.com/eoin"><code>@​eoin</code></a> made their
first contribution in <a
href="https://redirect.github.com/rolldown/rolldown/pull/9486">#9486</a></li>
</ul>
<p>Co-authored-by: shulaoda <a
href="mailto:165626830+shulaoda@users.noreply.github.com">165626830+shulaoda@users.noreply.github.com</a></p>
<h2>v1.2.10</h2>
<h2>[1.2.10] - 2026-09-23</h2>
<h3>🚀 Features</h3>
<ul>
<li>rolldown_plugin_esm_external_require: prefer 'module.exports' over a
namespace spread (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10901">#10901</a>)
by <a href="https://github.com/isker"><code>@​isker</code></a></li>
<li>watch: support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>label code-splitting timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10896">#10896</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>separate code-splitting group timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10892">#10892</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>clarify callback owners in the timing report (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10890">#10890</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>add checks.bundlerTimings with deprecated pluginTimings alias (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10883">#10883</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>code-splitting: initialize leaves behind a re-exported namespace
import (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10694">#10694</a>)
by <a href="https://github.com/hyfdev"><code>@​hyfdev</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-arm-eabi's
changelog</a>.</em></p>
<blockquote>
<h2>[1.2.11] - 2026-09-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>watch: report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>sourcemap: preserve names through <code>collapse_sourcemaps</code>
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9486">#9486</a>)
by <a href="https://github.com/eoin"><code>@​eoin</code></a></li>
<li>watch: map metadata events by kind and missing paths as deleted (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10973">#10973</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_fs_watcher: hand the handler file events instead of notify
results (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10980">#10980</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: share one event handler adapter between the
notify watchers (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10979">#10979</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: register every path with one watch mode (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10978">#10978</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: tweak the backend traits and the event mapping
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10977">#10977</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: translate notify events inside FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10972">#10972</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>watch: update the fs watcher layout and the dev coordinator message
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10981">#10981</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: document the event translation in FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10975">#10975</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>◀️ Revert</h3>
<ul>
<li>&quot;perf(dev/lazy): fetch a lazy route in one request&quot; (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>❤️ New Contributors</h3>
<ul>
<li><a href="https://github.com/eoin"><code>@​eoin</code></a> made their
first contribution in <a
href="https://redirect.github.com/rolldown/rolldown/pull/9486">#9486</a></li>
</ul>
<h2>[1.2.10] - 2026-09-23</h2>
<h3>🚀 Features</h3>
<ul>
<li>rolldown_plugin_esm_external_require: prefer 'module.exports' over a
namespace spread (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10901">#10901</a>)
by <a href="https://github.com/isker"><code>@​isker</code></a></li>
<li>watch: support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>label code-splitting timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10896">#10896</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>separate code-splitting group timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10892">#10892</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>clarify callback owners in the timing report (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10890">#10890</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>add checks.bundlerTimings with deprecated pluginTimings alias (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10883">#10883</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>code-splitting: initialize leaves behind a re-exported namespace
import (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10694">#10694</a>)
by <a href="https://github.com/hyfdev"><code>@​hyfdev</code></a></li>
<li>node: record the WASI target on the WebContainer binding fallback
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10952">#10952</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>dev: force incremental build on in DevEngine::new (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10958">#10958</a>)
by <a
href="https://github.com/o-alexandrov"><code>@​o-alexandrov</code></a></li>
<li>tree-shaking: propagate side effects through cycles (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10893">#10893</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8df4219851"><code>8df4219</code></a>
release: v1.2.11 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10987">#10987</a>)</li>
<li><a
href="6f85455383"><code>6f85455</code></a>
revert: &quot;perf(dev/lazy): fetch a lazy route in one request&quot;
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)</li>
<li><a
href="78699253af"><code>7869925</code></a>
feat(watch): report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)</li>
<li><a
href="3b8e06e99b"><code>3b8e06e</code></a>
release: v1.2.10 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10969">#10969</a>)</li>
<li><a
href="ec5bab8832"><code>ec5bab8</code></a>
feat(rolldown_plugin_esm_external_require): prefer 'module.exports' over
a na...</li>
<li><a
href="bb1db15db2"><code>bb1db15</code></a>
chore(deps): update napi (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10959">#10959</a>)</li>
<li><a
href="374639ef58"><code>374639e</code></a>
fix(node): record the WASI target on the WebContainer binding fallback
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10952">#10952</a>)</li>
<li><a
href="cfc9d19df0"><code>cfc9d19</code></a>
refactor(watch): let FsWatcher own the watched paths (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10948">#10948</a>)</li>
<li><a
href="1551cf8a09"><code>1551cf8</code></a>
feat(watch): support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)</li>
<li><a
href="b12f077c66"><code>b12f077</code></a>
test: handle Windows paths in sourcemap callback tests (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10942">#10942</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rolldown/rolldown/commits/v1.2.11/packages/rolldown">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-android-arm64` from 1.2.9 to 1.2.11
<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.2.11</h2>
<h2>[1.2.11] - 2026-09-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>watch: report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>sourcemap: preserve names through <code>collapse_sourcemaps</code>
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9486">#9486</a>)
by <a href="https://github.com/eoin"><code>@​eoin</code></a></li>
<li>watch: map metadata events by kind and missing paths as deleted (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10973">#10973</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_fs_watcher: hand the handler file events instead of notify
results (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10980">#10980</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: share one event handler adapter between the
notify watchers (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10979">#10979</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: register every path with one watch mode (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10978">#10978</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: tweak the backend traits and the event mapping
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10977">#10977</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: translate notify events inside FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10972">#10972</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>watch: update the fs watcher layout and the dev coordinator message
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10981">#10981</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: document the event translation in FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10975">#10975</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>◀️ Revert</h3>
<ul>
<li>&quot;perf(dev/lazy): fetch a lazy route in one request&quot; (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>❤️ New Contributors</h3>
<ul>
<li><a href="https://github.com/eoin"><code>@​eoin</code></a> made their
first contribution in <a
href="https://redirect.github.com/rolldown/rolldown/pull/9486">#9486</a></li>
</ul>
<p>Co-authored-by: shulaoda <a
href="mailto:165626830+shulaoda@users.noreply.github.com">165626830+shulaoda@users.noreply.github.com</a></p>
<h2>v1.2.10</h2>
<h2>[1.2.10] - 2026-09-23</h2>
<h3>🚀 Features</h3>
<ul>
<li>rolldown_plugin_esm_external_require: prefer 'module.exports' over a
namespace spread (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10901">#10901</a>)
by <a href="https://github.com/isker"><code>@​isker</code></a></li>
<li>watch: support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>label code-splitting timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10896">#10896</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>separate code-splitting group timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10892">#10892</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>clarify callback owners in the timing report (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10890">#10890</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>add checks.bundlerTimings with deprecated pluginTimings alias (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10883">#10883</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>code-splitting: initialize leaves behind a re-exported namespace
import (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10694">#10694</a>)
by <a href="https://github.com/hyfdev"><code>@​hyfdev</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.2.11] - 2026-09-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>watch: report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>sourcemap: preserve names through <code>collapse_sourcemaps</code>
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9486">#9486</a>)
by <a href="https://github.com/eoin"><code>@​eoin</code></a></li>
<li>watch: map metadata events by kind and missing paths as deleted (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10973">#10973</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🚜 Refactor</h3>
<ul>
<li>rolldown_fs_watcher: hand the handler file events instead of notify
results (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10980">#10980</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: share one event handler adapter between the
notify watchers (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10979">#10979</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: register every path with one watch mode (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10978">#10978</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>rolldown_fs_watcher: tweak the backend traits and the event mapping
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10977">#10977</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: translate notify events inside FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10972">#10972</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>watch: update the fs watcher layout and the dev coordinator message
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10981">#10981</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>watch: document the event translation in FsWatcher (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10975">#10975</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>◀️ Revert</h3>
<ul>
<li>&quot;perf(dev/lazy): fetch a lazy route in one request&quot; (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)
by <a href="https://github.com/h-a-n-a"><code>@​h-a-n-a</code></a></li>
</ul>
<h3>❤️ New Contributors</h3>
<ul>
<li><a href="https://github.com/eoin"><code>@​eoin</code></a> made their
first contribution in <a
href="https://redirect.github.com/rolldown/rolldown/pull/9486">#9486</a></li>
</ul>
<h2>[1.2.10] - 2026-09-23</h2>
<h3>🚀 Features</h3>
<ul>
<li>rolldown_plugin_esm_external_require: prefer 'module.exports' over a
namespace spread (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10901">#10901</a>)
by <a href="https://github.com/isker"><code>@​isker</code></a></li>
<li>watch: support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>label code-splitting timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10896">#10896</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>separate code-splitting group timing rows (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10892">#10892</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>clarify callback owners in the timing report (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10890">#10890</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
<li>add checks.bundlerTimings with deprecated pluginTimings alias (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10883">#10883</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>code-splitting: initialize leaves behind a re-exported namespace
import (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10694">#10694</a>)
by <a href="https://github.com/hyfdev"><code>@​hyfdev</code></a></li>
<li>node: record the WASI target on the WebContainer binding fallback
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10952">#10952</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
<li>dev: force incremental build on in DevEngine::new (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10958">#10958</a>)
by <a
href="https://github.com/o-alexandrov"><code>@​o-alexandrov</code></a></li>
<li>tree-shaking: propagate side effects through cycles (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10893">#10893</a>)
by <a
href="https://github.com/IWANABETHATGUY"><code>@​IWANABETHATGUY</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8df4219851"><code>8df4219</code></a>
release: v1.2.11 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10987">#10987</a>)</li>
<li><a
href="6f85455383"><code>6f85455</code></a>
revert: &quot;perf(dev/lazy): fetch a lazy route in one request&quot;
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10789">#10789</a>)
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10982">#10982</a>)</li>
<li><a
href="78699253af"><code>7869925</code></a>
feat(watch): report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)</li>
<li><a
href="3b8e06e99b"><code>3b8e06e</code></a>
release: v1.2.10 (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10969">#10969</a>)</li>
<li><a
href="ec5bab8832"><code>ec5bab8</code></a>
feat(rolldown_plugin_esm_external_require): prefer 'module.exports' over
a na...</li>
<li><a
href="bb1db15db2"><code>bb1db15</code></a>
chore(deps): update napi (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10959">#10959</a>)</li>
<li><a
href="374639ef58"><code>374639e</code></a>
fix(node): record the WASI target on the WebContainer binding fallback
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10952">#10952</a>)</li>
<li><a
href="cfc9d19df0"><code>cfc9d19</code></a>
refactor(watch): let FsWatcher own the watched paths (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10948">#10948</a>)</li>
<li><a
href="1551cf8a09"><code>1551cf8</code></a>
feat(watch): support directories in addWatchFile (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10944">#10944</a>)</li>
<li><a
href="b12f077c66"><code>b12f077</code></a>
test: handle Windows paths in sourcemap callback tests (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10942">#10942</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rolldown/rolldown/commits/v1.2.11/packages/rolldown">compare
view</a></li>
</ul>
</details>
<br />

Updates `@rolldown/binding-darwin-arm64` from 1.2.9 to 1.2.11
<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.2.11</h2>
<h2>[1.2.11] - 2026-09-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>watch: report only file events (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/10974">#10974</a>)
by <a
href="https://github.com/shulaoda"><code>@​shulaoda</code></a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>sourcemap: preserve names through <code>collapse_sourcemaps</code>
(<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown/issues/9486">#9486</a>)
by <a href="https://github.com/eoin"><code>@​eoin</code></a></li>
<li>watch: map metadata events by kind and missing paths as deleted (<a
href="https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown...

_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-09-28 17:37:12 +02:00

510 lines
21 KiB
TypeScript

import type { SessionConfigOption } from "@agentclientprotocol/sdk";
import type { ModelInfo, Query, Settings } from "@anthropic-ai/claude-agent-sdk";
import { AIR_RECOMMENDED_CONFIG_VALUE_CAPABILITY, withAirMeta } from "./air-extension.js";
export const MODEL_CONFIG_ID = "model";
export type SessionModelState = {
availableModels: Array<{ modelId: string; name: string; description?: string }>;
currentModelId: string;
};
type ModelLogger = {
log: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
};
type ModelSettingsSource = { getSettings(): Settings };
const MODEL_CONTEXT_HINT_PATTERN = /\[(\d+m)\]$/i;
const CONTEXT_HINT_SUFFIX_PATTERN = /-(\d+m)$/i;
const MODEL_FAMILY_VERSION_PATTERN = /\b(\d+)(?:[-.](\d+))?\b/;
const VERSIONABLE_MODEL_DISPLAY_PATTERN =
/^(?:Claude\s+)?([a-z][a-z0-9-]*)(?:\s+\d+(?:\.\d+)?)?(?:\s+\(\d+[mk]\s+context\))?$/i;
const DISPLAY_CONTEXT_SUFFIX_PATTERN = /\s+\((\d+[mk])\s+context\)$/i;
function stripContextHints(value: string): string {
return value.replace(/\[\d+m\]/gi, "").replace(CONTEXT_HINT_SUFFIX_PATTERN, "");
}
function canonicalizeModelId(value: string): string {
return value.trim().toLowerCase().replace(CONTEXT_HINT_SUFFIX_PATTERN, "[$1]");
}
function contextHintOf(value: string): string | null {
return canonicalizeModelId(value).match(MODEL_CONTEXT_HINT_PATTERN)?.[1] ?? null;
}
function extractModelFamilyVersion(value: string): string | null {
const match = stripContextHints(value).match(MODEL_FAMILY_VERSION_PATTERN);
if (!match) return null;
return match[2] ? `${match[1]}.${match[2]}` : match[1];
}
function modelVersionsCompatible(preference: string, candidate: ModelInfo): boolean {
const preferred = extractModelFamilyVersion(preference);
if (!preferred) return true;
const candidateVersion =
extractModelFamilyVersion(candidate.value) ??
extractModelFamilyVersion(candidate.displayName) ??
extractModelFamilyVersion(candidate.description);
return candidateVersion ? preferred === candidateVersion : true;
}
function displayModelVersion(model: ModelInfo, family: string): string | undefined {
const familyVersion = new RegExp(`\\b${family}[-\\s]+(\\d+)(?:[-.](\\d+))?`, "i");
// The display name is the value we are deciding whether to rewrite, so it
// cannot validate its own normalization. Require independent SDK metadata.
for (const source of [model.resolvedModel, model.description, model.value]) {
const match = source?.match(familyVersion);
if (match) return match[2] ? `${match[1]}.${match[2]}` : match[1];
}
return undefined;
}
/** Add concrete versions when a terse SDK label names the same family as the
* underlying model metadata. Multi-word/custom labels remain untouched.
* Context size remains in the option description; if normalization would
* collide, callers fall back to the original labels. */
function versionedModelDisplayName(model: ModelInfo): string {
const versionable = model.displayName.match(VERSIONABLE_MODEL_DISPLAY_PATTERN);
if (!versionable) return model.displayName;
const version = displayModelVersion(model, versionable[1]);
if (!version) return model.displayName;
const contextSuffix = model.displayName.match(DISPLAY_CONTEXT_SUFFIX_PATTERN);
const descriptionKeepsContext =
contextSuffix !== null &&
new RegExp(`\\b${contextSuffix[1]}\\s+context\\b`, "i").test(model.description);
const withoutContext = model.displayName.replace(DISPLAY_CONTEXT_SUFFIX_PATTERN, "");
if (/\b\d+(?:\.\d+)?\b/.test(withoutContext)) {
return descriptionKeepsContext ? withoutContext : model.displayName;
}
if (descriptionKeepsContext || contextSuffix === null) return `${withoutContext} ${version}`;
// Keep the suffix in its original spelling and insert the version before it.
return `${withoutContext} ${version}${contextSuffix[0]}`;
}
function tokenizeModelPreference(model: string): { tokens: string[]; contextHint?: string } {
const lower = model.trim().toLowerCase();
const contextHint = lower.match(MODEL_CONTEXT_HINT_PATTERN)?.[1]?.toLowerCase();
const tokens = lower
.replace(MODEL_CONTEXT_HINT_PATTERN, " $1 ")
.split(/[^a-z0-9]+/)
.filter(Boolean)
.map((token) => {
if (token === "opusplan") return "opus";
if (token === "best" || token === "default") return "";
return token;
})
.filter((token) => token && token !== "claude")
.filter((token) => /[a-z]/.test(token) || token.endsWith("m"));
return { tokens, contextHint };
}
function scoreModelMatch(model: ModelInfo, tokens: string[], contextHint?: string): number {
const haystack = `${model.value} ${model.displayName}`.toLowerCase();
let score = 0;
let nonHintMatched = false;
for (const token of tokens) {
if (!haystack.includes(token)) continue;
if (token !== contextHint) nonHintMatched = true;
score += token === contextHint ? 3 : 1;
}
return contextHint && !nonHintMatched ? 0 : score;
}
export function resolveModelPreference(models: ModelInfo[], preference: string): ModelInfo | null {
const trimmed = preference.trim();
if (!trimmed) return null;
const lower = trimmed.toLowerCase();
const canonicalPreference = canonicalizeModelId(trimmed);
const directMatch = models.find(
(model) =>
model.value === trimmed ||
canonicalizeModelId(model.value) === canonicalPreference ||
model.displayName.toLowerCase() === lower,
);
if (directMatch) return directMatch;
const matchesResolved = (model: ModelInfo) =>
model.resolvedModel != null && canonicalizeModelId(model.resolvedModel) === canonicalPreference;
const resolvedMatch =
models.find((model) => model.value !== "default" && matchesResolved(model)) ??
models.find(matchesResolved);
if (resolvedMatch) return resolvedMatch;
const preferenceHint = contextHintOf(trimmed);
const includesMatch = models.find((model) => {
if (!modelVersionsCompatible(trimmed, model)) return false;
if (contextHintOf(model.value) !== preferenceHint) return false;
const value = model.value.toLowerCase();
const display = model.displayName.toLowerCase();
return value.includes(lower) || display.includes(lower) || lower.includes(value);
});
if (includesMatch) return includesMatch;
const { tokens, contextHint } = tokenizeModelPreference(trimmed);
if (tokens.length === 0) return null;
let bestMatch: ModelInfo | null = null;
let bestScore = 0;
for (const model of models) {
if (!modelVersionsCompatible(trimmed, model)) continue;
const score = scoreModelMatch(model, tokens, contextHint);
if (score > 0 && (!bestMatch || score > bestScore)) {
bestMatch = model;
bestScore = score;
}
}
return bestMatch;
}
export function matchResumedModel(models: ModelInfo[], liveModel: string): ModelInfo {
const live = canonicalizeModelId(liveModel);
const defaultEntry = models.find((model) => model.value === "default");
const defaultResolved = defaultEntry?.resolvedModel
? canonicalizeModelId(defaultEntry.resolvedModel)
: undefined;
if (defaultEntry && defaultResolved === live) return defaultEntry;
const exactMatch = models.find(
(model) => model.resolvedModel && canonicalizeModelId(model.resolvedModel) === live,
);
if (exactMatch) return exactMatch;
if (
defaultEntry &&
defaultResolved &&
stripContextHints(defaultResolved) === stripContextHints(live)
) {
return defaultEntry;
}
return (
resolveModelPreference(models, liveModel) ?? {
value: liveModel,
displayName: liveModel,
description: "",
}
);
}
export function buildModelConfigOption(
models: SessionModelState,
modelInfos: ModelInfo[],
useRecommendedValue: boolean,
): SessionConfigOption {
const defaultInfo = modelInfos.find((model) => model.value === "default");
const selectableIds = new Set(models.availableModels.map((model) => model.modelId));
const concreteInfos = modelInfos.filter(
(model) => model.value !== "default" && selectableIds.has(model.value),
);
// Recommendations describe the running default, so fuzzy family matching
// must never substitute a different generation or context window.
const defaultResolved = defaultInfo?.resolvedModel;
const recommended = defaultResolved
? (concreteInfos.find(
(model) =>
canonicalizeModelId(model.resolvedModel ?? model.value) ===
canonicalizeModelId(defaultResolved),
) ?? null)
: null;
const concreteRecommendation = useRecommendedValue && recommended !== null;
const available = concreteRecommendation
? models.availableModels.filter((model) => model.modelId !== "default")
: models.availableModels;
return {
id: MODEL_CONFIG_ID,
name: "Model",
description: "AI model to use",
category: "model",
type: "select",
currentValue:
concreteRecommendation && models.currentModelId === "default"
? recommended.value
: models.currentModelId,
...(concreteRecommendation
? {
_meta: withAirMeta(undefined, AIR_RECOMMENDED_CONFIG_VALUE_CAPABILITY, recommended.value),
}
: {}),
options: available.map((model) => {
if (model.modelId === "default" && defaultInfo?.resolvedModel) {
const named = modelInfos.find(
(info) => info.value !== "default" && info.resolvedModel === defaultInfo.resolvedModel,
);
return {
value: model.modelId,
name: model.name,
description: named?.displayName ?? defaultInfo.resolvedModel,
};
}
return {
value: model.modelId,
name: model.name,
description: model.description ?? undefined,
};
}),
};
}
function resolveSettingsModel(
models: ModelInfo[],
settingsModel: unknown,
logger: ModelLogger,
): ModelInfo | null {
if (settingsModel === undefined) {
return null;
}
if (typeof settingsModel !== "string") {
const typeLabel = settingsModel === null ? "null" : typeof settingsModel;
logger.error(`Ignoring model from settings: expected a string, got ${typeLabel}.`);
return null;
}
return resolveModelPreference(models, settingsModel);
}
const MODEL_FAMILY_ALIASES = new Set(["opus", "sonnet", "haiku", "fable"]);
/** A model id without the spellings `deniedModels` ignores: provider
* prefixes, dates, version suffixes, `-fast` and context hints. */
function normalizeDeniedModelId(value: string): string {
let id = stripContextHints(value.trim().toLowerCase());
const providerPrefix = id.lastIndexOf("anthropic.");
if (providerPrefix !== -1) id = id.slice(providerPrefix + "anthropic.".length);
return id
.replace(/@.*$/, "")
.replace(/-v\d+(?::\d+)?$/, "")
.replace(/-fast$/, "")
.replace(/-\d{8}$/, "");
}
/**
* Whether managed `deniedModels` blocks a model id, following the CLI's rules
* closely enough for the picker: a family alias blocks the whole family, and a
* model id blocks that version in every spelling plus the later minor versions
* it prefixes (`claude-opus-5` also blocks `claude-opus-5-5`). The CLI stays
* the enforcer; this only keeps the picker from offering a refused row.
*/
export function isDeniedModel(modelId: string, deniedModels: readonly string[]): boolean {
const id = normalizeDeniedModelId(modelId);
if (!id) return false;
return deniedModels.some((entry) => {
const denied = normalizeDeniedModelId(entry);
if (!denied) return false;
if (MODEL_FAMILY_ALIASES.has(denied)) return id === denied || id.includes(`-${denied}`);
return id === denied || id.startsWith(`${denied}-`);
});
}
/**
* Restrict the SDK's model list to the user's `availableModels` allowlist
* (already merged-and-deduped across settings sources by `SettingsManager`).
* The user's exact entries become the model IDs surfaced via configOptions
* and passed to `setModel`, which prevents Claude Code from silently
* substituting a date-pinned variant (e.g. `haiku` →
* `claude-haiku-4-5-20251001`) that the user may not have access to.
*
* Display info and capability flags are copied from the closest SDK match so
* the UI still renders sensible names and effort levels.
*
* Semantics from https://code.claude.com/docs/en/model-config#restrict-model-selection:
* - `undefined` is handled by the caller (no allowlist applied).
* - The Default option is unaffected by `availableModels` — it always remains
* available, even when the allowlist is `[]`.
* - Managed `deniedModels` wins over the allowlist, so a denied entry is
* dropped even though the CLI would otherwise leave it unmatched.
*/
export function applyAvailableModelsAllowlist(
sdkModels: ModelInfo[],
allowlist: string[],
settingsModelOverrides?: Record<string, string>,
deniedModels: readonly string[] = [],
): ModelInfo[] {
// Default is always preserved per the docs. Synthesize one if the SDK
// didn't surface it so downstream code (e.g. `getAvailableModels` picking
// `models[0]` as a fallback) still has something to work with.
const defaultModel = sdkModels.find((m) => m.value === "default") ?? {
value: "default",
displayName: "Default",
description: "",
};
const result: ModelInfo[] = [defaultModel];
const seen = new Set<string>([defaultModel.value]);
const sdkModelsWithoutDefault = sdkModels.filter((m) => m.value !== "default");
// Bedrock/Vertex deployments enforce short aliases (e.g. "claude-opus-4-6")
// in availableModels but require provider-specific IDs at the API. We still
// resolve `sdkMatch` against the alias (`trimmed`) — that's what the
// matching heuristics above are built for, and override targets (ARNs,
// opaque provider IDs) often won't textually resemble anything in
// `sdkModelsWithoutDefault`. Only the entry's surfaced `value` becomes the
// override target, so it's what `setModel` ends up passing to the API.
for (const entry of allowlist) {
const trimmed = entry.trim();
if (!trimmed || seen.has(trimmed)) continue;
const overridden = settingsModelOverrides?.[trimmed];
const effective = overridden ?? trimmed;
if (seen.has(effective)) continue;
const sdkMatch = resolveModelPreference(sdkModelsWithoutDefault, trimmed);
if (
[trimmed, effective, sdkMatch?.resolvedModel].some(
(id) => id != null && isDeniedModel(id, deniedModels),
)
) {
continue;
}
if (sdkMatch) {
result.push({ ...sdkMatch, value: effective });
} else {
result.push({ value: effective, displayName: trimmed, description: "" });
}
seen.add(effective);
}
// The custom model option (ANTHROPIC_CUSTOM_MODEL_OPTION) is exempt from the
// allowlist, the same way Default is. Per the model-config docs it adds an
// entry "without replacing the built-in aliases" and "appears at the bottom of
// the /model picker", so we append it last and skip the allowlist filter; this
// keeps a slim alias allowlist from hiding the custom model row.
// https://code.claude.com/docs/en/model-config#add-a-custom-model-option
const customModelOption = process.env.ANTHROPIC_CUSTOM_MODEL_OPTION?.trim();
if (customModelOption && !seen.has(customModelOption)) {
const customModel = sdkModels.find((m) => m.value === customModelOption);
if (customModel) {
result.push(customModel);
seen.add(customModel.value);
}
}
return result;
}
/** Whether a rejected `setModel` was vetoed by a user-configured
* PreModelSwitch hook. The CLI's rejection message is the stable,
* distinguishable marker ("Model switch blocked by a PreModelSwitch hook:
* <reason>"); a format change makes this stop matching and the failure
* falls back to the ordinary fail-loud path, no worse than before. */
function isPreModelSwitchHookBlock(error: unknown): boolean {
return error instanceof Error && error.message.includes("blocked by a PreModelSwitch hook");
}
export async function getAvailableModels(
query: Query,
models: ModelInfo[],
sdkModels: ModelInfo[],
settingsManager: ModelSettingsSource,
logger: ModelLogger,
isResumedSession: boolean,
sessionId: string,
resumedModelHint?: string,
): Promise<SessionModelState> {
const settings = settingsManager.getSettings();
let currentModel = models[0];
let resolvedFromInput: string | undefined;
// Model priority (highest to lowest):
// 1. ANTHROPIC_MODEL environment variable
// 2. settings.model (user configuration)
// 3. the resumed session's live model (resumed sessions only)
// 4. models[0] (default first model)
if (process.env.ANTHROPIC_MODEL) {
const match = resolveModelPreference(models, process.env.ANTHROPIC_MODEL);
if (match) {
currentModel = match;
resolvedFromInput = process.env.ANTHROPIC_MODEL;
}
} else if (typeof settings.model === "string") {
const match = resolveSettingsModel(models, settings.model, logger);
if (match) {
currentModel = match;
resolvedFromInput = settings.model;
}
}
// A resumed session restores the model from its last real assistant
// transcript record. Use that same local record instead of getContextUsage:
// the latter is a control request to the live CLI process and can add tens
// of seconds to session/load before its first turn. No `setModel` here: the
// SDK is already running this model, and pushing a picker alias back (e.g.
// "opus[1m]") could change the live model rather than describe it.
if (resolvedFromInput === undefined && isResumedSession) {
currentModel = resumedModelHint ? matchResumedModel(models, resumedModelHint) : currentModel;
}
// Skip the setModel round-trip when we can prove the SDK has already landed
// on the same model. Two cases qualify:
// (a) No override applied — currentModel is the SDK's own default (or, on
// resume, the live model read back from the SDK above); nothing to sync.
// (b) The resolver returned the user's input verbatim AND that value exists
// in the SDK's original model list — meaning no fuzzy match or
// allowlist rewrite was involved, and the SDK (which reads the same
// ANTHROPIC_MODEL / settings.json) will have arrived at the same entry.
// This only holds for fresh sessions: a resumed session lands on the
// transcript's model regardless of env/settings, so the override must
// be re-asserted to keep the reported model truthful.
// Anything else (fuzzy match, allowlist-synthesized value, alias) gets a
// setModel call so we don't drift from the user's intended pin.
const sdkSawSameValue = sdkModels.some((m) => m.value === currentModel.value);
const skipSetModel =
resolvedFromInput === undefined ||
(!isResumedSession && currentModel.value === resolvedFromInput && sdkSawSameValue);
if (!skipSetModel) {
const setModelStartedAt = performance.now();
try {
await query.setModel(currentModel.value);
logger.log(
`[session/models] sessionId=${sessionId} phase=set-model durationMs=${Math.round(performance.now() - setModelStartedAt)} model=${currentModel.value} outcome=success`,
);
} catch (error) {
logger.log(
`[session/models] sessionId=${sessionId} phase=set-model durationMs=${Math.round(performance.now() - setModelStartedAt)} model=${currentModel.value} outcome=error`,
);
// On a fresh session the pin is a defining option — fail loudly. A
// resumed session already runs fine on the transcript's model, so
// failing the whole session/load over the re-assert would be worse
// than loading with the pin unapplied (mirrors the setPermissionMode
// containment in createSession). The SDK then stayed on the
// transcript's model, so read that back rather than reporting the
// pin the session isn't running.
//
// One fresh-session failure is advisory, not defining: a
// user-configured PreModelSwitch hook can veto the pin (CLI 2.1.251+;
// 'deny', or 'ask' — which headless sessions refuse), and the SDK
// rejects setModel with "Model switch blocked by a PreModelSwitch
// hook: …". Terminal Claude Code never lets a hook veto its startup
// model (the spawn model isn't a switch), so failing session/new here
// would make the same hook config fatal only over ACP. The session
// stays on the SDK's own default — report that. We can't read the
// live model back on this path: getContextUsage isn't serviced on a
// fresh session until the first prompt turn (issues #886/#880).
if (!isResumedSession) {
if (!isPreModelSwitchHookBlock(error)) throw error;
logger.error(
`Model pin "${currentModel.value}" was vetoed by a PreModelSwitch hook; staying on the default model:`,
error,
);
currentModel = models[0];
} else {
logger.error(`Failed to re-assert model "${currentModel.value}" on resume:`, error);
currentModel = resumedModelHint ? matchResumedModel(models, resumedModelHint) : models[0];
}
}
}
const displayNames = models.map(versionedModelDisplayName);
const displayNameCounts = new Map<string, number>();
for (const name of displayNames) {
displayNameCounts.set(name, (displayNameCounts.get(name) ?? 0) + 1);
}
return {
availableModels: models.map((model, index) => ({
modelId: model.value,
name:
displayNameCounts.get(displayNames[index]) === 1 ? displayNames[index] : model.displayName,
description: model.description,
})),
currentModelId: currentModel.value,
};
}