Sourced from @anthropic-ai/claude-agent-sdk's releases.
v0.3.263
What's changed
- Updated to parity with Claude Code v2.1.263
Update
npm install @anthropic-ai/claude-agent-sdk@0.3.263 # or yarn add @anthropic-ai/claude-agent-sdk@0.3.263 # or pnpm add @anthropic-ai/claude-agent-sdk@0.3.263 # or bun add @anthropic-ai/claude-agent-sdk@0.3.263v0.3.261
What's changed
- Added
pluginDelivery: 'initialize'to sendpluginsover stdin so the launch command line no longer grows with the plugin count (fixes Windows start failures with many plugins)- Fixed
query()throwing "Object not disposable" in runtimes without a nativeSymbol.dispose, such as Node ≤22vmcontexts (Jest'snodeenvironment, vitestvmThreads/vmForks) and Node <18.18- Updated to parity with Claude Code v2.1.261
Update
npm install @anthropic-ai/claude-agent-sdk@0.3.261 # or yarn add @anthropic-ai/claude-agent-sdk@0.3.261 # or pnpm add @anthropic-ai/claude-agent-sdk@0.3.261 # or bun add @anthropic-ai/claude-agent-sdk@0.3.261v0.3.260
What's changed
- Added optional
user_message_uuidtothinking_tokenssystem messages, linking thinking progress to the user message that triggered the turn- Added optional
first_content_frame_ms,first_stream_post_ms,first_stream_post_ack_msandfirst_stream_post_wall_msfields to the success result message for remote-session latency breakdowns- Fixed
managedSettingsdisableAutoMode: "disable"(either spelling) being dropped by the restrictive-only filter instead of turning auto mode off for the spawned session- Fixed
rewindFiles()reporting success when no files could be restored (for example when checkpoint backups are missing); it now fails- Changed
error_max_structured_output_retriesresults to append the last StructuredOutput tool error; validation errors now name the offending key, allowed values, and actual length or count- Changed
rate_limit_eventto also re-emit during an exceeded window on repeat 429s (about once per 30 seconds per limit window), so stream consumers can refresh stale rate-limit state- Updated to parity with Claude Code v2.1.260
Update
</tr></table>
... (truncated)
Sourced from @anthropic-ai/claude-agent-sdk's changelog.
0.3.263
- Updated to parity with Claude Code v2.1.263
0.3.262
- Updated to parity with Claude Code v2.1.262
0.3.261
- Added
pluginDelivery: 'initialize'to sendpluginsover stdin so the launch command line no longer grows with the plugin count (fixes Windows start failures with many plugins)- Fixed
query()throwing "Object not disposable" in runtimes without a nativeSymbol.dispose, such as Node ≤22vmcontexts (Jest'snodeenvironment, vitestvmThreads/vmForks) and Node <18.18- Updated to parity with Claude Code v2.1.261
0.3.260
- Added optional
user_message_uuidtothinking_tokenssystem messages, linking thinking progress to the user message that triggered the turn- Added optional
first_content_frame_ms,first_stream_post_ms,first_stream_post_ack_msandfirst_stream_post_wall_msfields to the success result message for remote-session latency breakdowns- Fixed
managedSettingsdisableAutoMode: "disable"(either spelling) being dropped by the restrictive-only filter instead of turning auto mode off for the spawned session- Fixed
rewindFiles()reporting success when no files could be restored (for example when checkpoint backups are missing); it now fails- Changed
error_max_structured_output_retriesresults to append the last StructuredOutput tool error; validation errors now name the offending key, allowed values, and actual length or count- Changed
rate_limit_eventto also re-emit during an exceeded window on repeat 429s (about once per 30 seconds per limit window), so stream consumers can refresh stale rate-limit state- Updated to parity with Claude Code v2.1.260
0.3.259
- Added
user_message_uuidsbesideuser_message_uuidon a turn's first reply frame and result: every user message the turn answered, so a reply to several merged messages can be matched to each- Added
permissionPrompts: 'none'option to auto-deny permission prompts in sessions with nobody to answer them, without disabling auto mode's classifier- Updated to parity with Claude Code v2.1.259
0.3.258
- Updated to parity with Claude Code v2.1.258
Sourced from @anthropic-ai/sdk's releases.
sdk: v0.124.0
0.124.0 (2026-09-04)
Full Changelog: sdk-v0.123.0...sdk-v0.124.0
Features
- api: add Claude Tag category and user breakdowns to usage reports (669ff22)
- api: add named types for organization compliance settings state (54be8da)
- api: add support for sending a workspace ID on more endpoints (a11e6f1)
Bug Fixes
- repair custom-code merge in messages resources (#455) (7ac43b9)
- tools: create agent-toolset files and directories owner-only (#485) (a9c2298)
Chores
- internal: bundle the mock server spec and update breaking-change detection (8752d02)
- internal: codegen related update (a63afbc)
- tests: reword the skip reason on the path-level query param tests (999bee5)
Documentation
- api: update a few doc strings (2ef3d59)
sdk: v0.123.0
0.123.0 (2026-09-01)
Full Changelog: sdk-v0.122.0...sdk-v0.123.0
Features
- api: beta user profiles: add external_user_onboarded_at, remove relationship in favor of access_type (3efb1a1)
- api: manual updates (c6f0bda)
- api: organization compliance settings, user-profile order_by, memory-store and toolset schema updates (8e2f0c2)
Bug Fixes
- keep credential file access out of non-Node bundles (ab6a4b2)
Chores
- internal: codegen related update (788ea8b)
... (truncated)
Sourced from @anthropic-ai/sdk's changelog.
0.124.0 (2026-09-04)
Full Changelog: sdk-v0.123.0...sdk-v0.124.0
Features
- api: add Claude Tag category and user breakdowns to usage reports (669ff22)
- api: add named types for organization compliance settings state (54be8da)
- api: add support for sending a workspace ID on more endpoints (a11e6f1)
Bug Fixes
- repair custom-code merge in messages resources (#455) (7ac43b9)
- tools: create agent-toolset files and directories owner-only (#485) (a9c2298)
Chores
- internal: bundle the mock server spec and update breaking-change detection (8752d02)
- internal: codegen related update (a63afbc)
- tests: reword the skip reason on the path-level query param tests (999bee5)
Documentation
- api: update a few doc strings (2ef3d59)
0.123.0 (2026-09-01)
Full Changelog: sdk-v0.122.0...sdk-v0.123.0
Features
- api: beta user profiles: add external_user_onboarded_at, remove relationship in favor of access_type (3efb1a1)
- api: manual updates (c6f0bda)
- api: organization compliance settings, user-profile order_by, memory-store and toolset schema updates (8e2f0c2)
Bug Fixes
- keep credential file access out of non-Node bundles (ab6a4b2)
Chores
- internal: codegen related update (788ea8b)
Documentation
... (truncated)
ba14b1f
Merge pull request #1177
from anthropics/release-please--branches--main--chan...f99c1a7
chore: release main54be8da
feat(api): add named types for organization compliance settings
state999bee5
chore(tests): reword the skip reason on the path-level query param
testsa9c2298
fix(tools): create agent-toolset files and directories owner-only (#485)2637d11
chore(examples): refresh platform model IDs (#376)669ff22
feat(api): add Claude Tag category and user breakdowns to usage
reportsa9090af
Build SDK8752d02
chore(internal): bundle the mock server spec and update breaking-change
detec...a63afbc
chore(internal): codegen related updateSourced from @typescript-eslint/eslint-plugin's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/eslint-plugin's changelog.
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
🩹 Fixes
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
❤️ Thank You
- Josh Goldberg ✨
@JoshuaKGoldberg- Ulrich Stark
@ulrichstarkSee GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0f66bdca
test(eslint-plugin): [member-ordering] use RuleTester
directly in `optional...4586535
fix(eslint-plugin): [no-deprecated] report deprecated imported values
used in...f8e1e4e
fix(eslint-plugin): [no-unnecessary-condition] no false positive on RHS
of a ...889cece
fix(eslint-plugin): [member-ordering] don't report fields that read
fields de...1a5a8b1
feat(eslint-plugin): [no-generated-empty-object-type] add rule (#12730)Sourced from @typescript-eslint/parser's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/parser's changelog.
8.70.0 (2026-09-07)
This was a version bump only for parser to align it with other projects, there were no code changes.
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0Sourced from eslint's releases.
v10.10.0
Features
264b434feat: adddandvflags tono-unexpected-multiline(#21305) (Gihyeon Jeong / 정기현)c6cc6c5feat: checkObject.prototypeproperty names innew-cap(#21269) (crimsonjay0)5661fa6feat: no-extra-bind false negatives with class fields and static blocks (#21260) (synthex-byte)Bug Fixes
bb47dc6fix: update dependency file-entry-cache to v11 (#20801) (Milos Djermanovic)427ac0afix: use format strings in debug calls (#21247) (Francesco Trotta)9d81532fix: support__proto__in/* exported */comments (#21261) (sethamus)87e0a08fix: prefer-object-has-own autofix breaks when Object is shadowed (#21282) (김채영)8e2cb14fix:new-capfalse positive forUTCcalls withproperties: false(#21275) (Pixel)9f4a364fix: Ignore static imports in no-unreachable (#21276) (Taha Kotil)Documentation
2417caddocs: Update README (GitHub Actions Bot)9cecb8adocs: document\ccontrol letter escapes in no-control-regex (#21286) (한국)8724829docs: update compat table links (#21263) (fnx)5634542docs: Clarify eqeqeq suggestion behavior (#21256) (Müslüm Yılmaz)Chores
b3d876bchore: disable npm audit in ecosystem tests (#21306) (Francesco Trotta)1696682ci: restore EMFILE test on Node.js 26 (#21297) (Marry (Subin Yang))2c7f5d6chore: update github/codeql-action action to v4.37.9 (#21296) (renovate[bot])3c753f1chore: update eslint (#21289) (renovate[bot])1c73469chore: update ecosystem plugins (#21280) (ESLint Bot)08a02betest: add error locations tono-extra-boolean-cast(#21266) (lumir)77bb1dbchore: update github/codeql-action action to v4.37.8 (#21270) (renovate[bot])007e81aci: skip EMFILE test on Node.js 26 (#21265) (lumir)0430280chore: improve ecosystem tests compatibility on Windows (#21178) (crimsonjay0)
3f20a57
10.10.0f4e5284
Build: changelog update for 10.10.0bb47dc6
fix: update dependency file-entry-cache to v11 (#20801)427ac0a
fix: use format strings in debug calls (#21247)b3d876b
chore: disable npm audit in ecosystem tests (#21306)9d81532
fix: support __proto__ in /* exported */
comments (#21261)264b434
feat: add d and v flags to
no-unexpected-multiline (#21305)1696682
ci: restore EMFILE test on Node.js 26 (#21297)2c7f5d6
chore: update github/codeql-action action to v4.37.9 (#21296)87e0a08
fix: prefer-object-has-own autofix breaks when Object is shadowed (#21282)Sourced from @eslint/plugin-kit's releases.
plugin-kit: v0.7.3
0.7.3 (2026-09-01)
Bug Fixes
a4466ca
chore: release main (#504)f83339d
docs: clarify parameter description in getText (#505)714ffde
docs: Update README sponsors18773d9
fix: preserve __proto__ in ConfigCommentParser
results (#501)caffae7
docs: Update README sponsorsae1ba25
docs: Update README sponsors50051c6
docs: Update README sponsorsea83524
docs: Update README sponsors29956ae
docs: Update README sponsorsf6d5bdf
docs: Update README sponsorsSourced from @typescript-eslint/project-service's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/project-service's changelog.
8.70.0 (2026-09-07)
🩹 Fixes
- project-service: avoid discarded tsserver logs (#12748)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0d2d07eb
fix(project-service): avoid discarded tsserver logs (#12748)Sourced from @typescript-eslint/scope-manager's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/scope-manager's changelog.
8.70.0 (2026-09-07)
This was a version bump only for scope-manager to align it with other projects, there were no code changes.
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0Sourced from @typescript-eslint/tsconfig-utils's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/tsconfig-utils's changelog.
8.70.0 (2026-09-07)
This was a version bump only for tsconfig-utils to align it with other projects, there were no code changes.
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0Sourced from @typescript-eslint/type-utils's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/type-utils's changelog.
8.70.0 (2026-09-07)
This was a version bump only for type-utils to align it with other projects, there were no code changes.
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0Sourced from @typescript-eslint/types's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaiblinger- Ulrich Stark
@ulrichstark- 송재욱
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
Sourced from @typescript-eslint/types's changelog.
8.70.0 (2026-09-07)
This was a version bump only for types to align it with other projects, there were no code changes.
See GitHub Releases for more information.
You can read about our versioning strategy and releases on our website.
7ee7608
chore(release): publish 8.70.0Sourced from @typescript-eslint/typescript-estree's releases.
v8.70.0
8.70.0 (2026-09-07)
🚀 Features
- eslint-plugin: [no-generated-empty-object-type] add rule (#12730)
- website: generate per-page social preview cards (#12734)
🩹 Fixes
- use stable release of pnpm 12 (#12808)
- update pnpm to 12.3.4 and dedupe Docusaurus packages (#12829)
- eslint-plugin: [member-ordering] don't report fields that read fields declared before them (#12729)
- eslint-plugin: [no-unnecessary-condition] no false positive on RHS of a nested logical expression (#12728)
- eslint-plugin: [no-deprecated] report deprecated imported values used in object shorthand properties (#12780)
- project-service: avoid discarded tsserver logs (#12748)
- typescript-estree: clarify the parserOptions.project error message (#12817)
❤️ Thank You
- Barry
@barry166- Evyatar Daud
@StyleShit- Josh Goldberg
- Josh Goldberg ✨
@JoshuaKGoldberg- Kirk Waiblinger
@kirkwaibling... _Description has been truncated_ --------- Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ben Brandt Co-authored-by: Claude Fable 5.1 --- docs/permission-extension.md | 11 +- docs/session-failure-extension.md | 1 + package-lock.json | 574 +++++++++++++--------- package.json | 14 +- src/acp-agent.ts | 89 +++- src/permissions/options.ts | 16 +- src/permissions/options/shared.ts | 3 + src/permissions/presentation.ts | 5 + src/session-failure-extension.ts | 19 + src/tests/acp-agent.test.ts | 183 ++++++- src/tests/model-presentation.test.ts | 18 - src/tests/permission-options.test.ts | 20 + src/tests/permission-presentation.test.ts | 20 + 13 files changed, 680 insertions(+), 293 deletions(-) diff --git a/docs/permission-extension.md b/docs/permission-extension.md index 5cbdce53..9fe33e4c 100644 --- a/docs/permission-extension.md +++ b/docs/permission-extension.md @@ -53,11 +53,12 @@ The request-level record is placed under `RequestPermissionRequest._meta.permiss } ``` -| Field | Required | Type | Meaning | -| ------------- | -------: | ---------------- | ----------------------------------------- | -| `version` | yes | integer `1` | Permission presentation schema version. | -| `title` | yes | non-empty string | The standard tool-call operation title. | -| `description` | no | string | Temporary diagnostic SDK decision reason. | +| Field | Required | Type | Meaning | +| ------------- | -------: | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `version` | yes | integer `1` | Permission presentation schema version. | +| `title` | yes | non-empty string | The standard tool-call operation title. | +| `description` | no | string | Temporary diagnostic SDK decision reason. | +| `defaultToNo` | no | `true` | The ask must not be approvable by a stray keystroke; the reject options are listed first and a client that pre-selects an option should focus the decline. | The permission title normally duplicates `toolCall.title`: one operation has one heading across the tool card and approval UI. `ExitPlanMode` is the deliberate exception and uses the action-oriented diff --git a/docs/session-failure-extension.md b/docs/session-failure-extension.md index cc1446dd..7c4b2a27 100644 --- a/docs/session-failure-extension.md +++ b/docs/session-failure-extension.md @@ -113,6 +113,7 @@ Claude SDK conditions map to these groups: | Claude condition | Category | | ---------------------------------------------------------------------------------------- | ---------------------------------- | | `authentication_failed`, `oauth_org_not_allowed`, synthetic login message | `access` | +| `verification_required`, `cloud_credential_error` | `access` (no `login` action) | | `billing_error`, `rate_limit`, `max_output_tokens`, usage/spend limit, budget/turn limit | `limit` | | `invalid_request`, `model_not_found` | `request` | | `overloaded`, `server_error`, unknown provider error, adapter internal error | `service` | diff --git a/package-lock.json b/package-lock.json index ca5d644d..9a1fce26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,20 +10,20 @@ "license": "Apache-2.0", "dependencies": { "@agentclientprotocol/sdk": "1.4.0", - "@anthropic-ai/claude-agent-sdk": "0.3.257", - "zod": "^4.0.0" + "@anthropic-ai/claude-agent-sdk": "0.3.270", + "zod": "4.6.5" }, "bin": { "claude-agent-acp": "dist/index.js" }, "devDependencies": { - "@anthropic-ai/sdk": "0.122.0", + "@anthropic-ai/sdk": "0.125.0", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.6", - "@types/node": "26.4.0", - "@typescript-eslint/eslint-plugin": "8.69.0", - "@typescript-eslint/parser": "8.69.0", - "eslint": "10.9.1", + "@types/node": "26.5.1", + "@typescript-eslint/eslint-plugin": "8.70.0", + "@typescript-eslint/parser": "8.70.0", + "eslint": "10.10.0", "eslint-config-prettier": "10.1.8", "globals": "17.12.0", "prettier": "3.9.6", @@ -45,22 +45,22 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.257.tgz", - "integrity": "sha512-Se55zXv48IYLg/WzoXzpbPLcq86suwDSbRUoNb69l4dkovorqS/47Xuy7MUo/gPNwwcPB4a+aqbXbshU33dcdQ==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.270.tgz", + "integrity": "sha512-sSfcm5Nhb+WHeBCxqeHRRQMUKPmFTL+zgv5xcRUVaFMLttfNEbn3IZJE+fLJJmy4h3J8zdc5sXdSa1JxyB8ppQ==", "license": "SEE LICENSE IN README.md", "engines": { "node": ">=18.0.0" }, "optionalDependencies": { - "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.257", - "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.257", - "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.257", - "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.257", - "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.257", - "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.257", - "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.257", - "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.257" + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.270", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.270", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.270", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.270", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.270", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.270", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.270", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.270" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", @@ -69,9 +69,9 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.257.tgz", - "integrity": "sha512-ITjFPYB8riu9tbxbrWArokiZ/90w/NDrYbtEvyr3ScilVtu1iupkComxkhvbUxoyT4JRDpKsdw/ZOfwSl/pkpA==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.270.tgz", + "integrity": "sha512-nk7BP+i559rheYz9DIwAfevd4DulQXP0mXPP+MeO2fGuIGFmzhE/c0JRm9YswXv5HdaYJvSzjGIB7dVA01NehA==", "cpu": [ "arm64" ], @@ -82,9 +82,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.257.tgz", - "integrity": "sha512-0s7QoLRnopbMvCqVpgCnvBWg4UNxPUybMZTknkn3HLBMvUjUdHs1QXb77c/yrT1WAPqDTw1Ju+H0esXwWa8/Kg==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.270.tgz", + "integrity": "sha512-89Uql8Oalm52ojdZZeNLU24LKrU+WG9QR7d6YP9ly4aY0YvQUJDaTosbDkijQngUETbPBFdKuVp6fNM8x0Zt3Q==", "cpu": [ "x64" ], @@ -95,12 +95,15 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.257.tgz", - "integrity": "sha512-38tv1s1CaIE6CyEBmJpfKtvwPzrasxPiRT079BEs5aaiLPQ+pmSGF0+Lwy7ot9i6xqr7v5/91TVo5JXHI8Pkpg==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.270.tgz", + "integrity": "sha512-iHPYqwetyeO4tZPzXyKZz0hUh2fLpwu/+biGTxxynikG3XrYknovZ/znGDA3TxjSFurqHf5IIDA+SOjh9OPs0A==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -108,12 +111,15 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.257.tgz", - "integrity": "sha512-t2WHfKjY4Jjgzfk0lbBUt6EVPQe+wXvXvRmYnK7ICfzZ1jS8CrpDajwBQErKFSMiUqGAutZy3vwDwGziW32cpw==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.270.tgz", + "integrity": "sha512-2BlLk2MAohWG2h43RKcjCA4ooMfBxzKf4yyYfOVv1DtYr8zPU876MHCT1VXB2BaemjKA0pdYJJBzH6pncwx6MQ==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -121,12 +127,15 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.257.tgz", - "integrity": "sha512-0FRyIwV4jEJErdDDoYMC0v9lzuFNz5y0lK2340H5fP02eNXsP3U0htKW/bfRP8Ppei+xc4QUZgdCI6rVzkhXGg==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.270.tgz", + "integrity": "sha512-ADaqz2viyAd0GUxdupYLX/K0YJb46xckNpEeWxyLK/9+26b/R5stbaGDyL29fIzyq1ymnNUOaCgEWEemgX0kEA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -134,12 +143,15 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.257.tgz", - "integrity": "sha512-qSlgAUEpj2JAA+YqMD222iv2W3x8xBDSYwdoaOx20VbaJRjFq8feViI7kcr1C6wVN+ApX4Rxl7YX6gekiBkA2g==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.270.tgz", + "integrity": "sha512-mzH3lnbzrbDGrTf75jLEmkbvkKRLLgmjLaWvf3QuUsgcw+aU69aOY0mW33oOrsuq5zg330uI3B4e68f4LbxNIA==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -147,9 +159,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.257.tgz", - "integrity": "sha512-7iEwy14lSqaAWvNR3KucBusQs5+hG6uoliYWZ2M2FyaCk5PHYymVf9mrRPtWhaYfNwum/YY13acYIIvnAbz0kA==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.270.tgz", + "integrity": "sha512-Pexeu26cLZByhs6VlrawNYAEu+QE2YptvwNkXsmpLRm7Q/C/M0N/BZBmuUcikXrQQ9cuVzSjuuTTpZt64mvtLA==", "cpu": [ "arm64" ], @@ -160,9 +172,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { - "version": "0.3.257", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.257.tgz", - "integrity": "sha512-NW0zMjHXFBdu2TcjT9Zo5o/1tJaDy6A7v4Gt/vLVJgaipV/RzAbyRGXZzH37hswyiKrSLGaSoYYP1vUfncbkUQ==", + "version": "0.3.270", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.270.tgz", + "integrity": "sha512-9UyfFcUYsyUZqSe/xX9nIJ1Og6i8FxhlQ35BDi79Ik5He87XFxEIGUvJuMcl7Mq2e3panyhekELFE+9H79xKdw==", "cpu": [ "x64" ], @@ -173,9 +185,9 @@ ] }, "node_modules/@anthropic-ai/sdk": { - "version": "0.122.0", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.122.0.tgz", - "integrity": "sha512-GGPNftt0caaz9MDlmNQGHX8855Ojaduyy5pm9Sm1h7HalCn0cWNb5/bweadJF+4yzbal+QL6ztBa09WAAOzLmQ==", + "version": "0.125.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.125.0.tgz", + "integrity": "sha512-Hq5wYlXupzJ9M1Fzqjqa3hObcuigEXVZJqSYDgeZGM3wF4qrNERM5Z1OOAeoT9rlod8awJ3uYyJjbQXp1ckIGg==", "license": "MIT", "dependencies": { "json-schema-to-ts": "^3.1.1", @@ -202,6 +214,30 @@ "node": ">=6.9.0" } }, + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -317,9 +353,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", - "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz", + "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -437,6 +473,30 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, + "license": "MIT" + }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", @@ -479,9 +539,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.148.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", - "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "version": "0.149.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.149.0.tgz", + "integrity": "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==", "dev": true, "license": "MIT", "peer": true, @@ -490,9 +550,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", - "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.8.tgz", + "integrity": "sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw==", "cpu": [ "arm" ], @@ -508,9 +568,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", - "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.8.tgz", + "integrity": "sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ==", "cpu": [ "arm64" ], @@ -526,9 +586,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", - "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.8.tgz", + "integrity": "sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA==", "cpu": [ "arm64" ], @@ -544,9 +604,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", - "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.8.tgz", + "integrity": "sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA==", "cpu": [ "x64" ], @@ -562,9 +622,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", - "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.8.tgz", + "integrity": "sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ==", "cpu": [ "x64" ], @@ -580,9 +640,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", - "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.8.tgz", + "integrity": "sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q==", "cpu": [ "arm" ], @@ -598,9 +658,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", - "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.8.tgz", + "integrity": "sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew==", "cpu": [ "arm64" ], @@ -619,9 +679,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", - "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.8.tgz", + "integrity": "sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA==", "cpu": [ "arm64" ], @@ -640,9 +700,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", - "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.8.tgz", + "integrity": "sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA==", "cpu": [ "ppc64" ], @@ -661,9 +721,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", - "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.8.tgz", + "integrity": "sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ==", "cpu": [ "s390x" ], @@ -682,9 +742,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", - "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.8.tgz", + "integrity": "sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g==", "cpu": [ "x64" ], @@ -703,9 +763,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", - "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.8.tgz", + "integrity": "sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA==", "cpu": [ "x64" ], @@ -724,9 +784,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", - "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.8.tgz", + "integrity": "sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg==", "cpu": [ "arm64" ], @@ -742,9 +802,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", - "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.8.tgz", + "integrity": "sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A==", "cpu": [ "arm64" ], @@ -760,9 +820,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", - "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.8.tgz", + "integrity": "sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng==", "cpu": [ "x64" ], @@ -866,27 +926,27 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "26.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz", - "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==", + "version": "26.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.5.1.tgz", + "integrity": "sha512-CzNm2FezW4VR/LjG6yUdiEgLE/rAQ9Slj5gCu/C2VrdcW7I0ahNZ8DRbHT7zOZ6r3ONgd/bsQIeSaoDGrd1C6g==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~8.3.0" + "undici-types": "~8.9.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.69.0.tgz", - "integrity": "sha512-t5jQTKPIgVW1PE6dR6H6Qz5gm8zjMlX5/2gRaOGd9eO6V7J+tQc6iWKukEe7dY8u9HyYasQ0yfF0/FSSTEO2gA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.0.tgz", + "integrity": "sha512-/v8HZt6RlyIZxB3ntehELOcUcfxKPVGWXnQdJuHRmzrqgF8nQypcC/oxGW+Ot4VGKDq81XugPKxx0n5PBtf9PA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/type-utils": "8.69.0", - "@typescript-eslint/utils": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/type-utils": "8.70.0", + "@typescript-eslint/utils": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -899,22 +959,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.69.0", + "@typescript-eslint/parser": "^8.70.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.69.0.tgz", - "integrity": "sha512-l4b0DhWioGg6Gt2ebGlvfkFMOjRsauxtsnDRwUSRX1qHq3HdTfQHV8wW9zEXeciai6HfeaKOedQn2Zoofx3WBw==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.0.tgz", + "integrity": "sha512-zYvrmj9Yxd63UGaXw+kdt6A0F0s0qveJyuatIM77bYC2DE4pgmg7a50u8LR7PRtXd0x+h+Tl3eXabGm06SWd3Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "debug": "^4.4.3" }, "engines": { @@ -930,14 +990,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.69.0.tgz", - "integrity": "sha512-yi4obFrHMmnsesWehHbkg9zMA7Jt8cXT+mKM08G999pH1yT6nqgsHx7MYm0uY1wAj8CqiBXYRJ7WAT0QdQHQXg==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.0.tgz", + "integrity": "sha512-hFHbTNqhU9G+2eKFXCBVb1tjFT/LceiJ4+HfLO4pTpDI0KHi6iajpcFFkaSQ9gXmCh7n82A0PthaayEdN6mspQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.69.0", - "@typescript-eslint/types": "^8.69.0", + "@typescript-eslint/tsconfig-utils": "^8.70.0", + "@typescript-eslint/types": "^8.70.0", "debug": "^4.4.3" }, "engines": { @@ -952,14 +1012,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.69.0.tgz", - "integrity": "sha512-ewfspqWvSxKSOaplqAUNbaSFO0eB6w1EtQ+esfYFRm3614Ty4uNtExkcbgd6nWsXphbqKyf9ZYdbZdv2xEoWEQ==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.0.tgz", + "integrity": "sha512-8nP3Kwh5hlgZ4FicGvmznAmJe8UL4sdU8tLukrPaMuQmDuk4Y8xYfzu/aYZW4xT2JCgc7H/TpDI5cGlxcWJSqQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0" + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -970,9 +1030,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.69.0.tgz", - "integrity": "sha512-xNqK7YTDZsLniQMV/4rpFR8Z5JlqeRvVjuG1YgF/mdPVH84HSD19L8CczMA0qg2RfwEV231GHH3VnToJDo4MfQ==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.0.tgz", + "integrity": "sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw==", "dev": true, "license": "MIT", "engines": { @@ -987,15 +1047,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.69.0.tgz", - "integrity": "sha512-ZfoJAVg3JZndQEpEl9petVlxau3lRuElc4HRMuAlLCf8to04/iHz692RUSNmXKDjEuJmIL+KZ2/BsOcBc16dsA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.0.tgz", + "integrity": "sha512-NUMKIhYVaVIVLnRL9CRt+VVcuLgSHUCpXn4/+K8wql+vdInUzvx8BjUO1oJ7cG9shjFJKtF8F8Hh2kCh3/KBVw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/utils": "8.69.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0", + "@typescript-eslint/utils": "8.70.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1012,9 +1072,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.69.0.tgz", - "integrity": "sha512-K3VrubUPhlo9VDBS6QdI8YB5j7ClpqLRdefcz6PFrhnwicehBweqQ9Evhl4l+FYz0HdDmMqIiSX0aldGRYtDCA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.0.tgz", + "integrity": "sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==", "dev": true, "license": "MIT", "engines": { @@ -1026,16 +1086,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.69.0.tgz", - "integrity": "sha512-AdFkgqck3Vudb/kWnxlyafU/4aBhHrbQ9locP2N4psXTy5mOBg0SHJumnLvx7r6g1gV4DKvUFwV2nJZBoqOD8w==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.0.tgz", + "integrity": "sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.69.0", - "@typescript-eslint/tsconfig-utils": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/project-service": "8.70.0", + "@typescript-eslint/tsconfig-utils": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1054,16 +1114,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.69.0.tgz", - "integrity": "sha512-tUbx60BBqQa31kXF5MCsOOLL5E/WzUuxIn7YpAvq+eaUlqvk8/NXnXMBNAdLCr0icjkzem7iUA5QqWHe/hJ1aw==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.0.tgz", + "integrity": "sha512-oZmtKJz/4fufZ2p3+Cn3ijEojcdfR+1zYDH2xKYrEly0dR/Q/1xUPRCOlKGxod78nWlU2UnDe09GZ3TaknBFGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0" + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1078,13 +1138,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.69.0.tgz", - "integrity": "sha512-+rmdgPA+EXkNgKYvHvFfhrs35utXbwaC5PGpDquSXcoXQDKUA5UjV0LmTucG/4JXkM31BTu4TilHtrN8IVBe8w==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.0.tgz", + "integrity": "sha512-BoC8PiO4Hkdo0TVJh9Ntxr5MxPDI7/oFsrygN5ADelFSeXG/qgNuucIGA+L5Z6JpPTE/uRfcTWtscjbUaufepQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", + "@typescript-eslint/types": "8.70.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1331,6 +1391,20 @@ "node": ">= 0.8" } }, + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1603,9 +1677,9 @@ } }, "node_modules/eslint": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.1.tgz", - "integrity": "sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==", + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.10.0.tgz", + "integrity": "sha512-NPXn6r5zl4uET1DAVPaOwzX3rut4c0wcmw3dWJAfOsTM5+TogXo0DDjz8pwm/hL8cyVNpHqeK4JpN0NjnyFFNw==", "dev": true, "license": "MIT", "workspaces": [ @@ -1617,7 +1691,7 @@ "@eslint/config-array": "^0.23.5", "@eslint/config-helpers": "^0.7.0", "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.2", + "@eslint/plugin-kit": "^0.7.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -1632,7 +1706,7 @@ "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", + "file-entry-cache": "11.1.5 || >11.1.6 <12", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", @@ -2012,16 +2086,13 @@ } }, "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" + "flat-cache": "^6.1.23" } }, "node_modules/finalhandler": { @@ -2064,17 +2135,15 @@ } }, "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" } }, "node_modules/flatted": { @@ -2221,6 +2290,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", @@ -2235,15 +2317,22 @@ } }, "node_modules/hono": { - "version": "4.13.5", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.5.tgz", - "integrity": "sha512-O6+/eCYRkzzzy0rPWwKLiGBR1nFuUPZynnwjxN1MBA62NNqbT0wQEzQyK2gSO5yDIDB336sXQleAhOHrzlYyKw==", + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.7.tgz", + "integrity": "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==", "license": "MIT", "peer": true, "engines": { "node": ">=16.9.0" } }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -2283,9 +2372,9 @@ } }, "node_modules/ignore": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.8.tgz", - "integrity": "sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.9.tgz", + "integrity": "sha512-brTTsvFRt5C1gGHtPst/281UjPD5t9fBqbgoMPlVWy11ZLTPfu7HxK4ZYqO9H7o/yC9rSTCI85EaQ4OoY12qYw==", "dev": true, "license": "MIT", "engines": { @@ -2366,22 +2455,15 @@ "license": "ISC" }, "node_modules/jose": { - "version": "6.2.10", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.10.tgz", - "integrity": "sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==", + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", + "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", "license": "MIT", "peer": true, "funding": { "url": "https://github.com/sponsors/panva" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, "node_modules/json-schema-to-ts": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", @@ -2417,13 +2499,13 @@ "license": "MIT" }, "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", "dependencies": { - "json-buffer": "3.0.1" + "@keyv/serialize": "^1.1.1" } }, "node_modules/levn": { @@ -2742,13 +2824,13 @@ } }, "node_modules/magic-string": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", - "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.3.1.tgz", + "integrity": "sha512-rm91zr2Ou+XueDTohjQQjdQEcYM6zVi8KVUCG8Ec3vHwUEKrhSdCNyfuIywkA6hcCAteIn0ZOtAHA6eGpiX+Pg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "@jridgewell/sourcemap-codec": "^1.6.0" } }, "node_modules/make-error": { @@ -2845,9 +2927,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", "dev": true, "funding": [ { @@ -2926,9 +3008,9 @@ } }, "node_modules/obug": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", - "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -3163,6 +3245,26 @@ "node": ">=6" } }, + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^2.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", + "dev": true, + "license": "MIT" + }, "node_modules/qs": { "version": "6.16.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", @@ -3221,14 +3323,14 @@ } }, "node_modules/rolldown": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", - "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.8.tgz", + "integrity": "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@oxc-project/types": "=0.148.0", + "@oxc-project/types": "=0.149.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -3238,21 +3340,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.7", - "@rolldown/binding-android-arm64": "1.2.7", - "@rolldown/binding-darwin-arm64": "1.2.7", - "@rolldown/binding-darwin-x64": "1.2.7", - "@rolldown/binding-freebsd-x64": "1.2.7", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", - "@rolldown/binding-linux-arm64-gnu": "1.2.7", - "@rolldown/binding-linux-arm64-musl": "1.2.7", - "@rolldown/binding-linux-ppc64-gnu": "1.2.7", - "@rolldown/binding-linux-s390x-gnu": "1.2.7", - "@rolldown/binding-linux-x64-gnu": "1.2.7", - "@rolldown/binding-linux-x64-musl": "1.2.7", - "@rolldown/binding-openharmony-arm64": "1.2.7", - "@rolldown/binding-win32-arm64-msvc": "1.2.7", - "@rolldown/binding-win32-x64-msvc": "1.2.7" + "@rolldown/binding-android-arm-eabi": "1.2.8", + "@rolldown/binding-android-arm64": "1.2.8", + "@rolldown/binding-darwin-arm64": "1.2.8", + "@rolldown/binding-darwin-x64": "1.2.8", + "@rolldown/binding-freebsd-x64": "1.2.8", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.8", + "@rolldown/binding-linux-arm64-gnu": "1.2.8", + "@rolldown/binding-linux-arm64-musl": "1.2.8", + "@rolldown/binding-linux-ppc64-gnu": "1.2.8", + "@rolldown/binding-linux-s390x-gnu": "1.2.8", + "@rolldown/binding-linux-x64-gnu": "1.2.8", + "@rolldown/binding-linux-x64-musl": "1.2.8", + "@rolldown/binding-openharmony-arm64": "1.2.8", + "@rolldown/binding-win32-arm64-msvc": "1.2.8", + "@rolldown/binding-win32-x64-msvc": "1.2.8" } }, "node_modules/router": { @@ -3666,9 +3768,9 @@ } }, "node_modules/undici-types": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", - "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", "dev": true, "license": "MIT" }, @@ -3710,17 +3812,17 @@ } }, "node_modules/vite": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", - "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz", + "integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "lightningcss": "^1.33.0", - "picomatch": "^4.0.5", - "postcss": "^8.5.26", - "rolldown": "~1.2.4", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.6", "tinyglobby": "^0.2.17" }, "bin": { @@ -3737,7 +3839,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "@vitejs/devtools": "^0.7.1", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -3944,9 +4046,9 @@ } }, "node_modules/zod": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz", - "integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==", + "version": "4.6.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", + "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index fadc5d3e..9c78d4e7 100644 --- a/package.json +++ b/package.json @@ -66,17 +66,17 @@ }, "dependencies": { "@agentclientprotocol/sdk": "1.4.0", - "@anthropic-ai/claude-agent-sdk": "0.3.257", - "zod": "^4.0.0" + "@anthropic-ai/claude-agent-sdk": "0.3.270", + "zod": "4.6.5" }, "devDependencies": { - "@anthropic-ai/sdk": "0.122.0", + "@anthropic-ai/sdk": "0.125.0", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.6", - "@types/node": "26.4.0", - "@typescript-eslint/eslint-plugin": "8.69.0", - "@typescript-eslint/parser": "8.69.0", - "eslint": "10.9.1", + "@types/node": "26.5.1", + "@typescript-eslint/eslint-plugin": "8.70.0", + "@typescript-eslint/parser": "8.70.0", + "eslint": "10.10.0", "eslint-config-prettier": "10.1.8", "globals": "17.12.0", "prettier": "3.9.6", diff --git a/src/acp-agent.ts b/src/acp-agent.ts index b8003d8b..2799e7db 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -626,10 +626,14 @@ type Turn = { * issue #866), and the model's task-notification followup summary all * land inside the turn. * - * The CLI does NOT hold its trailing idle for background agents (observed - * on 2.1.206: `idle` follows the result immediately while the subagent - * still runs), so the hold spans multiple idle cycles: user result → - * idle → (subagent works) → task_notification → followup turn → idle. + * Idle cadence depends on the CLI. Through 2.1.269 the trailing idle is + * NOT held for background agents (observed on 2.1.206: `idle` follows + * the result immediately while the subagent still runs), so the hold + * spans multiple idle cycles: user result → idle → (subagent works) → + * task_notification → followup turn → idle. From 2.1.270 the CLI stays + * `running` while background agents live (observed live: user result → + * task_notification → followup turn → ONE idle), so the user result's + * idle debt goes unpaid — swept at the next `running` transition. * The stored outcome (the result's stop reason and usage snapshot) is * what the turn settles with once its spawned subagents have settled — * at the followup's terminal result (the summary has streamed by then), @@ -4183,7 +4187,31 @@ export class ClaudeAcpAgent { break; } case "session_state_changed": { + const previousState = session.lastSessionState; session.lastSessionState = message.state; + if ( + message.state === "running" && + previousState !== "running" && + session.owedTrailingIdles > 0 + ) { + // A transition INTO `running` (the CLI reports state + // changes; a repeated `running` is not a transition and is + // left alone) proves the idle period before it ended: every + // idle the CLI was going to emit for earlier results has + // been emitted. Debt still outstanding here can never be paid. + // CLI 2.1.270+ withholds `idle` while background agents run + // (verified live: user result → task_notification → + // followup result → ONE idle), so a held turn's own result + // leaves one unpaid unit per hold. Left in place, each unit + // would absorb a later un-owed idle — masking an issue-#825 + // detection — or swallow the idle a steered turn settles on + // (the owed-idle branch below runs before the steer lane), + // hanging that prompt. Sweep it. + this.logger.log( + `[claude-agent-acp] Session ${params.sessionId}: dropping ${session.owedTrailingIdles} unpaid trailing-idle debt at the running transition`, + ); + session.owedTrailingIdles = 0; + } if (message.state === "idle") { // A non-cancelled turn normally settled at its terminal // `result` already (issue #773), and that result recorded an @@ -4225,17 +4253,19 @@ export class ClaudeAcpAgent { session.emittedAssistantText = false; } else if (isHeldOpen(session.activeTurn)) { // A turn held open for its background subagents (see - // Turn.deferredSettle). Idles keep their normal cadence - // during the hold — the CLI emits one per processing - // cycle (the turn's own trailer, then one per followup), - // NOT one final "all drained" signal — so each one - // absorbs an outstanding trailer debt, and the turn only - // settles once none of its spawned subagents is left - // (the followup-result settle usually got there first; - // this is the fallback when no followup came). Mid-hold - // idles never fall through: a held turn HAS its result, - // so reading its idle as "turn abandoned without a - // result" (issue #825) would fail a healthy prompt. + // Turn.deferredSettle). Idle cadence during the hold + // depends on the CLI: through 2.1.269 one idle per + // processing cycle (the turn's own trailer, then one per + // followup); from 2.1.270 none until the background + // agents drain, then one. Either way each idle absorbs an + // outstanding trailer debt (the unpayable remainder is + // swept at the next `running` transition above), and the + // turn only settles once none of its spawned subagents is + // left (the followup-result settle usually got there + // first; this is the fallback when no followup came). + // Mid-hold idles never fall through: a held turn HAS its + // result, so reading its idle as "turn abandoned without + // a result" (issue #825) would fail a healthy prompt. if (session.owedTrailingIdles > 0) { session.owedTrailingIdles--; } @@ -4601,10 +4631,18 @@ export class ClaudeAcpAgent { // here would outlive the `auth_required` rejection with no // action to clear it (issue #1072). if (kind === "auth_required") break; + // `no_response` (SDK 0.3.261+): the API sent no response headers + // within the first-byte window, so this retry waits longer for + // them. Say so — "attempt 1 of 1" alone reads like a final + // failure, and the wait is what the user is about to sit through. + const seconds = (ms: number) => `${Math.max(1, Math.round(ms / 1000))}s`; + const noResponse = message.no_response + ? ` No response after ${seconds(message.no_response.waited_ms)}; waiting up to ${seconds(message.no_response.retry_wait_ms)}.` + : ""; const title = message.error_status === null - ? `Reconnecting to Claude, attempt ${message.attempt} of ${message.max_retries}.` - : `Retrying Claude, attempt ${message.attempt} of ${message.max_retries}.`; + ? `Reconnecting to Claude, attempt ${message.attempt} of ${message.max_retries}.${noResponse}` + : `Retrying Claude, attempt ${message.attempt} of ${message.max_retries}.${noResponse}`; await publishSessionFailure(kind, { title, severity: "warning" }); break; } @@ -7006,6 +7044,8 @@ export class ClaudeAcpAgent { title, displayName, description, + defaultToNo, + suppressAlwaysAllowRule, }, ) => { const supportsTerminalOutput = this.clientCapabilities?._meta?.["terminal_output"] === true; @@ -7096,10 +7136,13 @@ export class ClaudeAcpAgent { // explicit ask rule). Re-applying bypass in the host would erase that // provider safety decision. - const durableChangeSet = normalizeDurablePermissionChangeSet( - suggestions, - matchedAskRule !== undefined, - ); + // No persistent "always allow" option when the user's own ask rule forced + // the prompt, or when the CLI says the rule it would write grants more + // than this ask's own action (`suppressAlwaysAllowRule`, SDK 0.3.268+ — + // set on its safety-check asks, e.g. delete-class Bash rulings and + // Artifact publishes). + const noPersistentRule = matchedAskRule !== undefined || suppressAlwaysAllowRule === true; + const durableChangeSet = normalizeDurablePermissionChangeSet(suggestions, noPersistentRule); const presentation = buildClaudePermissionPresentation({ toolName, input: toolInput, @@ -7111,6 +7154,7 @@ export class ClaudeAcpAgent { displayName, description, decisionReason, + defaultToNo, }); if (parentToolUseId) { @@ -7125,7 +7169,8 @@ export class ClaudeAcpAgent { input: toolInput, cwd: session.cwd, durableChangeSet, - allowPersistentOptions: matchedAskRule === undefined, + allowPersistentOptions: !noPersistentRule, + defaultToNo, availableModes: this.sessionModes.availableModeIds(session.modes), contextUsedPercent: session.contextUsedTokens === undefined || session.contextWindowSize <= 0 diff --git a/src/permissions/options.ts b/src/permissions/options.ts index 89588a21..7af91eb5 100644 --- a/src/permissions/options.ts +++ b/src/permissions/options.ts @@ -23,8 +23,12 @@ import { export { PERMISSION_OPTION_ID } from "./options/shared.js"; export function buildClaudePermissionOptions(context: PermissionOptionContext): PermissionOption[] { + // ACP has no "pre-selected option" field, so option order is the only lever + // for the CLI's `defaultToNo` hint ("open on the decline option"): lead with + // the reject options instead of the approvals. + const order = context.defaultToNo === true ? declineFirstOptionOrder : permissionOptionOrder; return buildUnsortedClaudePermissionOptions(context).sort( - (left, right) => permissionOptionOrder(left) - permissionOptionOrder(right), + (left, right) => order(left) - order(right), ); } @@ -71,6 +75,16 @@ function buildUnsortedClaudePermissionOptions( } } +function declineFirstOptionOrder(option: PermissionOption): number { + switch (option.kind) { + case "reject_once": + case "reject_always": + return 0; + default: + return 1 + permissionOptionOrder(option); + } +} + function permissionOptionOrder(option: PermissionOption): number { switch (option.kind) { case "allow_once": diff --git a/src/permissions/options/shared.ts b/src/permissions/options/shared.ts index da489768..b94d3ce3 100644 --- a/src/permissions/options/shared.ts +++ b/src/permissions/options/shared.ts @@ -23,6 +23,9 @@ export interface PermissionOptionContext { cwd: string; durableChangeSet?: DurablePermissionChangeSet; allowPersistentOptions?: boolean; + /** The CLI's `defaultToNo` hint (SDK 0.3.268+): the ask must not be + * approvable by a stray keystroke, so the decline option leads. */ + defaultToNo?: boolean; availableModes?: readonly string[]; contextUsedPercent?: number; } diff --git a/src/permissions/presentation.ts b/src/permissions/presentation.ts index 5fb33d9a..2c273777 100644 --- a/src/permissions/presentation.ts +++ b/src/permissions/presentation.ts @@ -12,6 +12,7 @@ export interface ClaudePermissionPresentationInput { displayName?: string; description?: string; decisionReason?: string; + defaultToNo?: boolean; } function humanText(value: unknown, maxLength: number, singleLine = false): string | undefined { @@ -104,6 +105,10 @@ export function buildClaudePermissionPresentation( version: 1, title, ...(description ? { description } : {}), + // The CLI's own hint, forwarded so a client that can pre-select + // an option keeps the decline focused; the option order already + // leads with the reject options when this is set. + ...(value.defaultToNo === true ? { defaultToNo: true } : {}), }, }, } diff --git a/src/session-failure-extension.ts b/src/session-failure-extension.ts index fc7902d7..3f4609cf 100644 --- a/src/session-failure-extension.ts +++ b/src/session-failure-extension.ts @@ -17,6 +17,7 @@ export function airSessionFailureCapabilityMeta(...additionalCapabilities: strin } export type ClaudeFailureKind = + | "access_denied" | "advisory" | "auth_required" | "bad_request" @@ -93,6 +94,15 @@ const AIR_FAILURE_POLICY: Record< fallbackTitle: string; } > = { + // Account or credential blocks that signing in again cannot fix: the + // organization must complete verification, or the cloud provider's + // credentials must be refreshed outside Claude. No `login` action, and not + // sticky like `auth_required` (nothing clears at `auth_status`). + access_denied: { + category: "access", + actions: ["retry"], + fallbackTitle: "Claude could not access the account or provider credentials.", + }, advisory: { category: "unknown", actions: [], @@ -448,6 +458,15 @@ export function providerFailureCategory( case "billing_error": case "account_on_hold": return "quota_exhausted"; + // 403 `permission_error` with error_code `verification_required` (the + // organization must verify at the console), and a Bedrock/Vertex/Foundry + // credential the CLI could not load (transient: it retries, and asks the + // user to check or refresh the credentials). Both are access failures + // `/login` does not repair, so they get their own lane rather than + // `auth_required`'s login action and sticky auth_status recovery. + case "verification_required": + case "cloud_credential_error": + return "access_denied"; case "rate_limit": return "rate_limited"; case "overloaded": diff --git a/src/tests/acp-agent.test.ts b/src/tests/acp-agent.test.ts index 89638d64..2e67d852 100644 --- a/src/tests/acp-agent.test.ts +++ b/src/tests/acp-agent.test.ts @@ -4118,6 +4118,79 @@ describe("canUseTool in bypassPermissions mode", () => { expect(request?.options.map((option) => option.optionId)).toEqual(["allow-once", "reject"]); }); + + // SDK 0.3.268+ hints on the CLI's safety-check asks (delete-class Bash + // rulings, Artifact publishes, …): the always-allow rule it would write is + // broader than the ask, so no persistent option may be offered; and the ask + // must open on its decline option, so the reject options lead. + it("offers no always-allow option when the CLI suppresses the persistent rule", async () => { + let request: RequestPermissionRequest | undefined; + const mockClient = { + sessionUpdate: async () => {}, + requestPermission: async (params: RequestPermissionRequest) => { + request = params; + return { outcome: { outcome: "selected", optionId: "allow-once" } }; + }, + } as unknown as AcpClient; + const agent = new ClaudeAcpAgent(mockClient, { log: () => {}, error: () => {} }); + agent.sessions["session-1"] = mockSessionState(); + agent.sessions["session-1"]!.emittedToolCalls.add("tool-1"); + + await agent.canUseTool("session-1")("Bash", { command: "rm -rf build" }, { + signal: new AbortController().signal, + suggestions: [ + { + type: "addRules", + rules: [{ toolName: "Bash", ruleContent: "rm:*" }], + behavior: "allow", + destination: "localSettings", + }, + ], + toolUseID: "tool-1", + suppressAlwaysAllowRule: true, + } as any); + + expect(request?.options.map((option) => option.optionId)).toEqual(["allow-once", "reject"]); + expect(request?._meta).toEqual({ permission: { version: 1, title: "Bash" } }); + }); + + it("leads with the reject option and forwards the hint when the CLI defaults to no", async () => { + let request: RequestPermissionRequest | undefined; + const mockClient = { + sessionUpdate: async () => {}, + requestPermission: async (params: RequestPermissionRequest) => { + request = params; + return { outcome: { outcome: "selected", optionId: "reject" } }; + }, + } as unknown as AcpClient; + const agent = new ClaudeAcpAgent(mockClient, { log: () => {}, error: () => {} }); + agent.sessions["session-1"] = mockSessionState(); + agent.sessions["session-1"]!.emittedToolCalls.add("tool-1"); + + const result = await agent.canUseTool("session-1")("Bash", { command: "rm -rf build" }, { + signal: new AbortController().signal, + suggestions: [ + { + type: "addRules", + rules: [{ toolName: "Bash", ruleContent: "rm:*" }], + behavior: "allow", + destination: "localSettings", + }, + ], + toolUseID: "tool-1", + defaultToNo: true, + } as any); + + expect(request?.options.map((option) => option.kind)).toEqual([ + "reject_once", + "allow_once", + "allow_always", + ]); + expect(request?._meta).toEqual({ + permission: { version: 1, title: "Bash", defaultToNo: true }, + }); + expect(result).toMatchObject({ behavior: "deny" }); + }); }); describe("subagent permission attribution (issue #851)", () => { @@ -6547,6 +6620,52 @@ describe("stop reason propagation", () => { ); }); + it("says how long a no-response retry waited and will wait", async () => { + const updates: SessionNotification[] = []; + const agent = new ClaudeAcpAgent( + { + sessionUpdate: async (update: SessionNotification) => updates.push(update), + } as unknown as AcpClient, + { log: () => {}, error: () => {} }, + ); + (agent as any).clientCapabilities = airSessionFailureCapabilities; + injectSession(agent, [ + { + type: "system", + subtype: "api_retry", + attempt: 1, + max_retries: 1, + retry_delay_ms: 0, + error_status: null, + error: "unknown", + // SDK 0.3.261+: the API sent no response headers within the + // first-byte window; the retry waits longer for them. + no_response: { waited_ms: 180_000, retry_wait_ms: 600_000 }, + uuid: randomUUID(), + session_id: "test-session", + }, + createResultMessage({ + subtype: "success", + stop_reason: "end_turn", + is_error: false, + result: "ok", + }), + ]); + + await agent.prompt({ sessionId: "test-session", prompt: [{ type: "text", text: "test" }] }); + const warning = updates + .map((update) => (update.update._meta as any)?.jetbrains?.air?.sessionFailure) + .find(Boolean); + expect(warning).toEqual( + expect.objectContaining({ + category: "connection", + severity: "warning", + title: + "Reconnecting to Claude, attempt 1 of 1. No response after 180s; waiting up to 600s.", + }), + ); + }); + it("clears a connection retry warning internally after the turn succeeds", async () => { const updates: SessionNotification[] = []; const agent = new ClaudeAcpAgent( @@ -6656,6 +6775,8 @@ describe("stop reason propagation", () => { it.each([ ["billing_error", "limit"], ["account_on_hold", "limit"], + ["verification_required", "access"], + ["cloud_credential_error", "access"], ["rate_limit", "limit"], ["overloaded", "service"], ["invalid_request", "request"], @@ -13831,10 +13952,11 @@ describe("deferred settlement for live background subagents (issues #864/#866)", // out-of-turn session/update, but many clients stop consuming at the // prompt response, so the subagents' remaining output would be dropped // and their permission requests would block on an RPC nobody answers. The turn is held open - // across the CLI's idle cycles (observed cadence: user result → idle → - // subagent works → task_notification → followup turn → idle) and settles - // once its subagents are done — at the followup's terminal result, or at - // an idle with none of them left. + // across the CLI's idle cycles (cadence through CLI 2.1.269: user result → + // idle → subagent works → task_notification → followup turn → idle; from + // 2.1.270: no idle until the subagent drains) and settles once its + // subagents are done — at the followup's terminal result, or at an idle + // with none of them left. function createMockAgent() { const mockClient = { @@ -14017,6 +14139,59 @@ describe("deferred settlement for live background subagents (issues #864/#866)", await agent.sessions["test-session"]?.consumer; }); + // CLI 2.1.270+ stays `running` while background agents live (verified + // live: user result → task_notification → followup result → ONE idle), so + // the user result's trailing-idle debt is never paid. It must not linger: + // a stale unit would swallow a later un-owed idle (masking issue #825) or + // the idle a steered turn settles on. The next transition into `running` + // sweeps it. + it("settles under the 2.1.270 cadence and sweeps the unpaid idle debt at the next running", async () => { + const { agent, events } = chunkCapturingAgent(); + + injectGeneratorSession(agent, (input) => { + async function* messageGenerator() { + const iter = input[Symbol.asyncIterator](); + const { value: first } = await iter.next(); + yield userEcho(first); + yield running(); + yield subagentStarted("agent-1"); + yield resultMessage(); + // No idle here: the CLI is still `running` for the live subagent. + yield taskNotification("agent-1"); + yield assistantText("promised summary"); + yield resultMessage({ origin: { kind: "task-notification" } }); + yield idle(); // one idle for both results + const { value: second } = await iter.next(); + yield userEcho(second); + yield running(); + yield assistantText("second answer"); + yield resultMessage(); + yield idle(); + } + return messageGenerator(); + }); + + const session = () => agent.sessions["test-session"]!; + const first = await agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "explore" }], + }); + expect(first.stopReason).toBe("end_turn"); + expect(events.indexOf("chunk:promised summary")).toBeGreaterThanOrEqual(0); + // Two results, one idle: one unit of debt is left over. + await waitFor(() => session().owedTrailingIdles === 1); + + const second = await agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "again" }], + }); + expect(second.stopReason).toBe("end_turn"); + // The `running` transition swept the stale unit, so the second turn's + // own idle leaves nothing outstanding. + await waitFor(() => session().owedTrailingIdles === 0); + await agent.sessions["test-session"]?.consumer; + }); + it("falls back to settling at an idle when no followup comes", async () => { const agent = createMockAgent(); diff --git a/src/tests/model-presentation.test.ts b/src/tests/model-presentation.test.ts index e6647e70..18465c65 100644 --- a/src/tests/model-presentation.test.ts +++ b/src/tests/model-presentation.test.ts @@ -1,6 +1,3 @@ -import { readFileSync } from "node:fs"; -import { createRequire } from "node:module"; -import { dirname, join } from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { query, type ModelInfo, type Query } from "@anthropic-ai/claude-agent-sdk"; import { buildModelConfigOption, getAvailableModels } from "../session-model.js"; @@ -16,21 +13,6 @@ describe("versioned model display names", () => { beforeEach(() => vi.stubEnv("ANTHROPIC_MODEL", undefined)); afterEach(() => vi.unstubAllEnvs()); - it("requires reviewing the live model contract whenever the SDK is upgraded", () => { - const require = createRequire(import.meta.url); - const sdkPackage = JSON.parse( - readFileSync( - join(dirname(require.resolve("@anthropic-ai/claude-agent-sdk")), "package.json"), - "utf8", - ), - ); - expect( - sdkPackage.version, - "Run RUN_INTEGRATION_TESTS=true npx vitest run src/tests/model-presentation.test.ts " + - "and review the Opus name normalization before updating this version guard.", - ).toBe("0.3.257"); - }); - it("adds standard-family versions and preserves model identity and recommendation", async () => { const models: ModelInfo[] = [ { ...OPUS, value: "default", displayName: "Default (recommended)" }, diff --git a/src/tests/permission-options.test.ts b/src/tests/permission-options.test.ts index c7cdaa02..fc119b0e 100644 --- a/src/tests/permission-options.test.ts +++ b/src/tests/permission-options.test.ts @@ -29,6 +29,26 @@ describe("Claude permission options and response mapping", () => { contextUsedPercent, }); + it("leads with the reject options when the CLI defaults the ask to no", () => { + const changeSet = normalizeDurablePermissionChangeSet([ + { type: "addRules", rules: [rule], behavior: "allow", destination: "localSettings" }, + ]); + const context = { + toolName: "Bash", + input: { command: "npm test" }, + cwd: "/workspace", + durableChangeSet: changeSet, + }; + expect(buildClaudePermissionOptions(context).map((option) => option.kind)).toEqual([ + "allow_once", + "allow_always", + "reject_once", + ]); + expect( + buildClaudePermissionOptions({ ...context, defaultToNo: true }).map((option) => option.kind), + ).toEqual(["reject_once", "allow_once", "allow_always"]); + }); + it("builds the native Bash static-suggestions option from the exact update bundle", () => { const changeSet = normalizeDurablePermissionChangeSet([ { type: "addRules", rules: [rule], behavior: "allow", destination: "session" }, diff --git a/src/tests/permission-presentation.test.ts b/src/tests/permission-presentation.test.ts index f106b39d..083aa090 100644 --- a/src/tests/permission-presentation.test.ts +++ b/src/tests/permission-presentation.test.ts @@ -103,6 +103,26 @@ describe("Claude permission ACP v1 presentation", () => { }); }); + it("forwards the CLI's defaultToNo hint in the permission record", () => { + const presentation = buildClaudePermissionPresentation({ + toolName: "Bash", + input: { command: "rm -rf build" }, + toolUseID: "tool-1", + defaultToNo: true, + }); + expect(presentation._meta).toEqual({ + permission: { version: 1, title: "Bash", defaultToNo: true }, + }); + expect( + buildClaudePermissionPresentation({ + toolName: "Bash", + input: { command: "rm -rf build" }, + toolUseID: "tool-1", + defaultToNo: false, + })._meta, + ).toEqual({ permission: { version: 1, title: "Bash" } }); + }); + it("uses the human command description as the permission title", () => { const input = { command: "npm test", description: "Run the tests" }; const presentation = buildClaudePermissionPresentation({