mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-11-02 15:31:50 +00:00
Compare commits
7 Commits
fix/reject
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
981bf9a28a | ||
|
|
4d79b9ffbc | ||
|
|
5565259771 | ||
|
|
720bbb3e4c | ||
|
|
38cf656fc9 | ||
|
|
1d0306468b | ||
|
|
c6de68797b |
@@ -1,3 +1,3 @@
|
||||
{
|
||||
".": "0.99.1"
|
||||
".": "0.100.0"
|
||||
}
|
||||
|
||||
84
AGENTS.md
84
AGENTS.md
@@ -16,13 +16,85 @@ npm run format # prettier --write
|
||||
CI runs `format:check`, `lint`, `build` and `test:run`. Run `npm run check` before
|
||||
opening a PR.
|
||||
|
||||
## Code comments
|
||||
## Coding guidelines
|
||||
|
||||
Keep comments straightforward, concise, and concrete. Say what the code does and
|
||||
why, in plain terms: name the actual state, call, or failure involved instead of
|
||||
alluding to it. Prefer a short concrete example over an abstract description.
|
||||
Don't use vague phrases like "keeps it honest" or "the residual case" that make
|
||||
the reader reconstruct the meaning.
|
||||
- Keep edits consistent with the surrounding code's formatting, naming and idioms.
|
||||
- Keep comments concise and concrete. Name the actual state, call or failure
|
||||
instead of alluding to it, prefer a short example over an abstract
|
||||
description, and avoid vague phrases like "keeps it honest". A comment or doc
|
||||
must be true on every code path it describes, and a doc that lists what a
|
||||
result omits or rejects must name the actual cases.
|
||||
- When a request can't be served, throw a `RequestError` whose message says what
|
||||
happened and what to do (e.g. "Try again when the turn ends"). Don't drop the
|
||||
request silently.
|
||||
- Don't report success for work you start without awaiting it. If the detached
|
||||
call can still refuse and its `.catch` only logs, check the refusal condition
|
||||
first or report the failure to the client.
|
||||
- A result must not depend on what an earlier call happened to cache. A request
|
||||
right after a restart, with cold caches, must return the same thing as one
|
||||
after a warm-up.
|
||||
- If code relies on an ordering or call sequence that nothing enforces (e.g. an
|
||||
echo arriving before the result), say so in a short comment.
|
||||
|
||||
## Architecture and design fit
|
||||
|
||||
- Before coding, read the code the change plugs into and find the module that
|
||||
owns the state or concept. Build on that module, not beside it.
|
||||
- Don't add new features or components to `acp-agent.ts`. If no existing module fits the new
|
||||
code cleanly, create a dedicated one that owns the feature's state and logic,
|
||||
and keep the change in `acp-agent.ts` to the calls that wire it in.
|
||||
- Prefer extending an existing mechanism over adding a new one, even if it takes
|
||||
a small refactor (moving a helper, generalizing a function). Add a parallel
|
||||
path, special case or flag only when the existing structure can't support the
|
||||
change.
|
||||
- Before writing new logic, check whether it already exists in a sibling handler
|
||||
of the same flow or in a helper that works with the same data, and reuse it.
|
||||
Paths that handle the same input must apply the same rules through the same
|
||||
code: the live stream and the `session/load` replay, the command list and
|
||||
command dispatch, `prompt` and `steer`. Two copies of one check drift apart.
|
||||
- Put guards, filters and cleanup in the module that owns the state, so every
|
||||
caller gets them. If guards, flags or fallbacks pile up in one place,
|
||||
restructure instead of adding another.
|
||||
- If a result is meant to match another request's output, reuse that request's
|
||||
logic.
|
||||
- The adapter serves ACP v1 and v2. A change that is not meant for one protocol
|
||||
version only must work correctly in both. `src/v2/` converts v2 requests to v1
|
||||
and reuses the v1 logic; keep v2-only differences in the conversion.
|
||||
- A session runs one turn at a time. "Claude is working" means `startTurn`'s
|
||||
check (an unsettled turn in `turnQueue`, or `foregroundWork` for the session);
|
||||
don't write a narrower one. Anything that sends `session/update` must go
|
||||
through the turn queue or be refused while the session is busy, or its output
|
||||
lands inside another turn. Keep the session marked busy across awaited network
|
||||
calls.
|
||||
- Don't branch on a local copy of state that Claude Code or a remote service
|
||||
owns: it goes stale when the other side changes. Have a command set the state
|
||||
the user asks for instead of toggling it.
|
||||
- A command or name the adapter adds must not shadow one that Claude Code or the
|
||||
user's own commands and skills already provide.
|
||||
- New optional request fields and `_meta` keys must not reject requests that
|
||||
were valid before.
|
||||
- If a workaround or new path is unavoidable (e.g. a Claude Code or SDK
|
||||
limitation), say why in a short code comment and in the PR description.
|
||||
|
||||
## Testing guidelines
|
||||
|
||||
- Before adding a test, search `src/tests/` for existing tests of the same API
|
||||
and scenario, and add to their file and `describe` block. Use the helpers in
|
||||
`helpers.ts` and `session-doubles.ts` instead of copying setup.
|
||||
- Don't add cases that take the same code path. Tests that differ only in input
|
||||
and expected output belong in one `it.each`. Don't repeat another test's
|
||||
assertions; assert only what this test is about.
|
||||
- Reach a state the shortest way (e.g. set `session.tornDown = true`) instead of
|
||||
driving a full flow with extra mocks, unless the flow is what you test.
|
||||
- Build test doubles from what the bundled Claude Code CLI really sends,
|
||||
including fields like `origin` it echoes back and fields it omits. A double
|
||||
simpler than the real message hides bugs. If unsure, check against the real
|
||||
CLI (`npm run test:integration`).
|
||||
- Cover both ACP v1 and v2 when a change affects what a client receives
|
||||
(updates, responses, replay). A change to internal logic only does not need
|
||||
its tests duplicated per version.
|
||||
- For each behavior the docs or comments promise, including what is omitted or
|
||||
rejected, have a test that would fail if it broke.
|
||||
|
||||
## Pull requests
|
||||
|
||||
|
||||
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## [0.100.0](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.99.1...v0.100.0) (2026-11-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* list v2 background tool calls ([#1511](https://github.com/agentclientprotocol/claude-agent-acp/issues/1511)) ([4d79b9f](https://github.com/agentclientprotocol/claude-agent-acp/commit/4d79b9ffbce95c23928a5dd771d6c87476d37160))
|
||||
* report subagent working directories ([#1496](https://github.com/agentclientprotocol/claude-agent-acp/issues/1496)) ([eb78afa](https://github.com/agentclientprotocol/claude-agent-acp/commit/eb78afa8556b8fc4082495e48e3fd1762fb6a50f))
|
||||
* report v2 background work ([#1510](https://github.com/agentclientprotocol/claude-agent-acp/issues/1510)) ([5565259](https://github.com/agentclientprotocol/claude-agent-acp/commit/5565259771cb74e3a9bdbacfcbce43e061d81422))
|
||||
* report why Claude Code could not start a session ([#1508](https://github.com/agentclientprotocol/claude-agent-acp/issues/1508)) ([38cf656](https://github.com/agentclientprotocol/claude-agent-acp/commit/38cf656fc9d80fec2d1a16c472779803e2c802d2))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* align session/cancel, session/close, and v2 setup with the ACP v2 spec ([#1494](https://github.com/agentclientprotocol/claude-agent-acp/issues/1494)) ([f50598a](https://github.com/agentclientprotocol/claude-agent-acp/commit/f50598a39c5dc3908d4b98a7213e01d63ea867d5))
|
||||
* forward v2 elicitation values and read dismissed v2 permission prompts as a refusal ([#1493](https://github.com/agentclientprotocol/claude-agent-acp/issues/1493)) ([3bc6711](https://github.com/agentclientprotocol/claude-agent-acp/commit/3bc671193c6456516fe05a0eaa53c17bdfb6a190))
|
||||
* keep native Windows paths in v2 git patches ([#1492](https://github.com/agentclientprotocol/claude-agent-acp/issues/1492)) ([c3428de](https://github.com/agentclientprotocol/claude-agent-acp/commit/c3428de1bf411c513b0703ddd56bb6c5fdff583c))
|
||||
* preserve live session settings across provider refreshes ([#1474](https://github.com/agentclientprotocol/claude-agent-acp/issues/1474)) ([e01a288](https://github.com/agentclientprotocol/claude-agent-acp/commit/e01a28838499dd6dd7c31e35708090b938e852c6))
|
||||
* reject unreadable skill manifests ([#1482](https://github.com/agentclientprotocol/claude-agent-acp/issues/1482)) ([99a6e76](https://github.com/agentclientprotocol/claude-agent-acp/commit/99a6e76158b9164e51bd62e3b89113beadea5ce2))
|
||||
* report the fresh context's usage when ExitPlanMode clears context ([#1484](https://github.com/agentclientprotocol/claude-agent-acp/issues/1484)) ([2fd46c8](https://github.com/agentclientprotocol/claude-agent-acp/commit/2fd46c866d4ff2939fe1b1245b15a536d6de7c0b))
|
||||
* update to @agentclientprotocol/sdk 2.2.0 ([#1491](https://github.com/agentclientprotocol/claude-agent-acp/issues/1491)) ([1d2b92f](https://github.com/agentclientprotocol/claude-agent-acp/commit/1d2b92feae5eeccde3ac738edca1f1d71250762e))
|
||||
* update to @agentclientprotocol/sdk 2.4.0 ([#1509](https://github.com/agentclientprotocol/claude-agent-acp/issues/1509)) ([720bbb3](https://github.com/agentclientprotocol/claude-agent-acp/commit/720bbb3e4c65874775a0bb9418799baf4b6e3680))
|
||||
* update to Claude Agent SDK 0.3.316 (Claude Code 2.1.316) ([#1507](https://github.com/agentclientprotocol/claude-agent-acp/issues/1507)) ([1d03064](https://github.com/agentclientprotocol/claude-agent-acp/commit/1d0306468b632c6a56b4fb076ad7a19f23d9e7b5))
|
||||
* validate session, prompt, config, and auth requests per the latest ACP spec ([#1495](https://github.com/agentclientprotocol/claude-agent-acp/issues/1495)) ([d2ef490](https://github.com/agentclientprotocol/claude-agent-acp/commit/d2ef490a318033049af00cb9164a39ac2dd1eb95))
|
||||
|
||||
## [0.99.1](https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.99.0...v0.99.1) (2026-10-29)
|
||||
|
||||
|
||||
|
||||
298
package-lock.json
generated
298
package-lock.json
generated
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "@agentclientprotocol/claude-agent-acp",
|
||||
"version": "0.99.1",
|
||||
"version": "0.100.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@agentclientprotocol/claude-agent-acp",
|
||||
"version": "0.99.1",
|
||||
"version": "0.100.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "2.2.0",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.312",
|
||||
"@agentclientprotocol/sdk": "2.4.0",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.316",
|
||||
"diff": "9.0.0",
|
||||
"zod": "4.6.7"
|
||||
},
|
||||
@@ -21,14 +21,14 @@
|
||||
"@anthropic-ai/sdk": "1.3.0",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@tsconfig/node22": "22.0.6",
|
||||
"@types/node": "26.6.5",
|
||||
"@types/node": "26.6.6",
|
||||
"@typescript-eslint/eslint-plugin": "8.72.1",
|
||||
"@typescript-eslint/parser": "8.72.1",
|
||||
"ajv": "8.20.0",
|
||||
"ajv-formats": "3.0.1",
|
||||
"eslint": "10.13.0",
|
||||
"eslint": "10.14.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"globals": "17.13.0",
|
||||
"globals": "17.14.0",
|
||||
"prettier": "3.9.10",
|
||||
"typescript": "6.0.3",
|
||||
"vitest": "5.0.5"
|
||||
@@ -38,9 +38,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@agentclientprotocol/sdk": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-2.2.0.tgz",
|
||||
"integrity": "sha512-o1+eDQVb05yzPY+5v54awHyONU1oeLsbLVavkwrMQaZDuJDh/38pQiXJS4ix4d6QA3Y4bU0lHFRjwg99KKKSaQ==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-2.4.0.tgz",
|
||||
"integrity": "sha512-7qJ8nnyj7WesC5ve185ioTpB2/svQoeGV4HA4nLEhgDUrcmBe54/08VcXc/oL4p14tDbxxECZzdYmUYQ+4l+Wg==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@modelcontextprotocol/server": "^2.4.0",
|
||||
@@ -53,22 +53,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.312.tgz",
|
||||
"integrity": "sha512-Ilj5Agx3ak/Z0UPZNLS7+CTnYMa+Ijf8+FKelh9MKGRwHVYyfvmJgL0fsmooI78SdkZwqjI5a4CwOAsJurdjJA==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.316.tgz",
|
||||
"integrity": "sha512-mCMr0que5kIy80JslJub6WFDB2+GYRGWNeVgSZaBpkBwXrr4wnRMnnGHitkA2BEJ5QP5xWyc6YH/6do/edxCWg==",
|
||||
"license": "SEE LICENSE IN README.md",
|
||||
"engines": {
|
||||
"node": ">=18.14.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.312",
|
||||
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.312"
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.316",
|
||||
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.316"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@anthropic-ai/sdk": ">=0.93.0",
|
||||
@@ -77,9 +77,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.312.tgz",
|
||||
"integrity": "sha512-AVmdMOuoeE3Y9f4wAIPcEAAS0OFaZw1L6l11YuyqfS0B/+DYxkWxS/ZYZ1NbUy57eaIW/vdEgz9Q5M99Pl6ZJw==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.316.tgz",
|
||||
"integrity": "sha512-1I1oJ/YGqq4pFQvJqycD2e8pbsUQLLR+DwEzG9jQAGCoSKkxP1TBfHpjSik/0byCixyzpYObrYXPC0PKBIR91g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -90,9 +90,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.312.tgz",
|
||||
"integrity": "sha512-Dmxyil+GPzF1WENoFOi1Cx0roSdJA6HewGAfAFvsH5vYrzb6G0REGuoQQ0n3u8i8qFgtl1m/WSl4u5t+MdiHWA==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.316.tgz",
|
||||
"integrity": "sha512-gzNncKrID/6yJIKCAuF/pY1kfygQZ4dU0J+MNFl0bU+iQW65ERoIyoghYVfrAQ/gH2fuvnQtWxa8LQNScHgNMA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -103,9 +103,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.312.tgz",
|
||||
"integrity": "sha512-jebsXksKh7g7u1x+RxjYQXM50TCN0e7GthebXa+n5IebF3pPqtmyWGVIiEEjvpajn3P6Zh8BWUVuufUpXn8ccA==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.316.tgz",
|
||||
"integrity": "sha512-+lm9XSw/em14yMZ41fbo80kfblbylfBQc9nYS6GgLoZVvgT3wSeEbv88v+mEK/jFw9g3VCH4ZI01sjNM34o7uw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -119,9 +119,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.312.tgz",
|
||||
"integrity": "sha512-9GT0JzbfhODwsCO3MCg79wPH47qARCuKECcryeAJnVczplAlXSIiBw1+6UcqL5+0wSYFu6D/tvw/AiVy+PkHsg==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.316.tgz",
|
||||
"integrity": "sha512-1qqaEdsAs6eipEQQ4bMAWiwDjIouyA/YN5KQWS0/+kuPb+GKS8rUVW2dty2elV703hsMovb4IhMP4cv5K7R9YA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -135,9 +135,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.312.tgz",
|
||||
"integrity": "sha512-UOsqza2uo5gqlX2OU72LhkQvIaNJKUQMJIi1poX2NtYqaWACqNo/TZPWfOBzxhyWmX8BLWaOlcuZGPLgcCJOTg==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.316.tgz",
|
||||
"integrity": "sha512-+csYyGkHziNp4It+ZykqTmXRZBuNrieTiBnji+zwAxNmLLCWz8xEWjNmwhaLPIMpUiaYREkDhZXt/AS6xXta5w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -151,9 +151,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.312.tgz",
|
||||
"integrity": "sha512-zM+PB6qVybdwtlqElXQ4+wCwk2v/jjT3Xau4foydzy/g5pGRTuGT3PTcfDLeG0j9zF8IxLaCQ/+Bl9MABPQD8g==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.316.tgz",
|
||||
"integrity": "sha512-pMG9MRkjxMMbIxpwg/cKz6JorNjZtJOA9l/fifRQ/A01zGTKrRIaSCWoGg+Asmc64QBOa3aA4vzE/od9B1R0Tw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -167,9 +167,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.312.tgz",
|
||||
"integrity": "sha512-Li9CyzsC2mzGmF1wtt/R59ChBLww6nc2dLn6tb+bgTDcd6kqvW44x5rIH+lRmBcpTNHR/8VO/k+GlmnkxqeaQQ==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.316.tgz",
|
||||
"integrity": "sha512-Xj4iTS8NsB6isGhnZEnaIXIpUcSspv/lyIVnfPZjVGwuttaVHjq4IxfDopsPaVsPuTKd+L7DLAaBram1k85U2g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -180,9 +180,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": {
|
||||
"version": "0.3.312",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.312.tgz",
|
||||
"integrity": "sha512-9GgGHHFEQnXx6EPhkPplOw1ndqmys8+Z+uOR68EIQlXGZm+wE+BmfypyHAoZhjs4151iWdQgNzjDT7wet3crdw==",
|
||||
"version": "0.3.316",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.316.tgz",
|
||||
"integrity": "sha512-FzQA1zHbYJTtLR9nn1McwkGYeiEmroTmYjIg7xZqo5eweJ8U/DESZKR/QdfF04MXe2DF23oLL8WHjEa+WxbGQw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -363,9 +363,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@hono/node-server": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.5.tgz",
|
||||
"integrity": "sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==",
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.6.tgz",
|
||||
"integrity": "sha512-p/KH9MnfNcsm3sR6x4lNgm5j+QN4Et8srKredl9DZfXiyZ1UQ3aQ2YVpFLbqktYN5JI+DB+VZFKM2PqE5hLKjQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
@@ -544,9 +544,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.155.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz",
|
||||
"integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==",
|
||||
"version": "0.156.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.156.0.tgz",
|
||||
"integrity": "sha512-1Duyg48TdJNdyhEB8Xn1L36bT9Pv6GUtlKjHxOys8xkaF/rQq3XJE+bAurSK/AgIz5mGFsb77cn9Pb20+WCScw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
@@ -555,9 +555,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz",
|
||||
"integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.16.tgz",
|
||||
"integrity": "sha512-ia3DwAs0OsMGS7+IConptSiyk9pEXkOx/AbJ2n/lAGxH3QkWQus1t8d7gnAT38FCU2sQu8lUbeR6AiZFv4JxaA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -573,9 +573,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.16.tgz",
|
||||
"integrity": "sha512-kx5wBiMB6E7TEvpl2B9gjLU004BkvEm2Dr941BFjx/SontPwSzNuQUIoVKxHHoSjpFIfHMmcguyLOtyn0hObRg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -591,9 +591,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.16.tgz",
|
||||
"integrity": "sha512-qslZrXnKJU4cUpjoAmtAo/KQM9e2IRMlmpig6Zpwj+8KWxW8v+nkAf9216Bsek9lOC1jvg2yCjygCFo2f83msQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -609,9 +609,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.16.tgz",
|
||||
"integrity": "sha512-FdF+y48ND13eAyM2mQn+85kvAqNlvRWROy2rhgA463X/0Gv4vGtazZtfaF1mRBLscYvtOlh4QnLjOWiFzX69OQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -627,9 +627,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.16.tgz",
|
||||
"integrity": "sha512-ddjqFM5e95AgLbUPtKIS7V1KTVlA0RUgCVr5mn+/IEhsdy3pr+Vuj/HZ7nlMN2FyxIwUktOH1LEPIQXO1v9y1Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -645,9 +645,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz",
|
||||
"integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.16.tgz",
|
||||
"integrity": "sha512-tHdKWbFkFBI687iim3LIyIvyL7j66VvQYkDPss5Stn/qyE2tWkR1YD0dXmXPFKKqT/o5ZEJVsaRsWS2meQwGOA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -663,9 +663,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.16.tgz",
|
||||
"integrity": "sha512-FJiLGAblPBMlBEdbOqw6kW6QcXDWAf/oJu7gYs9ZJZwmg+K+/zjFLxPTIY9izJUzxzc24FHvmseyA0IvJSl17w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -684,9 +684,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.16.tgz",
|
||||
"integrity": "sha512-hrJpblMsrQ58U9veWpbXzkhV5zStunds6HWLprqq1qauvgBr1E6P+24kLj6lSLI9vjRn/RYpjprhkHQPKGWpNg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -705,9 +705,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.16.tgz",
|
||||
"integrity": "sha512-qJd/dC6j6CwLG9/s/RP2nb1RZ0GIgj7Ioj7x/SYa3RzjVrlzrmH0fhIOpfvqQDeIsdP0loi+kHaMhJzY1PBIaA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -726,9 +726,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.16.tgz",
|
||||
"integrity": "sha512-Vx7Xg5uUJuNcujJjI70OICaH0EYj80BtOLZTSN7uOYg8QOLlyKnaG0IW7Fn/J0IpJsaKzmDKMhOQv1JBM9m9vg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -747,9 +747,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.16.tgz",
|
||||
"integrity": "sha512-TNKhgE3uJTsTzatUSSYt0Kgo+Oa2uSlSjz4r1aEIea7HX6ULBym4fAlYUhG1i6pjNf2njfCUAfKwr6C3E9Xg1w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -768,9 +768,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.16.tgz",
|
||||
"integrity": "sha512-7chXdpjXZ8qG0+mIxECN3cT9kvhZ3/oZhMX6Pp876P7CDrIy8nJswva6Mq357JR7eYXfuskwZxMeV1SzoZdHrA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -789,9 +789,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.16.tgz",
|
||||
"integrity": "sha512-Kwjt+7uNTJK5/MDkGWGVO2KQPnj8yAV75dMpfwyHZrJSXWHrniOB0aUEWlVYf3H1hOqFLIStLdM5QXq6bnKmOQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -807,9 +807,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.16.tgz",
|
||||
"integrity": "sha512-/LH6WfjDRXXJz/p5xl4TmU+jpcnwcxbKEQBW/GZE0JHfN0lGIyTtsUEGaQ/q/GikkGJ2yLKe6pwm7AnEWO8pdw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -825,9 +825,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.16.tgz",
|
||||
"integrity": "sha512-1lv1KvX0Z871zfk7vw+dnXMMnHNyDwMzWG8Kv3HxDXMOhzCX4SHc7HK319fInP0i+0p9D8brkfzL7pJOaGl+tw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -889,9 +889,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
||||
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz",
|
||||
"integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -903,9 +903,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "26.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.5.tgz",
|
||||
"integrity": "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==",
|
||||
"version": "26.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz",
|
||||
"integrity": "sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1543,13 +1543,17 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.1.tgz",
|
||||
"integrity": "sha512-Ev/hIyePLZtpL98x562lvPtenrUfGr0lfaf44HFZ+hDEwso7ccV9QAZrEVLg0hxNAzygaAFxy2dYaAKKM0G06A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
@@ -1613,9 +1617,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "10.13.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.13.0.tgz",
|
||||
"integrity": "sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==",
|
||||
"version": "10.14.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.14.0.tgz",
|
||||
"integrity": "sha512-T0pNsxkb9IKmtQjhpK3d7nWOpFv+YHuMbTJnSVMoQblF0onvXfErrtp4V1jHtsQPan7dKaGVD0q1WCXnzMF31A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
@@ -1628,7 +1632,7 @@
|
||||
"@eslint/config-helpers": "^0.7.0",
|
||||
"@eslint/core": "^1.2.1",
|
||||
"@eslint/plugin-kit": "^0.7.3",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanfs/node": "^0.16.8",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@humanwhocodes/retry": "^0.4.2",
|
||||
"@types/estree": "^1.0.6",
|
||||
@@ -1649,7 +1653,7 @@
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-glob": "^4.0.0",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"minimatch": "^10.2.5",
|
||||
"minimatch": "^10.2.6",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.3"
|
||||
},
|
||||
@@ -1941,9 +1945,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express-rate-limit": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.1.tgz",
|
||||
"integrity": "sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==",
|
||||
"version": "8.7.2",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.2.tgz",
|
||||
"integrity": "sha512-U1ScocxDD9WI09LaBVypvNkOtNR5yWAmZLkuKJdAzIchA4YKFYF6GT5IKER7epG58oXtjvGlV0/6ii0F83EyZg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -2201,9 +2205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "17.13.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz",
|
||||
"integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==",
|
||||
"version": "17.14.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.14.0.tgz",
|
||||
"integrity": "sha512-UtdkTVyAJePQv0J2M9Xe4L0ruNSDV314XiIJsADI2Zf40bcdAonE/D/OhAU8AT99oij9mhLByb+NvA3QWZYgCg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -2266,9 +2270,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hono": {
|
||||
"version": "4.13.14",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.14.tgz",
|
||||
"integrity": "sha512-yhRLQ21U6qa9Hsu2N7Qcbh8tE+WKEcoErjIo56LeSGiGXGp9sA7UpE86Ui9uexb61KakiGwuHMn2QdV7w6i6kQ==",
|
||||
"version": "4.13.16",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.16.tgz",
|
||||
"integrity": "sha512-AOLOEhvrV+iH92xXCnFr/5+3KjPKcI3xP63XJtX5spAnkznPdHijlIsUTpi7/9EhWqrTCekw5c5zh1K+YsVw7A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
@@ -2404,9 +2408,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "6.2.13",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.13.tgz",
|
||||
"integrity": "sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==",
|
||||
"version": "6.2.15",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.15.tgz",
|
||||
"integrity": "sha512-qdF6ewcZARtef63fJ9AKKZPgxw+t7USH6HLXYcD4CrdmSvDp79rpJSPFEKc90QBeGS63u1KQtN2MZQHC0yDIzA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
@@ -3215,9 +3219,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.17.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.17.0.tgz",
|
||||
"integrity": "sha512-5LK5BZ2XDHMvcUJaf0CQ5HL3aVgKbpklvByC7qLSxYkfE8COEEbJg5xCHWCTqzqi0Gs4Jn5Mv5v3R38W6edscA==",
|
||||
"version": "6.17.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.17.1.tgz",
|
||||
"integrity": "sha512-jd3COkaKVgGUW+ZHyEHCG9bH7RoaaiWuMgzsIBjUMVjLAaWGWpoUAVwljVvBHxRu/2qEHnadLGZrkutYUBPQJA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -3271,14 +3275,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz",
|
||||
"integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==",
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.16.tgz",
|
||||
"integrity": "sha512-bWvlMpFKiTfDKfnK7FC2MPgPeWCf/Kpwsq49ApdW+FQaBZb6O6dZ4MAPbPUjp7hYQrw/RobqCzn64BRrQecGHw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.155.0",
|
||||
"@oxc-project/types": "=0.156.0",
|
||||
"@rolldown/pluginutils": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -3288,21 +3292,21 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.15",
|
||||
"@rolldown/binding-android-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-x64": "1.2.15",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.15",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.15",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.15",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.15",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.15",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.15"
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.16",
|
||||
"@rolldown/binding-android-arm64": "1.2.16",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.16",
|
||||
"@rolldown/binding-darwin-x64": "1.2.16",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.16",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.16",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.16",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.16",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.16",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.16",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.16",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.16",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.16",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.16",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.16"
|
||||
}
|
||||
},
|
||||
"node_modules/router": {
|
||||
@@ -3532,9 +3536,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinybench": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.2.tgz",
|
||||
"integrity": "sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==",
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.3.tgz",
|
||||
"integrity": "sha512-Al01C2JIBnO2CXCAPbpAl6sUiOZHeThGtHYNTa51JRw9PyWOCdr+9Ong05R4qg/Sk3+H645E8ov1h2c58ityNw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
||||
12
package.json
12
package.json
@@ -3,7 +3,7 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "0.99.1",
|
||||
"version": "0.100.0",
|
||||
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
||||
"main": "dist/lib.js",
|
||||
"types": "dist/lib.d.ts",
|
||||
@@ -65,8 +65,8 @@
|
||||
"node": ">=22"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "2.2.0",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.312",
|
||||
"@agentclientprotocol/sdk": "2.4.0",
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.316",
|
||||
"diff": "9.0.0",
|
||||
"zod": "4.6.7"
|
||||
},
|
||||
@@ -74,14 +74,14 @@
|
||||
"@anthropic-ai/sdk": "1.3.0",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@tsconfig/node22": "22.0.6",
|
||||
"@types/node": "26.6.5",
|
||||
"@types/node": "26.6.6",
|
||||
"@typescript-eslint/eslint-plugin": "8.72.1",
|
||||
"@typescript-eslint/parser": "8.72.1",
|
||||
"ajv": "8.20.0",
|
||||
"ajv-formats": "3.0.1",
|
||||
"eslint": "10.13.0",
|
||||
"eslint": "10.14.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"globals": "17.13.0",
|
||||
"globals": "17.14.0",
|
||||
"prettier": "3.9.10",
|
||||
"typescript": "6.0.3",
|
||||
"vitest": "5.0.5"
|
||||
|
||||
250
src/acp-agent.ts
250
src/acp-agent.ts
@@ -164,6 +164,22 @@ import {
|
||||
backgroundedBashToolCallIds,
|
||||
clientSupportsAsyncTasks,
|
||||
} from "./async-tasks.js";
|
||||
import {
|
||||
backgroundLevel,
|
||||
type BackgroundLevel,
|
||||
type BackgroundSink,
|
||||
backgroundToolCallPause,
|
||||
backgroundToolCallStates,
|
||||
type BackgroundTaskEnd,
|
||||
type BackgroundToolCall,
|
||||
BackgroundWorkReporter,
|
||||
cancelBackgroundWork,
|
||||
droppedTasks,
|
||||
endBackgroundWork,
|
||||
registerBackgroundToolCalls,
|
||||
takeBackgroundTerminalExit,
|
||||
takeBackgroundToolCallEnd,
|
||||
} from "./background-work.js";
|
||||
import {
|
||||
AUTH_STATUS_PROBE_TIMEOUT_MS,
|
||||
AUTH_STATUS_UPDATE_METHOD,
|
||||
@@ -302,7 +318,11 @@ import {
|
||||
unregisterHookCallback,
|
||||
} from "./tools.js";
|
||||
import { previewPatchContent } from "./diff.js";
|
||||
import { backgroundedBashToolCall, withRunningTerminal } from "./tool-calls/background.js";
|
||||
import {
|
||||
backgroundedBashToolCall,
|
||||
withRunningTerminal,
|
||||
withRunningToolCall,
|
||||
} from "./tool-calls/background.js";
|
||||
import { ChangedMetaFilter } from "./tool-calls/changed-meta-filter.js";
|
||||
import { ToolCallFieldTracker } from "./tool-calls/field-tracker.js";
|
||||
import { ClientCapabilities as ToolCallClientCapabilities } from "./tool-calls/client-capabilities.js";
|
||||
@@ -381,6 +401,7 @@ import {
|
||||
ultracodeWorkflowsEnabled,
|
||||
type UltracodeOptionState,
|
||||
} from "./session-ultracode.js";
|
||||
import { STARTUP_FAILURE_RESULTS_ENV, startupFailureError } from "./startup-failure.js";
|
||||
|
||||
export { EFFORT_CONFIG_ID, settingsEffortForModel } from "./session-effort.js";
|
||||
export {
|
||||
@@ -1454,7 +1475,9 @@ export type Session = {
|
||||
* `perTaskStopAffordance`: then it spares both, and the client is expected
|
||||
* to stop each one itself. A client that can cancel one subagent gets the
|
||||
* declaration, but it has no control for a workflow unless it is AIR with
|
||||
* `asyncTasks` (`_session/async_task/stop`). So for such a client the
|
||||
* `asyncTasks` (`_session/async_task/stop`), or gets the session's
|
||||
* background work (`reportsBackground`, with `tool_call/cancel`), which
|
||||
* `session/cancel` must leave running. So for any other such client the
|
||||
* adapter stops the workflows after the interrupt, as the interrupt did
|
||||
* before. */
|
||||
stopsWorkflowsOnCancel?: boolean;
|
||||
@@ -1465,6 +1488,18 @@ export type Session = {
|
||||
* `withRunningTerminal`). Only for a client that renders terminals and is
|
||||
* not AIR, which shows the command through its async tasks. */
|
||||
backgroundTerminals?: Map<string, { toolCallId: string; parentToolUseId?: string }>;
|
||||
/** The tool calls whose tasks went on in the background and still run, by
|
||||
* task id: a Monitor, a Workflow, or a backgrounded MCP call. The tool call
|
||||
* stays `in_progress` (or `paused`) after its result, until its task ends
|
||||
* (see `withRunningToolCall`). Only while `reportsBackground`. */
|
||||
backgroundToolCalls?: Map<string, BackgroundToolCall>;
|
||||
/** Whether the client gets the session's background work (see
|
||||
* `background-work.ts`). Only when Claude Code's interrupt spares
|
||||
* background tasks, as `perTaskStopAffordance` makes it. */
|
||||
reportsBackground?: boolean;
|
||||
/** Claude Code's live background task set, from its last
|
||||
* `background_tasks_changed`. Per CLI process, as is a session. */
|
||||
backgroundLevel?: BackgroundLevel;
|
||||
/** The parent tool call of each subagent that a settle bookend removed from
|
||||
* `liveBackgroundTasks`. The SDK can resume such a subagent under the same
|
||||
* agent id without a new `task_started` (a running `task_updated` patch or
|
||||
@@ -2442,8 +2477,8 @@ export function isReplayHiddenMetaMessage(message: unknown): boolean {
|
||||
export interface AcpClient {
|
||||
sessionUpdate(params: AcpSessionNotification): Promise<void>;
|
||||
/** `signal`, when aborted, sends `$/cancel_request` for the in-flight
|
||||
* permission request so the client can dismiss its prompt (and settle our
|
||||
* await) instead of leaving the dialog open after the turn was cancelled. */
|
||||
* permission request so the client can dismiss its prompt, and rejects the
|
||||
* call at once: a client that ignores the cancel never answers. */
|
||||
requestPermission(
|
||||
params: AcpPermissionRequest,
|
||||
signal?: AbortSignal,
|
||||
@@ -2451,7 +2486,8 @@ export interface AcpClient {
|
||||
readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse>;
|
||||
writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse>;
|
||||
/** `signal`, when aborted, sends `$/cancel_request` for the in-flight
|
||||
* elicitation so the client can dismiss its prompt and settle our await. */
|
||||
* elicitation so the client can dismiss its prompt, and rejects the call
|
||||
* at once, as {@link requestPermission} does. */
|
||||
createElicitation(
|
||||
params: CreateElicitationRequest,
|
||||
signal?: AbortSignal,
|
||||
@@ -2480,6 +2516,7 @@ class ClientConnection implements AcpClient {
|
||||
): Promise<RequestPermissionResponse> {
|
||||
return this.ctx.request(methods.client.session.requestPermission, params, {
|
||||
cancellationSignal: signal,
|
||||
stopWaitingOnCancel: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2497,6 +2534,7 @@ class ClientConnection implements AcpClient {
|
||||
): Promise<CreateElicitationResponse> {
|
||||
return this.ctx.request(methods.client.elicitation.create, params, {
|
||||
cancellationSignal: signal,
|
||||
stopWaitingOnCancel: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2824,6 +2862,8 @@ export class ClaudeAcpAgent {
|
||||
>();
|
||||
/** See the `foreground` constructor option. */
|
||||
private readonly foregroundEvents?: (sessionId: string) => ForegroundEvents;
|
||||
/** See the `background` constructor option. */
|
||||
private readonly backgroundWork: BackgroundWorkReporter;
|
||||
/** Counts the prompts `startTurn()` has received, across sessions. */
|
||||
private promptsReceived = 0;
|
||||
/** Per session, the `promptsReceived` count when its last cancel started.
|
||||
@@ -2875,10 +2915,17 @@ export class ClaudeAcpAgent {
|
||||
* ended from its prompt response.
|
||||
*/
|
||||
foreground?: (sessionId: string) => ForegroundEvents;
|
||||
/**
|
||||
* Where the agent reports the background work of each session (see
|
||||
* `background-work.ts`): once when the session starts, and each time
|
||||
* the work changes. Without it, nothing reports the work.
|
||||
*/
|
||||
background?: BackgroundSink;
|
||||
} = {},
|
||||
) {
|
||||
this.v2 = options.v2 ?? false;
|
||||
this.foregroundEvents = options.foreground;
|
||||
this.backgroundWork = new BackgroundWorkReporter(options.background);
|
||||
this.sessions = {};
|
||||
this.client = new ChangedMetaClient(client, () => this.toolCallCapabilities.air.client);
|
||||
this.logger = logger ?? console;
|
||||
@@ -5370,27 +5417,15 @@ export class ClaudeAcpAgent {
|
||||
this.syncAwaitingUser(params.sessionId, session);
|
||||
};
|
||||
|
||||
/** Ends the display terminal of a command that went to the background, once
|
||||
* its task ends (see `Session.backgroundTerminals`). Claude Code reports no
|
||||
* exit code for it, and `completed` does not mean 0: Claude Code accepts
|
||||
* some non-zero codes as a success, such as grep's 1. */
|
||||
const endBackgroundTerminal = async (taskId: string) => {
|
||||
const terminal = session.backgroundTerminals?.get(taskId);
|
||||
if (!terminal) return;
|
||||
session.backgroundTerminals!.delete(taskId);
|
||||
await sendUpdate({
|
||||
sessionId: params.sessionId,
|
||||
update: {
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: terminal.toolCallId,
|
||||
_meta: {
|
||||
...(terminal.parentToolUseId
|
||||
? { claudeCode: { parentToolUseId: terminal.parentToolUseId } }
|
||||
: {}),
|
||||
terminal_exit: { terminal_id: terminal.toolCallId, exit_code: null, signal: null },
|
||||
},
|
||||
},
|
||||
});
|
||||
/** Ends the display terminal of a command that went to the background, and
|
||||
* gives a tool call whose task went on in the background its final
|
||||
* status, once the task ends (see `Session.backgroundTerminals` and
|
||||
* `Session.backgroundToolCalls`). */
|
||||
const endBackgroundTask = async (taskId: string, end: BackgroundTaskEnd) => {
|
||||
const exit = takeBackgroundTerminalExit(session, params.sessionId, taskId);
|
||||
if (exit) await sendUpdate(exit);
|
||||
const toolCallEnd = takeBackgroundToolCallEnd(session, params.sessionId, taskId, end);
|
||||
if (toolCallEnd) await sendUpdate(toolCallEnd);
|
||||
};
|
||||
|
||||
/** Settles a task. Its request may still be open, and an agent without a
|
||||
@@ -5921,6 +5956,9 @@ export class ClaudeAcpAgent {
|
||||
// pulled only after the pause.
|
||||
const pause = messageLoopYielder.maybeYield();
|
||||
if (pause) await pause;
|
||||
// The last message may have changed the background work, and its
|
||||
// updates are sent, so the list follows them.
|
||||
this.backgroundWork.sync(params.sessionId, session, this.foregroundState(params.sessionId));
|
||||
pendingNext ??= session.query
|
||||
.next()
|
||||
.then((result) => ({ kind: "message" as const, result }));
|
||||
@@ -6839,7 +6877,7 @@ export class ClaudeAcpAgent {
|
||||
streamedBlocksByParent.delete(message.tool_use_id);
|
||||
droppedStreams.delete(message.tool_use_id);
|
||||
}
|
||||
await endBackgroundTerminal(message.task_id);
|
||||
await endBackgroundTask(message.task_id, message.status);
|
||||
if (message.status === "stopped") {
|
||||
await closeStoppedSubagentToolCalls(message.tool_use_id);
|
||||
}
|
||||
@@ -6884,15 +6922,33 @@ export class ClaudeAcpAgent {
|
||||
streamedBlocksByParent.delete(parentToolUseId);
|
||||
droppedStreams.delete(parentToolUseId);
|
||||
}
|
||||
await endBackgroundTerminal(message.task_id);
|
||||
await endBackgroundTask(
|
||||
message.task_id,
|
||||
message.patch.status === "killed" ? "stopped" : message.patch.status,
|
||||
);
|
||||
if (message.patch.status === "killed") {
|
||||
await closeStoppedSubagentToolCalls(parentToolUseId);
|
||||
}
|
||||
settleLiveTask(message.task_id);
|
||||
} else if (message.patch.status === "paused") {
|
||||
const pause = backgroundToolCallPause(
|
||||
session,
|
||||
params.sessionId,
|
||||
message.task_id,
|
||||
true,
|
||||
);
|
||||
if (pause) await sendUpdate(pause);
|
||||
} else if (
|
||||
message.patch.status === "running" ||
|
||||
message.patch.status === "pending"
|
||||
) {
|
||||
const resume = backgroundToolCallPause(
|
||||
session,
|
||||
params.sessionId,
|
||||
message.task_id,
|
||||
false,
|
||||
);
|
||||
if (resume) await sendUpdate(resume);
|
||||
// The SDK can resume a finished subagent under the same
|
||||
// agent id without a new task_started.
|
||||
resumeLiveTask(message.task_id);
|
||||
@@ -7060,8 +7116,15 @@ export class ClaudeAcpAgent {
|
||||
// control requests, which this adapter never issues.
|
||||
case "control_request_progress":
|
||||
break;
|
||||
case "background_tasks_changed":
|
||||
case "background_tasks_changed": {
|
||||
await asyncTasks.backgroundTasksChanged(message.tasks);
|
||||
if (session.reportsBackground) {
|
||||
const level = backgroundLevel(message.tasks);
|
||||
for (const taskId of droppedTasks(session, level)) {
|
||||
await endBackgroundTask(taskId, undefined);
|
||||
}
|
||||
session.backgroundLevel = level;
|
||||
}
|
||||
// A level signal: the full live background-task set on every
|
||||
// membership change, with REPLACE semantics. Used only to
|
||||
// reconcile `liveBackgroundTasks` — dropping (or, for
|
||||
@@ -7105,6 +7168,7 @@ export class ClaudeAcpAgent {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
unreachable(message, this.logger);
|
||||
break;
|
||||
@@ -8463,6 +8527,7 @@ export class ClaudeAcpAgent {
|
||||
const acceptedPlanToolUseId = observeExitPlanToolResults(message, content, session);
|
||||
let backgroundedToolCalls: ReadonlySet<string> = new Set();
|
||||
let runningTerminal: string | undefined;
|
||||
let runningToolCalls: ReadonlySet<string> = new Set();
|
||||
if (message.type === "user") {
|
||||
rememberResolvedToolNames(session, content);
|
||||
recordSubagentFileEdits(
|
||||
@@ -8495,6 +8560,13 @@ export class ClaudeAcpAgent {
|
||||
: {}),
|
||||
});
|
||||
}
|
||||
runningToolCalls = registerBackgroundToolCalls(
|
||||
session,
|
||||
content,
|
||||
toolUseResult,
|
||||
session.toolUseCache,
|
||||
message.parent_tool_use_id,
|
||||
);
|
||||
await asyncTasks.toolResults(content);
|
||||
backgroundedToolCalls = backgroundedBashToolCallIds(
|
||||
content,
|
||||
@@ -8557,13 +8629,16 @@ export class ClaudeAcpAgent {
|
||||
// (e.g. a subagent image) carry the stamped parentToolUseId
|
||||
// meta and are excluded there.
|
||||
await sendUpdate(
|
||||
withRunningTerminal(
|
||||
backgroundedBashToolCall(
|
||||
acceptedPlanToolResult(notification, acceptedPlanToolUseId),
|
||||
backgroundedToolCalls,
|
||||
asyncTasks.enabled,
|
||||
withRunningToolCall(
|
||||
withRunningTerminal(
|
||||
backgroundedBashToolCall(
|
||||
acceptedPlanToolResult(notification, acceptedPlanToolUseId),
|
||||
backgroundedToolCalls,
|
||||
asyncTasks.enabled,
|
||||
),
|
||||
runningTerminal,
|
||||
),
|
||||
runningTerminal,
|
||||
runningToolCalls,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -9278,9 +9353,17 @@ export class ClaudeAcpAgent {
|
||||
return;
|
||||
}
|
||||
session.queryClosed = true;
|
||||
// Its list row now shows what the registry and the transcript tell.
|
||||
for (const [sessionId, candidate] of Object.entries(this.sessions)) {
|
||||
if (candidate === session) this.sessionIndex.onOwnSessionChanged(sessionId);
|
||||
if (candidate !== session) continue;
|
||||
// Its list row now shows what the registry and the transcript tell.
|
||||
this.sessionIndex.onOwnSessionChanged(sessionId);
|
||||
// Its background tasks end with the query's process.
|
||||
for (const exit of endBackgroundWork(session, sessionId)) {
|
||||
this.client.sessionUpdate(exit).catch((error) => {
|
||||
this.logger.error(`Session ${sessionId}: failed to end a background terminal:`, error);
|
||||
});
|
||||
}
|
||||
this.backgroundWork.sync(sessionId, session, this.foregroundState(sessionId));
|
||||
}
|
||||
session.consumer = undefined;
|
||||
session.contextCompaction = undefined;
|
||||
@@ -9336,6 +9419,7 @@ export class ClaudeAcpAgent {
|
||||
session.asyncTaskRuntime?.clear();
|
||||
this.replayedChildModels.delete(sessionId);
|
||||
this.cancelledThrough.delete(sessionId);
|
||||
this.backgroundWork.forget(sessionId);
|
||||
delete this.sessions[sessionId];
|
||||
this.sessionIndex.onTeardown(sessionId);
|
||||
const ended = await raceTimeoutAndAbort(
|
||||
@@ -9382,6 +9466,57 @@ export class ClaudeAcpAgent {
|
||||
return {};
|
||||
}
|
||||
|
||||
/** Stops a command running in the background (v2 `terminal/cancel`, see
|
||||
* {@link cancelBackgroundWork}). */
|
||||
cancelBackgroundTerminal(params: { sessionId: string; terminalId: string }): Promise<void> {
|
||||
return cancelBackgroundWork(this.sessions, params.sessionId, {
|
||||
terminalId: params.terminalId,
|
||||
});
|
||||
}
|
||||
|
||||
/** Stops the task of a tool call running in the background (v2
|
||||
* `tool_call/cancel`, see {@link cancelBackgroundWork}). */
|
||||
cancelBackgroundToolCall(params: { sessionId: string; toolCallId: string }): Promise<void> {
|
||||
return cancelBackgroundWork(this.sessions, params.sessionId, {
|
||||
toolCallId: params.toolCallId,
|
||||
});
|
||||
}
|
||||
|
||||
/** Sends the current state of each tool call in `toolCallIds` that the root
|
||||
* session `sessionId` runs in the background: the call as its tool use
|
||||
* shows it, with its status now. v2 requires it for each tool call that a
|
||||
* `session/resume` snapshot lists. A failure is logged, as for
|
||||
* {@link publishLiveSubagents}. */
|
||||
async publishBackgroundToolCalls(sessionId: string, toolCallIds: string[]): Promise<void> {
|
||||
const session = this.sessions[sessionId];
|
||||
if (!session) return;
|
||||
const renderer = new AcpToolCallRenderer(this.toolCallCapabilities);
|
||||
try {
|
||||
for (const update of backgroundToolCallStates(session, sessionId, toolCallIds, renderer)) {
|
||||
await this.client.sessionUpdate(update);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Session ${sessionId}: failed to send background tool calls:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sends the current `subagent_update` of each live subagent session in
|
||||
* `children`, of the session `sessionId` (see
|
||||
* {@link NativeSubagentRuntime.currentUpdate}). v2 requires it for each
|
||||
* child that a `session/resume` snapshot lists. A failure is logged, as
|
||||
* for {@link publishCurrentSubagentStates}. */
|
||||
async publishLiveSubagents(sessionId: string, children: string[]): Promise<void> {
|
||||
const runtime = this.sessions[sessionId]?.nativeSubagentRuntime;
|
||||
try {
|
||||
for (const child of children) {
|
||||
const update = runtime?.currentUpdate(child);
|
||||
if (update) await this.client.sessionUpdate(asSdkSessionNotification(update));
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Session ${sessionId}: failed to send current subagent states:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Per client: see {@link sessionIndex.SessionIndexConnection.deleteSession}. */
|
||||
async deleteSession(params: DeleteSessionRequest): Promise<DeleteSessionResponse> {
|
||||
return this.sessionIndex.deleteSession(params);
|
||||
@@ -10330,10 +10465,9 @@ export class ClaudeAcpAgent {
|
||||
/** Forward a permission request to the client, wiring the tool call's
|
||||
* `signal` through as a `cancellationSignal`. When the turn is cancelled
|
||||
* while the client's prompt is still open the signal aborts, the SDK sends
|
||||
* `$/cancel_request`, and our local abort race settles even if the client
|
||||
* ignores it. A request rejection and a local abort surface the same
|
||||
* "Tool use aborted" that the callers expect. `canUseTool` decides what a
|
||||
* `cancelled` outcome means. */
|
||||
* `$/cancel_request` and stops waiting for the client's answer. The
|
||||
* rejection surfaces as the "Tool use aborted" that the callers expect.
|
||||
* `canUseTool` decides what a `cancelled` outcome means. */
|
||||
private async requestPermissionFromClient(
|
||||
params: AcpPermissionRequest,
|
||||
toolName: string,
|
||||
@@ -10364,9 +10498,6 @@ export class ClaudeAcpAgent {
|
||||
);
|
||||
if (signal.aborted) throw new Error("Tool use aborted");
|
||||
|
||||
// Do not rely on every ACP client settling requestPermission after the
|
||||
// cancellation signal. The local race guarantees that Claude's tool call
|
||||
// is released even when an older or broken client ignores $/cancel_request.
|
||||
// The request goes to a subagent's child session for a tool call of that
|
||||
// subagent, but it blocks the turn of the owner session.
|
||||
try {
|
||||
@@ -10374,7 +10505,7 @@ export class ClaudeAcpAgent {
|
||||
this.withPendingUserInput(
|
||||
ownerSessionId,
|
||||
signal,
|
||||
() => raceWithAbort(this.client.requestPermission(params, signal), signal),
|
||||
() => this.client.requestPermission(params, signal),
|
||||
agentID,
|
||||
),
|
||||
);
|
||||
@@ -10387,25 +10518,24 @@ export class ClaudeAcpAgent {
|
||||
}
|
||||
|
||||
/** Send the client an elicitation for a callback of Claude Code. When the
|
||||
* callback's `signal` aborts, the SDK sends `$/cancel_request` and keeps
|
||||
* waiting for the client's reply, which a client that ignores the cancel
|
||||
* never sends. So the call also rejects at once on the abort, as
|
||||
* {@link requestPermissionFromClient} does for a permission request. Left
|
||||
* open, the request would stay in `openUserInputs` (see
|
||||
* {@link withPendingUserInput}), which keeps steering non-interrupting, and
|
||||
* a child's `openRequests` would not drop. */
|
||||
* callback's `signal` aborts, the SDK sends `$/cancel_request` and the call
|
||||
* rejects at once, without waiting for a reply that a client ignoring the
|
||||
* cancel never sends. Left open, the request would stay in
|
||||
* `openUserInputs` (see {@link withPendingUserInput}), which keeps steering
|
||||
* non-interrupting, and a child's `openRequests` would not drop. */
|
||||
private elicitFromClient(
|
||||
request: CreateElicitationRequest,
|
||||
signal: AbortSignal,
|
||||
): Promise<CreateElicitationResponse> {
|
||||
return raceWithAbort(this.client.createElicitation(request, signal), signal);
|
||||
return this.client.createElicitation(request, signal);
|
||||
}
|
||||
|
||||
/** `signal`, also aborted when `teardownSession` aborts the
|
||||
* `abortController` of session `sessionId`. Claude Code aborts a callback's
|
||||
* own signal when its query closes, but not necessarily before
|
||||
* `session/close` responds, and v2 requires every pending elicitation of
|
||||
* the session to be cancelled with `$/cancel_request` before that response. */
|
||||
* `session/close` responds, and v2 requires every pending permission
|
||||
* request and elicitation of the session to be cancelled with
|
||||
* `$/cancel_request` before that response. */
|
||||
private untilSessionClosed(sessionId: string, signal: AbortSignal): AbortSignal {
|
||||
const sessionSignal = this.sessions[sessionId]?.abortController?.signal;
|
||||
return sessionSignal ? AbortSignal.any([signal, sessionSignal]) : signal;
|
||||
@@ -12064,6 +12194,7 @@ export class ClaudeAcpAgent {
|
||||
...providerEnv,
|
||||
// Opt-in to session state events like when the agent is idle
|
||||
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1",
|
||||
...STARTUP_FAILURE_RESULTS_ENV,
|
||||
};
|
||||
// Scopes the context-window cache to this query's backend (see
|
||||
// `contextWindowCache`). Derived from the same `env` object handed to the
|
||||
@@ -12318,7 +12449,7 @@ export class ClaudeAcpAgent {
|
||||
) {
|
||||
throw RequestError.sessionNotFound(sessionId);
|
||||
}
|
||||
throw error;
|
||||
throw startupFailureError(error) ?? error;
|
||||
}
|
||||
timing.phase("sdk-initialize");
|
||||
|
||||
@@ -12595,8 +12726,10 @@ export class ClaudeAcpAgent {
|
||||
emittedToolCalls: new Set(),
|
||||
eagerToolCallSessions: new Map(),
|
||||
liveBackgroundTasks: new Map(),
|
||||
reportsBackground: this.backgroundWork.enabled && options.perTaskStopAffordance === true,
|
||||
stopsWorkflowsOnCancel:
|
||||
options.perTaskStopAffordance === true &&
|
||||
!this.backgroundWork.enabled &&
|
||||
!clientSupportsAsyncTasks(this.clientCapabilities),
|
||||
nativeSubagentsByTaskId: new Map(),
|
||||
nativeSubagentTaskIdByToolUseId: new Map(),
|
||||
@@ -12614,6 +12747,11 @@ export class ClaudeAcpAgent {
|
||||
fileChangeReporter,
|
||||
};
|
||||
timing.phase("register");
|
||||
this.backgroundWork.sync(
|
||||
sessionId,
|
||||
this.sessions[sessionId],
|
||||
this.foregroundState(sessionId),
|
||||
);
|
||||
this.refreshContextWindowInBackground(sessionId, this.sessions[sessionId]);
|
||||
|
||||
return {
|
||||
|
||||
531
src/background-work.ts
Normal file
531
src/background-work.ts
Normal file
@@ -0,0 +1,531 @@
|
||||
/**
|
||||
* The background work of a session: the work that Claude Code keeps running
|
||||
* independently of the session's foreground work, which ACP v2 lists on every
|
||||
* `state_update` of the session as `background` (the v2 prompt lifecycle,
|
||||
* "Background work").
|
||||
*
|
||||
* The lists are built from Claude Code's live background task set
|
||||
* (`background_tasks_changed`), without the tasks it marks `ambient`, which
|
||||
* are housekeeping that it started on its own. The root session and each
|
||||
* announced subagent session (the subagents RFD form) has its own list. Each
|
||||
* task is listed once, in the list of the session that runs it:
|
||||
*
|
||||
* - A command that went to the background: its display terminal, from the
|
||||
* Bash tool result until its task ends (`Session.backgroundTerminals`).
|
||||
* - A detached subagent: its child session, in its parent's list, while it
|
||||
* works, and while it is idle with background work of its own.
|
||||
* - A task that a tool call started, such as a `Monitor`, a `Workflow` or a
|
||||
* backgrounded MCP call: that tool call, kept `in_progress` (or `paused`)
|
||||
* from its tool result until its task ends (`Session.backgroundToolCalls`).
|
||||
* - Any other task, once its `task_started` came and the tool call that
|
||||
* started it, if any, returned: a `_claude/task` item with the task's id
|
||||
* and description. For example, a task whose tool call ended before the
|
||||
* task joined the level.
|
||||
*
|
||||
* Only a session whose interrupt spares background tasks reports its lists
|
||||
* (`Session.reportsBackground`): `session/cancel` must leave listed work
|
||||
* running.
|
||||
*/
|
||||
import { RequestError } from "@agentclientprotocol/sdk/unstable";
|
||||
import type { AcpSessionNotification } from "./acp-subagents.js";
|
||||
import type { NativeSubagent } from "./native-subagents.js";
|
||||
import { type AcpToolCallRenderer, V2_CANCELLED, V2_PAUSED } from "./tool-calls/renderer.js";
|
||||
|
||||
/** An item of a `background` list. */
|
||||
export type BackgroundItem =
|
||||
| { type: "terminal"; terminalId: string }
|
||||
| { type: "tool_call"; toolCallId: string }
|
||||
| { type: "subagent"; sessionId: string }
|
||||
| { type: "_claude/task"; taskId: string; description: string };
|
||||
|
||||
/** A tool call whose task runs on in the background (see `Session.backgroundToolCalls`). */
|
||||
export interface BackgroundToolCall {
|
||||
toolCallId: string;
|
||||
/** The tool use of the call, which Claude Code no longer caches after its result. */
|
||||
toolUse: { name: string; input: unknown };
|
||||
/** The subagent tool call that made the call, if any. */
|
||||
parentToolUseId?: string;
|
||||
paused?: boolean;
|
||||
}
|
||||
|
||||
/** How a background task ended, as Claude Code reports it. Undefined when it did not say. */
|
||||
export type BackgroundTaskEnd = "completed" | "failed" | "stopped" | undefined;
|
||||
|
||||
/** The live background task set of `background_tasks_changed`, by task id. */
|
||||
export type BackgroundLevel = Map<
|
||||
string,
|
||||
{ ambient: boolean; taskType: string; description: string; parentTaskId?: string }
|
||||
>;
|
||||
|
||||
/** The work state of a session, as its `state_update` names it. */
|
||||
export type WorkStateName = "idle" | "running" | "requires_action" | "unknown";
|
||||
|
||||
/** A new list of the session `sessionId`, with what its repeated state needs. */
|
||||
export interface BackgroundReport {
|
||||
sessionId: string;
|
||||
items: BackgroundItem[];
|
||||
/** The session's work state now, or undefined when it has none yet. */
|
||||
state: WorkStateName | undefined;
|
||||
/** The parent of a subagent session, which mirrors the child's state. */
|
||||
parentSessionId?: string;
|
||||
}
|
||||
|
||||
/** Where the agent reports the lists (see the agent's `background` option). */
|
||||
export interface BackgroundSink {
|
||||
/** The list of a session changed, or is reported for the first time. */
|
||||
changed(report: BackgroundReport): void;
|
||||
/** The session ended: its list is no longer reported. */
|
||||
forget(sessionId: string): void;
|
||||
}
|
||||
|
||||
/** The state of a session that its lists are built from. */
|
||||
export interface BackgroundWorkSession {
|
||||
reportsBackground?: boolean;
|
||||
backgroundLevel?: BackgroundLevel;
|
||||
backgroundTerminals?: Map<string, { toolCallId: string; parentToolUseId?: string }>;
|
||||
backgroundToolCalls?: Map<string, BackgroundToolCall>;
|
||||
nativeSubagentsByTaskId?: Map<string, NativeSubagent>;
|
||||
liveBackgroundTasks?: Map<string, { parentToolUseId?: string; isSubagent: boolean }>;
|
||||
/** The tool uses whose result has not come yet, by id. */
|
||||
toolUseCache?: Record<string, unknown>;
|
||||
query: { stopTask(taskId: string): Promise<void> };
|
||||
}
|
||||
|
||||
/** The tools whose structured result names the task that the call started. */
|
||||
const TASK_TOOLS = new Set(["Monitor", "Workflow"]);
|
||||
|
||||
/**
|
||||
* Registers each tool call of a tool result message whose task goes on in
|
||||
* the background: a `Monitor` or `Workflow` call, whose structured result
|
||||
* names its task, or a call that a live task names as its tool use, such as
|
||||
* a backgrounded MCP call. The task must be in the level: one that ended
|
||||
* already, or that Claude Code marks `ambient`, leaves its call as it is.
|
||||
* Returns the ids of the calls, whose result then reports `in_progress` (see
|
||||
* `withRunningToolCall`).
|
||||
*/
|
||||
export function registerBackgroundToolCalls(
|
||||
session: BackgroundWorkSession,
|
||||
content: unknown,
|
||||
toolUseResult: unknown,
|
||||
toolUses: Record<string, { name: string; input: unknown }>,
|
||||
parentToolUseId: string | null,
|
||||
): Set<string> {
|
||||
const registered = new Set<string>();
|
||||
if (!session.reportsBackground || !Array.isArray(content)) return registered;
|
||||
const results = content.filter(
|
||||
(block): block is { type: "tool_result"; tool_use_id: string; is_error?: boolean } =>
|
||||
typeof block === "object" &&
|
||||
block !== null &&
|
||||
block.type === "tool_result" &&
|
||||
typeof block.tool_use_id === "string" &&
|
||||
block.is_error !== true,
|
||||
);
|
||||
const structuredTaskId =
|
||||
results.length === 1 &&
|
||||
typeof toolUseResult === "object" &&
|
||||
toolUseResult !== null &&
|
||||
typeof (toolUseResult as { taskId?: unknown }).taskId === "string"
|
||||
? (toolUseResult as { taskId: string }).taskId
|
||||
: undefined;
|
||||
for (const { tool_use_id: toolCallId } of results) {
|
||||
const toolUse = toolUses[toolCallId];
|
||||
if (!toolUse) continue;
|
||||
const taskId =
|
||||
(TASK_TOOLS.has(toolUse.name) ? structuredTaskId : undefined) ??
|
||||
[...(session.liveBackgroundTasks ?? [])].find(
|
||||
([, task]) => task.parentToolUseId === toolCallId && !task.isSubagent,
|
||||
)?.[0];
|
||||
const task = taskId === undefined ? undefined : session.backgroundLevel?.get(taskId);
|
||||
if (
|
||||
!task ||
|
||||
task.ambient ||
|
||||
task.taskType === "local_bash" ||
|
||||
task.taskType === "local_agent"
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
(session.backgroundToolCalls ??= new Map()).set(taskId!, {
|
||||
toolCallId,
|
||||
toolUse,
|
||||
...(parentToolUseId ? { parentToolUseId } : {}),
|
||||
});
|
||||
registered.add(toolCallId);
|
||||
}
|
||||
return registered;
|
||||
}
|
||||
|
||||
/** The level of a `background_tasks_changed` payload. */
|
||||
export function backgroundLevel(
|
||||
tasks: {
|
||||
task_id: string;
|
||||
task_type: string;
|
||||
description: string;
|
||||
parent_task_id?: string;
|
||||
ambient?: boolean;
|
||||
}[],
|
||||
): BackgroundLevel {
|
||||
return new Map(
|
||||
tasks.map((task) => [
|
||||
task.task_id,
|
||||
{
|
||||
ambient: task.ambient === true,
|
||||
taskType: task.task_type,
|
||||
description: task.description,
|
||||
...(task.parent_task_id !== undefined ? { parentTaskId: task.parent_task_id } : {}),
|
||||
},
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `background` list of the root session `rootSessionId` and of each of
|
||||
* its announced subagent sessions, by session id, deeper sessions first and
|
||||
* the root last. Each list is empty while
|
||||
* the level has not been reported: Claude Code sends none before the first
|
||||
* background task starts.
|
||||
*/
|
||||
export function backgroundLists(
|
||||
session: BackgroundWorkSession,
|
||||
rootSessionId: string,
|
||||
): Map<string, BackgroundItem[]> {
|
||||
const children = [...(session.nativeSubagentsByTaskId ?? [])].filter(
|
||||
([, child]) => child.announced,
|
||||
);
|
||||
const childByTask = new Map(children);
|
||||
const childByToolUse = new Map(
|
||||
children.flatMap(([, child]) =>
|
||||
child.parentToolUseId ? [[child.parentToolUseId, child] as const] : [],
|
||||
),
|
||||
);
|
||||
const lists = new Map<string, BackgroundItem[]>([
|
||||
[rootSessionId, []],
|
||||
...children.map(([, child]): [string, BackgroundItem[]] => [child.sessionId, []]),
|
||||
]);
|
||||
const level: BackgroundLevel = session.backgroundLevel ?? new Map();
|
||||
for (const [taskId, task] of level) {
|
||||
if (task.ambient) continue;
|
||||
// A subagent's command or tool call runs on the child's stream.
|
||||
const ownerOf = (parentToolUseId: string | undefined) =>
|
||||
parentToolUseId ? childByToolUse.get(parentToolUseId)?.sessionId : rootSessionId;
|
||||
const terminal = session.backgroundTerminals?.get(taskId);
|
||||
if (terminal) {
|
||||
const owner = ownerOf(terminal.parentToolUseId);
|
||||
if (owner) lists.get(owner)!.push({ type: "terminal", terminalId: terminal.toolCallId });
|
||||
continue;
|
||||
}
|
||||
const toolCall = session.backgroundToolCalls?.get(taskId);
|
||||
if (toolCall) {
|
||||
const owner = ownerOf(toolCall.parentToolUseId);
|
||||
if (owner) lists.get(owner)!.push({ type: "tool_call", toolCallId: toolCall.toolCallId });
|
||||
continue;
|
||||
}
|
||||
// A command without a terminal yet is one that foreground work waits on.
|
||||
// A subagent is listed below, as its session.
|
||||
if (task.taskType === "local_bash" || task.taskType === "local_agent") continue;
|
||||
// A task joins the level before its `task_started`, and before the tool
|
||||
// call that starts it returns. Until both, the task is unknown or part of
|
||||
// that tool call, which the foreground work waits on. Claude Code drops a
|
||||
// tool use from its cache at the tool's result.
|
||||
const live = session.liveBackgroundTasks?.get(taskId);
|
||||
if (!live || (live.parentToolUseId && session.toolUseCache?.[live.parentToolUseId])) {
|
||||
continue;
|
||||
}
|
||||
const parent = task.parentTaskId ? childByTask.get(task.parentTaskId) : undefined;
|
||||
lists
|
||||
.get(parent?.sessionId ?? rootSessionId)!
|
||||
.push({ type: "_claude/task", taskId, description: task.description });
|
||||
}
|
||||
// A child is listed in its parent's list while it works in the background,
|
||||
// and while it is idle with background work of its own. Deeper children
|
||||
// first, so a child's list is whole before its parent's reads it.
|
||||
const sessions = new Map(children.map(([, child]) => [child.sessionId, child]));
|
||||
const depth = (child: NativeSubagent): number => {
|
||||
const parent = sessions.get(child.parentSessionId);
|
||||
return parent ? depth(parent) + 1 : 0;
|
||||
};
|
||||
for (const [taskId, child] of children.sort(([, a], [, b]) => depth(b) - depth(a))) {
|
||||
const task = level.get(taskId);
|
||||
const working =
|
||||
child.workState !== undefined &&
|
||||
child.workState !== "idle" &&
|
||||
task !== undefined &&
|
||||
!task.ambient;
|
||||
if (working || lists.get(child.sessionId)!.length > 0) {
|
||||
lists.get(child.parentSessionId)?.push({ type: "subagent", sessionId: child.sessionId });
|
||||
}
|
||||
}
|
||||
// In the same order, the root last: a child's own list goes out before its
|
||||
// parent's list drops it.
|
||||
return new Map([
|
||||
...children.map(([, child]): [string, BackgroundItem[]] => [
|
||||
child.sessionId,
|
||||
lists.get(child.sessionId)!,
|
||||
]),
|
||||
[rootSessionId, lists.get(rootSessionId)!],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The tasks of the terminals and tool calls that `level` does not hold:
|
||||
* Claude Code no longer runs them, so they end before a list drops them, as
|
||||
* v2 requires. A terminal or tool call is registered at its tool result,
|
||||
* after its task joined the level, so a later level without the task means
|
||||
* that it ended. Claude Code usually sends a task's end before that level,
|
||||
* which ends them first, but the SDK does not promise that order.
|
||||
*/
|
||||
export function droppedTasks(session: BackgroundWorkSession, level: BackgroundLevel): string[] {
|
||||
return [
|
||||
...(session.backgroundTerminals?.keys() ?? []),
|
||||
...(session.backgroundToolCalls?.keys() ?? []),
|
||||
].filter((taskId) => !level.has(taskId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the terminal of the background command `taskId` of the session
|
||||
* `sessionId`, and returns the update that exits it, or undefined when the
|
||||
* command has no terminal. Claude Code reports no exit code for it, and
|
||||
* `completed` does not mean 0: Claude Code accepts some non-zero codes as a
|
||||
* success, such as grep's 1.
|
||||
*/
|
||||
export function takeBackgroundTerminalExit(
|
||||
session: BackgroundWorkSession,
|
||||
sessionId: string,
|
||||
taskId: string,
|
||||
): AcpSessionNotification | undefined {
|
||||
const terminal = session.backgroundTerminals?.get(taskId);
|
||||
if (!terminal) return undefined;
|
||||
session.backgroundTerminals!.delete(taskId);
|
||||
return {
|
||||
sessionId,
|
||||
update: {
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: terminal.toolCallId,
|
||||
_meta: {
|
||||
...(terminal.parentToolUseId
|
||||
? { claudeCode: { parentToolUseId: terminal.parentToolUseId } }
|
||||
: {}),
|
||||
terminal_exit: { terminal_id: terminal.toolCallId, exit_code: null, signal: null },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the background tool call of the task `taskId` of the session
|
||||
* `sessionId`, and returns the update that gives it its final status, or
|
||||
* undefined when the task has no such call. A task that Claude Code stopped
|
||||
* is `cancelled`. One that ended without saying how, such as one that the
|
||||
* level dropped, is `completed`: it no longer runs, and reported no failure.
|
||||
*/
|
||||
export function takeBackgroundToolCallEnd(
|
||||
session: BackgroundWorkSession,
|
||||
sessionId: string,
|
||||
taskId: string,
|
||||
end: BackgroundTaskEnd,
|
||||
): AcpSessionNotification | undefined {
|
||||
const toolCall = session.backgroundToolCalls?.get(taskId);
|
||||
if (!toolCall) return undefined;
|
||||
session.backgroundToolCalls!.delete(taskId);
|
||||
return toolCallStatusUpdate(
|
||||
sessionId,
|
||||
toolCall,
|
||||
end === "stopped" ? V2_CANCELLED : end === "failed" ? "failed" : "completed",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The update that reports the background tool call of the task `taskId` as
|
||||
* `paused`, or as `in_progress` again, when `paused` changes it. Claude Code
|
||||
* pauses a workflow this way.
|
||||
*/
|
||||
export function backgroundToolCallPause(
|
||||
session: BackgroundWorkSession,
|
||||
sessionId: string,
|
||||
taskId: string,
|
||||
paused: boolean,
|
||||
): AcpSessionNotification | undefined {
|
||||
const toolCall = session.backgroundToolCalls?.get(taskId);
|
||||
if (!toolCall || (toolCall.paused ?? false) === paused) return undefined;
|
||||
toolCall.paused = paused;
|
||||
return toolCallStatusUpdate(sessionId, toolCall, paused ? V2_PAUSED : "in_progress");
|
||||
}
|
||||
|
||||
/**
|
||||
* The current state of each background tool call in `toolCallIds` of the
|
||||
* root session `sessionId`: the call as `renderer` shows its tool use, with
|
||||
* its status now (see `ClaudeAcpAgent.publishBackgroundToolCalls`).
|
||||
*/
|
||||
export function backgroundToolCallStates(
|
||||
session: BackgroundWorkSession & { cwd: string },
|
||||
sessionId: string,
|
||||
toolCallIds: string[],
|
||||
renderer: AcpToolCallRenderer,
|
||||
): AcpSessionNotification[] {
|
||||
return [...(session.backgroundToolCalls?.values() ?? [])]
|
||||
.filter((toolCall) => toolCallIds.includes(toolCall.toolCallId))
|
||||
.map((toolCall) => {
|
||||
const update = renderer.toolCall(
|
||||
{ id: toolCall.toolCallId, ...toolCall.toolUse },
|
||||
{ cwd: session.cwd },
|
||||
);
|
||||
const status = toolCall.paused ? V2_PAUSED : "in_progress";
|
||||
return { sessionId, update: { ...update, status } as AcpSessionNotification["update"] };
|
||||
});
|
||||
}
|
||||
|
||||
function toolCallStatusUpdate(
|
||||
sessionId: string,
|
||||
toolCall: BackgroundToolCall,
|
||||
status: NonNullable<
|
||||
Extract<AcpSessionNotification["update"], { sessionUpdate: "tool_call_update" }>["status"]
|
||||
>,
|
||||
): AcpSessionNotification {
|
||||
return {
|
||||
sessionId,
|
||||
update: {
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: toolCall.toolCallId,
|
||||
status,
|
||||
...(toolCall.parentToolUseId
|
||||
? { _meta: { claudeCode: { parentToolUseId: toolCall.parentToolUseId } } }
|
||||
: {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the background work of a session whose query closed: Claude Code's
|
||||
* background tasks end with its process. Returns the updates that exit the
|
||||
* root session's terminals and cancel its tool calls, and empties the level,
|
||||
* so the next lists are empty. A subagent's command or tool call is left as
|
||||
* it was: it is on the child's stream, which the closed query's routing
|
||||
* owned.
|
||||
*/
|
||||
export function endBackgroundWork(
|
||||
session: BackgroundWorkSession,
|
||||
sessionId: string,
|
||||
): AcpSessionNotification[] {
|
||||
if (!session.reportsBackground) return [];
|
||||
const exits = [...(session.backgroundTerminals ?? [])].flatMap(([taskId, terminal]) => {
|
||||
const exit = terminal.parentToolUseId
|
||||
? undefined
|
||||
: takeBackgroundTerminalExit(session, sessionId, taskId);
|
||||
return exit ? [exit] : [];
|
||||
});
|
||||
const ends = [...(session.backgroundToolCalls ?? [])].flatMap(([taskId, toolCall]) => {
|
||||
const end = toolCall.parentToolUseId
|
||||
? undefined
|
||||
: takeBackgroundToolCallEnd(session, sessionId, taskId, "stopped");
|
||||
return end ? [end] : [];
|
||||
});
|
||||
session.backgroundLevel = undefined;
|
||||
return [...exits, ...ends];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the task of a terminal or tool call that the session `sessionId`
|
||||
* lists (v2 `terminal/cancel` and `tool_call/cancel`). `sessions` are the
|
||||
* root sessions, by id: a subagent session's list is built with its root's.
|
||||
* The terminal exits, or the tool call gets its final status, when Claude
|
||||
* Code reports the task stopped.
|
||||
*/
|
||||
export async function cancelBackgroundWork(
|
||||
sessions: Record<string, BackgroundWorkSession>,
|
||||
sessionId: string,
|
||||
target: { terminalId: string } | { toolCallId: string },
|
||||
): Promise<void> {
|
||||
const notCancellable = () =>
|
||||
"terminalId" in target
|
||||
? RequestError.invalidParams(
|
||||
{ sessionId, terminalId: target.terminalId },
|
||||
`Terminal ${target.terminalId} is not a command running in the background, so it cannot be cancelled.`,
|
||||
)
|
||||
: RequestError.invalidParams(
|
||||
{ sessionId, toolCallId: target.toolCallId },
|
||||
`Tool call ${target.toolCallId} is not running in the background, so it cannot be cancelled.`,
|
||||
);
|
||||
const isTarget = (item: BackgroundItem) =>
|
||||
"terminalId" in target
|
||||
? item.type === "terminal" && item.terminalId === target.terminalId
|
||||
: item.type === "tool_call" && item.toolCallId === target.toolCallId;
|
||||
const listed = (root: string, session: BackgroundWorkSession) =>
|
||||
session.reportsBackground === true &&
|
||||
(backgroundLists(session, root).get(sessionId)?.some(isTarget) ?? false);
|
||||
const owner = Object.entries(sessions).find(([root, session]) => listed(root, session));
|
||||
if (!owner) throw notCancellable();
|
||||
const [root, session] = owner;
|
||||
const id = "terminalId" in target ? target.terminalId : target.toolCallId;
|
||||
const taskId = [
|
||||
...(("terminalId" in target ? session.backgroundTerminals : session.backgroundToolCalls) ?? []),
|
||||
].find(([, entry]) => entry.toolCallId === id)![0];
|
||||
try {
|
||||
await session.query.stopTask(taskId);
|
||||
} catch (error) {
|
||||
// The task ended meanwhile: it has ended on the client too, or is about to.
|
||||
if (!listed(root, session)) throw notCancellable();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes the lists of each session that reports them, each time one
|
||||
* changes. The sink sends them to the client synchronously, so a list follows
|
||||
* the updates sent before it.
|
||||
*/
|
||||
export class BackgroundWorkReporter {
|
||||
/** The list last published for each session, as JSON, and the root session it is built with. */
|
||||
private readonly published = new Map<string, { json: string; root: string }>();
|
||||
|
||||
constructor(private readonly sink?: BackgroundSink) {}
|
||||
|
||||
/** Whether the lists are reported at all. */
|
||||
get enabled(): boolean {
|
||||
return this.sink !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes each list of the root session `rootSessionId` that changed. The
|
||||
* first call for a session publishes its list, also when it is empty.
|
||||
* `rootState` is the root session's state now.
|
||||
*/
|
||||
sync(rootSessionId: string, session: BackgroundWorkSession, rootState: WorkStateName): void {
|
||||
if (!this.sink || !session.reportsBackground) return;
|
||||
const children = new Map(
|
||||
[...(session.nativeSubagentsByTaskId?.values() ?? [])].map((child) => [
|
||||
child.sessionId,
|
||||
child,
|
||||
]),
|
||||
);
|
||||
for (const [sessionId, items] of backgroundLists(session, rootSessionId)) {
|
||||
const json = JSON.stringify(items);
|
||||
if (this.published.get(sessionId)?.json === json) continue;
|
||||
this.published.set(sessionId, { json, root: rootSessionId });
|
||||
const child = children.get(sessionId);
|
||||
this.sink.changed({
|
||||
sessionId,
|
||||
items,
|
||||
state: child ? workStateName(child.workState) : rootState,
|
||||
...(child ? { parentSessionId: child.parentSessionId } : {}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** The root session `rootSessionId` ended, and its subagent sessions with it. */
|
||||
forget(rootSessionId: string): void {
|
||||
for (const [sessionId, { root }] of this.published) {
|
||||
if (root !== rootSessionId) continue;
|
||||
this.published.delete(sessionId);
|
||||
this.sink?.forget(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A child's work state, when it is one that v2 names. */
|
||||
function workStateName(state: string | undefined): WorkStateName | undefined {
|
||||
return state === "idle" ||
|
||||
state === "running" ||
|
||||
state === "requires_action" ||
|
||||
state === "unknown"
|
||||
? state
|
||||
: undefined;
|
||||
}
|
||||
@@ -303,7 +303,7 @@ export function applyAskElicitationResponse(
|
||||
questions: AskUserQuestion[],
|
||||
options: { reportUnanswered?: boolean } = {},
|
||||
): AskUserQuestionOutcome {
|
||||
// Typed against the output schema: as of SDK 0.3.312 only it lists
|
||||
// Typed against the output schema: as of SDK 0.3.316 only it lists
|
||||
// `unanswered`, though the tool reads the same annotations from its input.
|
||||
const annotations: NonNullable<AskUserQuestionOutput["annotations"]> = {};
|
||||
const withAnnotations = (answers: AskUserQuestionOutput["answers"]) => ({
|
||||
|
||||
@@ -292,6 +292,30 @@ export class NativeSubagentRuntime {
|
||||
return child?.announced ? child.workState : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RFD form: the `subagent_update` that tells a client that holds nothing
|
||||
* of the announced child `sessionId` of this live session what it is now:
|
||||
* its labels, its directory, its `cancel` capability, and its work state.
|
||||
* Undefined when no such child runs here.
|
||||
*/
|
||||
currentUpdate(sessionId: string): AcpSessionNotification | undefined {
|
||||
if (this.form !== "rfd") return undefined;
|
||||
const child = this.childOfSession(sessionId);
|
||||
if (!child?.announced || !child.workState) return undefined;
|
||||
return {
|
||||
sessionId: child.parentSessionId,
|
||||
update: {
|
||||
sessionUpdate: "subagent_update",
|
||||
sessionId: child.sessionId,
|
||||
...(child.title ? { title: child.title } : {}),
|
||||
...(child.description ? { description: child.description } : {}),
|
||||
...(child.reportedCwd ? { cwd: child.reportedCwd } : {}),
|
||||
capabilities: { cancel: {} },
|
||||
state: { state: child.workState },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the model of a child response, an exact model id, as the entry of
|
||||
* the root session's `model` option that matches it, else as the id (see
|
||||
|
||||
@@ -25,7 +25,7 @@ export type UltracodeSettingsReport = {
|
||||
};
|
||||
|
||||
// `Query.getSettings()` exists at runtime (sdk.mjs) but is missing from the
|
||||
// SDK's type declarations as of 0.3.312.
|
||||
// SDK's type declarations as of 0.3.316.
|
||||
type GetSettingsQuery = Query & {
|
||||
getSettings?: () => Promise<{
|
||||
applied?: { ultracodeAvailable?: unknown; ultracodeRequested?: unknown };
|
||||
|
||||
42
src/startup-failure.ts
Normal file
42
src/startup-failure.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { RequestError } from "@agentclientprotocol/sdk/unstable";
|
||||
import type { SDKStartupFailureReason } from "@anthropic-ai/claude-agent-sdk";
|
||||
|
||||
/** Makes the CLI write an `error_during_execution` result with a
|
||||
* `startup_failure_reason` before it exits on a known startup failure. Without
|
||||
* it, some failures (e.g. `proxy_invalid`) end with stderr and an exit code
|
||||
* alone. The SDK then rejects `initializationResult()` with an error that
|
||||
* carries the reason as `startupFailureReason`. */
|
||||
export const STARTUP_FAILURE_RESULTS_ENV = { CLAUDE_CODE_STARTUP_FAILURE_RESULTS: "1" };
|
||||
|
||||
/** The SDK's prefix on the message of an error built from an error result. */
|
||||
const ERROR_RESULT_PREFIX = "Claude Code returned an error result: ";
|
||||
|
||||
/** Reasons that signing in again, or with another account, can fix. */
|
||||
const AUTH_REQUIRED_REASONS: ReadonlySet<SDKStartupFailureReason> = new Set([
|
||||
"gateway_signin_required",
|
||||
"org_pin_mismatch",
|
||||
"org_config_refused",
|
||||
]);
|
||||
|
||||
/** The ACP error for a CLI that refused to start, or `undefined` when `error`
|
||||
* carries no `startupFailureReason` (older CLIs, failures without a known
|
||||
* cause). The message is the CLI's own, which says what to fix, e.g.
|
||||
* `Invalid proxy URL in HTTPS_PROXY: … Fix or unset HTTPS_PROXY and restart
|
||||
* Claude Code.`; `data.startupFailureReason` carries the reason. */
|
||||
export function startupFailureError(error: unknown): RequestError | undefined {
|
||||
if (!(error instanceof Error)) return undefined;
|
||||
const reason = (error as { startupFailureReason?: unknown }).startupFailureReason;
|
||||
if (typeof reason !== "string" || reason === "") return undefined;
|
||||
|
||||
const message = error.message.startsWith(ERROR_RESULT_PREFIX)
|
||||
? error.message.slice(ERROR_RESULT_PREFIX.length)
|
||||
: error.message;
|
||||
const data = { startupFailureReason: reason };
|
||||
if (AUTH_REQUIRED_REASONS.has(reason as SDKStartupFailureReason)) {
|
||||
return RequestError.authRequired(data, message);
|
||||
}
|
||||
if (reason === "cwd_unavailable") {
|
||||
return RequestError.invalidParams(data, message);
|
||||
}
|
||||
return RequestError.internalError(data, message);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeAll, beforeEach, afterAll, afterEach, vi } from "vitest";
|
||||
import { spawn, spawnSync } from "child_process";
|
||||
import {
|
||||
type AnyMessage,
|
||||
AvailableCommand,
|
||||
ClientCapabilities,
|
||||
client as acpClient,
|
||||
@@ -57,7 +58,8 @@ import {
|
||||
import { SessionTitles } from "../session-titles.js";
|
||||
import { formatUsageResponse, isUsageCommandText, parseUsageResponse } from "../usage-markdown.js";
|
||||
import { Pushable } from "../utils.js";
|
||||
import { initializeClient, makeMockQuery } from "./helpers.js";
|
||||
import { heldRequest, initializeClient, makeMockQuery } from "./helpers.js";
|
||||
import { acpProtocolRouter } from "../serve.js";
|
||||
import * as agentSdk from "@anthropic-ai/claude-agent-sdk";
|
||||
import {
|
||||
deleteSession,
|
||||
@@ -5249,7 +5251,7 @@ describe("permission request cancellation", () => {
|
||||
it("does not wait for a permission client that ignores cancellation", async () => {
|
||||
const mockClient = {
|
||||
sessionUpdate: async () => {},
|
||||
requestPermission: () => new Promise<RequestPermissionResponse>(() => {}),
|
||||
requestPermission: heldRequest<RequestPermissionResponse>,
|
||||
} as unknown as AcpClient;
|
||||
const agent = new ClaudeAcpAgent(mockClient, { log: () => {}, error: () => {} });
|
||||
const session = injectSession(agent, "session-1");
|
||||
@@ -5399,7 +5401,7 @@ describe("permission request cancellation", () => {
|
||||
"does not wait for $name when its client ignores cancellation",
|
||||
async ({ start, aborted }) => {
|
||||
// The client holds the elicitation and never answers $/cancel_request.
|
||||
const createElicitation = vi.fn(() => new Promise<CreateElicitationResponse>(() => {}));
|
||||
const createElicitation = vi.fn(heldRequest<CreateElicitationResponse>);
|
||||
const mockClient = {
|
||||
sessionUpdate: async () => {},
|
||||
createElicitation,
|
||||
@@ -5429,12 +5431,10 @@ describe("permission request cancellation", () => {
|
||||
"cancels $name before session/close responds",
|
||||
async ({ start, aborted }) => {
|
||||
const events: string[] = [];
|
||||
const createElicitation = vi.fn(
|
||||
(_params: unknown, signal: AbortSignal) =>
|
||||
new Promise<CreateElicitationResponse>(() => {
|
||||
signal.addEventListener("abort", () => events.push("cancel_request"), { once: true });
|
||||
}),
|
||||
);
|
||||
const createElicitation = vi.fn((params: unknown, signal: AbortSignal) => {
|
||||
signal.addEventListener("abort", () => events.push("cancel_request"), { once: true });
|
||||
return heldRequest<CreateElicitationResponse>(params, signal);
|
||||
});
|
||||
const mockClient = {
|
||||
sessionUpdate: async () => {},
|
||||
createElicitation,
|
||||
@@ -5455,14 +5455,72 @@ describe("permission request cancellation", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "a permission request",
|
||||
start: (agent: ClaudeAcpAgent, signal: AbortSignal) =>
|
||||
agent.canUseTool("session-1")("Bash", { command: "ls" }, {
|
||||
signal,
|
||||
suggestions: [],
|
||||
toolUseID: "tool-1",
|
||||
} as any),
|
||||
},
|
||||
elicitations[0],
|
||||
])(
|
||||
"cancels $name over the connection and stops waiting for a client that ignores it",
|
||||
async ({ start }) => {
|
||||
const toAgent = new TransformStream<AnyMessage, AnyMessage>();
|
||||
const toClient = new TransformStream<AnyMessage, AnyMessage>();
|
||||
let agent!: ClaudeAcpAgent;
|
||||
acpProtocolRouter(
|
||||
{ log: () => {}, error: () => {} },
|
||||
(created) => (agent = created),
|
||||
"v1",
|
||||
).connect({ readable: toAgent.readable, writable: toClient.writable });
|
||||
const cancelled: string[] = [];
|
||||
// The client holds each request. The signal also aborts when the
|
||||
// connection closes, with another reason than `-32800`.
|
||||
const hold = ({ method, signal }: { method: string; signal: AbortSignal }) =>
|
||||
new Promise<never>(() => {
|
||||
signal.addEventListener("abort", () => {
|
||||
if ((signal.reason as { code?: unknown } | undefined)?.code === -32800) {
|
||||
cancelled.push(method);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await acpClient({ name: "test-client" })
|
||||
.onRequest(methods.client.session.requestPermission, hold)
|
||||
.onRequest(methods.client.elicitation.create, hold)
|
||||
.connectWith(
|
||||
{ readable: toClient.readable, writable: toAgent.writable },
|
||||
async (client) => {
|
||||
await client.request(methods.agent.initialize, {
|
||||
protocolVersion: 1,
|
||||
clientCapabilities: { elicitation: { form: {} } },
|
||||
});
|
||||
const session = injectSession(agent, "session-1");
|
||||
session.emittedToolCalls.add("tool-1");
|
||||
const controller = new AbortController();
|
||||
const pending = start(agent, controller.signal);
|
||||
await vi.waitFor(() => expect(session.openUserInputs?.size).toBe(1));
|
||||
controller.abort();
|
||||
|
||||
await expect(pending).rejects.toThrow("Tool use aborted");
|
||||
await vi.waitFor(() => expect(cancelled).toHaveLength(1));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("cancels a permission request before session/close responds", async () => {
|
||||
const events: string[] = [];
|
||||
const mockClient = {
|
||||
sessionUpdate: async () => {},
|
||||
requestPermission: (_params: RequestPermissionRequest, signal?: AbortSignal) =>
|
||||
new Promise<RequestPermissionResponse>(() => {
|
||||
signal?.addEventListener("abort", () => events.push("cancel_request"), { once: true });
|
||||
}),
|
||||
requestPermission: (params: RequestPermissionRequest, signal?: AbortSignal) => {
|
||||
signal?.addEventListener("abort", () => events.push("cancel_request"), { once: true });
|
||||
return heldRequest<RequestPermissionResponse>(params, signal);
|
||||
},
|
||||
} as unknown as AcpClient;
|
||||
const agent = new ClaudeAcpAgent(mockClient, { log: () => {}, error: () => {} });
|
||||
const session = injectSession(agent, "session-1");
|
||||
@@ -5481,32 +5539,6 @@ describe("permission request cancellation", () => {
|
||||
await expect(pending).rejects.toThrow("Tool use aborted");
|
||||
});
|
||||
|
||||
it("observes a client rejection when the signal aborts during request creation", async () => {
|
||||
const controller = new AbortController();
|
||||
const clientOperation = Promise.reject(new Error("Request cancelled"));
|
||||
const then = vi.spyOn(clientOperation, "then");
|
||||
const mockClient = {
|
||||
sessionUpdate: async () => {},
|
||||
requestPermission: () => {
|
||||
controller.abort();
|
||||
return clientOperation;
|
||||
},
|
||||
} as unknown as AcpClient;
|
||||
const agent = new ClaudeAcpAgent(mockClient, { log: () => {}, error: () => {} });
|
||||
const session = injectSession(agent, "session-1");
|
||||
session.emittedToolCalls.add("tool-1");
|
||||
|
||||
await expect(
|
||||
agent.canUseTool("session-1")("Bash", { command: "ls" }, {
|
||||
signal: controller.signal,
|
||||
suggestions: [],
|
||||
toolUseID: "tool-1",
|
||||
} as any),
|
||||
).rejects.toThrow("Tool use aborted");
|
||||
|
||||
expect(then).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("does not wait for an eager tool-call update that ignores cancellation", async () => {
|
||||
const requestPermission = vi.fn();
|
||||
const mockClient = {
|
||||
@@ -6799,7 +6831,7 @@ describe("subagent permission attribution (issue #851)", () => {
|
||||
sessionUpdate: async (notification: AcpSessionNotification) => {
|
||||
updates.push(notification);
|
||||
},
|
||||
requestPermission: () => new Promise(() => {}),
|
||||
requestPermission: heldRequest,
|
||||
} as unknown as AcpClient,
|
||||
{ log: () => {}, error: () => {} },
|
||||
);
|
||||
@@ -7336,7 +7368,7 @@ describe("subagent permission attribution (issue #851)", () => {
|
||||
updates.push(notification);
|
||||
},
|
||||
// A client that ignores $/cancel_request.
|
||||
createElicitation: () => new Promise(() => {}),
|
||||
createElicitation: heldRequest,
|
||||
} as unknown as AcpClient,
|
||||
{ log: () => {}, error: () => {} },
|
||||
);
|
||||
@@ -8632,7 +8664,7 @@ describe("subagent permission attribution (issue #851)", () => {
|
||||
requestPermission: (params: { sessionId: string }, signal?: AbortSignal) => {
|
||||
log.push(`request @${params.sessionId}`);
|
||||
signal?.addEventListener("abort", () => log.push(`withdrawn @${params.sessionId}`));
|
||||
return new Promise(() => {});
|
||||
return heldRequest(params, signal);
|
||||
},
|
||||
} as unknown as AcpClient,
|
||||
{ log: () => {}, error: () => {} },
|
||||
@@ -26883,7 +26915,7 @@ describe("turn steering (_session/steering)", () => {
|
||||
"uses priority:'now' again once $name is withdrawn, though its client never settles it",
|
||||
async ({ start }) => {
|
||||
// A client that ignores $/cancel_request: its request never settles.
|
||||
const userInputRequest = vi.fn(() => new Promise<never>(() => {}));
|
||||
const userInputRequest = vi.fn(heldRequest<never>);
|
||||
const input = new Pushable<any>();
|
||||
const inputPush = vi.spyOn(input, "push");
|
||||
const agent = new ClaudeAcpAgent(
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"AskUserQuestion","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Asking for your input","toolCallId":"toolu_ask"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"Which database?","type":"text"},"type":"content"}],"rawInput":{"questions":[{"header":"Database","multiSelect":false,"options":[{"description":"Relational","label":"Postgres","preview":"CREATE TABLE t ();"},{"description":"Key-value","label":"Redis"}],"question":"Which database?"}]},"sessionUpdate":"tool_call_update","title":"Which database?","toolCallId":"toolu_ask"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"elicitation/create","payload":{"message":"Which database?","mode":"form","requestedSchema":{"properties":{"question_0":{"oneOf":[{"_meta":{"_claude/askUserQuestionOption":{"preview":"CREATE TABLE t ();"}},"const":"Postgres","description":"Relational","title":"Postgres"},{"const":"Redis","description":"Key-value","title":"Redis"}],"title":"Database","type":"string"},"question_0_custom":{"description":"Type your own answer, or add a note to the option you chose above (optional).","title":"Other","type":"string"}},"type":"object"},"sessionId":"<session>","toolCallId":"toolu_ask"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"User has answered your questions: \"Which database?\"=\"Postgres\".","type":"text"},"type":"content"}],"rawOutput":"User has answered your questions: \"Which database?\"=\"Postgres\".","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_ask"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"terminal_update","terminalId":"toolu_bg"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_bg","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Terminal","toolCallId":"toolu_bg"}}}
|
||||
@@ -15,4 +15,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"exitStatus":{},"sessionUpdate":"terminal_update","terminalId":"toolu_bg"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_bg"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"terminal_update","terminalId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_bash","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Terminal","toolCallId":"toolu_bash"}}}
|
||||
@@ -14,4 +14,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"exitStatus":{"exitCode":1},"sessionUpdate":"terminal_update","terminalId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"tool_call_update","status":"failed","toolCallId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"terminal_update","terminalId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_bash","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Terminal","toolCallId":"toolu_bash"}}}
|
||||
@@ -10,9 +10,9 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"command":"ls -la"},"sessionUpdate":"tool_call_update","title":"ls -la","toolCallId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"command":"ls -la","description":"List files"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"terminalId":"toolu_bash","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{"command":"ls -la","description":"List files"},"title":"ls -la","toolCallId":"toolu_bash"},"type":"tool_call"},"title":"ls -la"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"output":{"data":"YS50cwpiLnRz"},"sessionUpdate":"terminal_update","terminalId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"exitStatus":{"exitCode":0},"sessionUpdate":"terminal_update","terminalId":"toolu_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_bash"}}}
|
||||
@@ -20,4 +20,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"ne.","type":"text"},"messageId":"msg_done","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","sessionUpdate":"compaction_update","status":"in_progress"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","error":"Context too small","sessionUpdate":"compaction_update","status":"failed"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","sessionUpdate":"compaction_update","status":"in_progress"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","content":{"text":"The summary.","type":"text"},"sessionUpdate":"compaction_summary_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","sessionUpdate":"compaction_update","status":"completed"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"usage_update","size":200000,"used":100}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":100}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","sessionUpdate":"compaction_update","status":"in_progress"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","content":{"text":"The summary.","type":"text"},"sessionUpdate":"compaction_summary_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"compactionId":"00000000-0000-4000-8000-000000000001","sessionUpdate":"compaction_update","status":"completed"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"usage_update","size":200000,"used":100}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":100}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"edit","locations":[],"name":"Edit","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Edit","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"path":"<cwd>/src/app.ts"}],"rawInput":{"file_path":"<cwd>/src/app.ts"},"sessionUpdate":"tool_call_update","title":"Edit src/app.ts","toolCallId":"toolu_edit"}}}
|
||||
@@ -10,9 +10,9 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"file_path":"<cwd>/src/app.ts","new_string":"value = 2","old_string":"value = 1"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"changes":[{"fileType":"text","operation":"modify","path":"<cwd>/src/app.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/src/app.ts <cwd>/src/app.ts\n--- <cwd>/src/app.ts\n+++ <cwd>/src/app.ts\n@@ -1 +1 @@\n-const value = 1;\n+const value = 2;\n"},"type":"diff"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"changes":[{"fileType":"text","operation":"modify","path":"<cwd>/src/app.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/src/app.ts <cwd>/src/app.ts\n--- <cwd>/src/app.ts\n+++ <cwd>/src/app.ts\n@@ -1 +1 @@\n-const value = 1;\n+const value = 2;\n"},"type":"diff"}],"kind":"edit","locations":[{"path":"<cwd>/src/app.ts"}],"name":"Edit","rawInput":{"file_path":"<cwd>/src/app.ts","new_string":"value = 2","old_string":"value = 1"},"title":"Edit src/app.ts","toolCallId":"toolu_edit"},"type":"tool_call"},"title":"Edit src/app.ts"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"```\nThe user doesn't want to proceed with this tool use. The tool use was rejected.\n```","type":"text"},"type":"content"}],"rawOutput":"The user doesn't want to proceed with this tool use. The tool use was rejected.","sessionUpdate":"tool_call_update","status":"failed","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"edit","locations":[],"name":"Edit","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Edit","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"path":"<cwd>/src/app.ts"}],"rawInput":{"file_path":"<cwd>/src/app.ts"},"sessionUpdate":"tool_call_update","title":"Edit src/app.ts","toolCallId":"toolu_edit"}}}
|
||||
@@ -10,10 +10,10 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"file_path":"<cwd>/src/app.ts","new_string":"const value = 2;","old_string":"const value = 1;"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"changes":[{"fileType":"text","operation":"modify","path":"<cwd>/src/app.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/src/app.ts <cwd>/src/app.ts\n--- <cwd>/src/app.ts\n+++ <cwd>/src/app.ts\n@@ -1,3 +1,3 @@\n line 1\n-const value = 1;\n+const value = 2;\n line 3\n"},"type":"diff"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"changes":[{"fileType":"text","operation":"modify","path":"<cwd>/src/app.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/src/app.ts <cwd>/src/app.ts\n--- <cwd>/src/app.ts\n+++ <cwd>/src/app.ts\n@@ -1,3 +1,3 @@\n line 1\n-const value = 1;\n+const value = 2;\n line 3\n"},"type":"diff"}],"kind":"edit","locations":[{"path":"<cwd>/src/app.ts"}],"name":"Edit","rawInput":{"file_path":"<cwd>/src/app.ts","new_string":"const value = 2;","old_string":"const value = 1;"},"title":"Edit src/app.ts","toolCallId":"toolu_edit"},"type":"tool_call"},"title":"Edit src/app.ts"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawOutput":"The file <cwd>/src/app.ts has been updated successfully.","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"line":1,"path":"<cwd>/src/app.ts"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"switch_mode","name":"ExitPlanMode","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Approve Plan","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"# Plan\n1. Do it","type":"text"},"type":"content"}],"rawInput":{"plan":"# Plan\n1. Do it"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes, manually approve edits","optionId":"exit-plan-default"},{"kind":"allow_always","name":"Yes, clear context (0% used) and use auto mode","optionId":"exit-plan-clear-auto"},{"kind":"allow_always","name":"Yes, and use auto mode","optionId":"exit-plan-auto"},{"kind":"allow_always","name":"Yes, and bypass permissions","optionId":"exit-plan-bypass"},{"kind":"reject_once","name":"No, keep planning","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"content":{"text":"# Plan\n1. Do it","type":"text"},"type":"content"}],"kind":"switch_mode","name":"ExitPlanMode","rawInput":{"plan":"# Plan\n1. Do it"},"title":"Approve Plan","toolCallId":"toolu_plan"},"type":"tool_call"},"title":"Ready to code?"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawOutput":"User has approved your plan. You can now start coding.\n\n## Approved Plan:\n# Plan\n1. Do it","sessionUpdate":"tool_call_update","status":"completed","title":"Exited Plan Mode","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"plan":{"content":"# Plan\n1. Do it","planId":"plan-mode","type":"markdown"},"sessionUpdate":"plan_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"switch_mode","name":"ExitPlanMode","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Approve Plan","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"# Plan\n1. Do it","type":"text"},"type":"content"}],"rawInput":{"plan":"# Plan\n1. Do it"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes, manually approve edits","optionId":"exit-plan-default"},{"kind":"allow_always","name":"Yes, clear context (0% used) and use auto mode","optionId":"exit-plan-clear-auto"},{"kind":"allow_always","name":"Yes, and use auto mode","optionId":"exit-plan-auto"},{"kind":"allow_always","name":"Yes, and bypass permissions","optionId":"exit-plan-bypass"},{"kind":"reject_once","name":"No, keep planning","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"content":{"text":"# Plan\n1. Do it","type":"text"},"type":"content"}],"kind":"switch_mode","name":"ExitPlanMode","rawInput":{"plan":"# Plan\n1. Do it"},"title":"Approve Plan","toolCallId":"toolu_plan"},"type":"tool_call"},"title":"Ready to code?"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"```\n```\nThe user doesn't want to proceed with this tool use.\n```\n```","type":"text"},"type":"content"}],"rawOutput":"The user doesn't want to proceed with this tool use.","sessionUpdate":"tool_call_update","status":"failed","toolCallId":"toolu_plan"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"/goal Ship the feature","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"search","name":"Grep","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"grep","toolCallId":"toolu_grep"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"pattern":"value"},"sessionUpdate":"tool_call_update","title":"grep \"value\"","toolCallId":"toolu_grep"}}}
|
||||
@@ -16,4 +16,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"pattern":"**/*.ts"},"sessionUpdate":"tool_call_update","title":"Find `**/*.ts`","toolCallId":"toolu_glob"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"src/app.ts\nsrc/b.ts","type":"text"},"type":"content"}],"rawOutput":"src/app.ts\nsrc/b.ts","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_glob"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"mcp__docs__search","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"mcp__docs__search","toolCallId":"toolu_mcp"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"q":"acp"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_mcp"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"_meta":{"claudeCode":{"mcpServer":{"name":"docs","source":"project"}}},"content":[],"kind":"other","name":"mcp__docs__search","rawInput":{"q":"acp"},"title":"mcp__docs__search","toolCallId":"toolu_mcp"},"type":"tool_call"},"title":"mcp__docs__search"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"Found 2 documents.","type":"text"},"type":"content"}],"rawOutput":[{"text":"Found 2 documents.","type":"text"}],"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_mcp"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"claudeCode":{"toolResponse":{"mode":"select"}}},"kind":"read","locations":[{"path":"/memory/a.md"},{"path":"/memory/b.md"}],"name":"memory_recall","sessionUpdate":"tool_call_update","status":"completed","title":"Recalled 2 memories","toolCallId":"00000000-0000-4000-8000-000000000001"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"claudeCode":{"toolResponse":{"mode":"synthesize"}}},"content":[{"content":{"text":"The user prefers tabs.","type":"text"},"type":"content"}],"kind":"read","name":"memory_recall","sessionUpdate":"tool_call_update","status":"completed","title":"Recalled synthesized memory","toolCallId":"00000000-0000-4000-8000-000000000002"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"SandboxNetworkAccess","rawInput":{"host":"example.com"},"sessionUpdate":"tool_call_update","status":"pending","title":"SandboxNetworkAccess","toolCallId":"toolu_net"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"description":"Reason: Sandbox blocks network","options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"content":{"text":"```json\n{\n \"host\": \"example.com\"\n}\n```","type":"text"},"type":"content"}],"kind":"other","name":"SandboxNetworkAccess","rawInput":{"host":"example.com"},"title":"example.com","toolCallId":"toolu_net"},"type":"tool_call"},"title":"example.com"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_net"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"NotebookEdit","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"NotebookEdit","toolCallId":"toolu_nb"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"notebook_path":"<cwd>/n.ipynb"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_nb"}}}
|
||||
@@ -10,9 +10,9 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"cell_id":"cell-1","new_source":"print('hi')","notebook_path":"<cwd>/n.ipynb"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_nb"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"cell_id":"cell-1","edit_mode":"replace","new_source":"print('hi')","notebook_path":"<cwd>/n.ipynb"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_nb"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[],"kind":"other","name":"NotebookEdit","rawInput":{"cell_id":"cell-1","edit_mode":"replace","new_source":"print('hi')","notebook_path":"<cwd>/n.ipynb"},"title":"NotebookEdit","toolCallId":"toolu_nb"},"type":"tool_call"},"title":"NotebookEdit"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"Updated cell cell-1 with print('hi')","type":"text"},"type":"content"}],"rawOutput":"Updated cell cell-1 with print('hi')","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_nb"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"terminal_update","terminalId":"toolu_denied"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_denied","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Terminal","toolCallId":"toolu_denied"}}}
|
||||
@@ -14,4 +14,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"exitStatus":{},"sessionUpdate":"terminal_update","terminalId":"toolu_denied"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_denied","type":"terminal"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_denied"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"Work","type":"text"},"messageId":"msg_rate","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"ing.","type":"text"},"messageId":"msg_rate","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6","_claude/rateLimit":{"resetsAt":1700000000,"status":"allowed_warning","utilization":0.9}},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6","_claude/origin":{"kind":"human"}},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"read","locations":[],"name":"Read","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Read File","toolCallId":"toolu_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"line":1,"path":"<cwd>/a.ts"}],"rawInput":{"file_path":"<cwd>/a.ts"},"sessionUpdate":"tool_call_update","title":"Read a.ts","toolCallId":"toolu_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"```\n1\tconst a = 1;\n```","type":"text"},"type":"content"}],"rawOutput":"1\tconst a = 1;\n<system-reminder>x</system-reminder>","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -18,5 +18,5 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"Fixed.","type":"text"},"messageId":"msg_r2","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"description":"The history of 1 subagent of this session could not be restored.","sessionUpdate":"notice","severity":"info","title":"Some subagent history is not available"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"session_info_update","title":"Fix the app","updatedAt":"2026-01-01T00:00:00.000Z"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"idle"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"idle"}}}
|
||||
{"kind":"response","method":"session/resume","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}]}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"Skill","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Load skill","toolCallId":"toolu_skill"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"skill":"commits"},"sessionUpdate":"tool_call_update","title":"Load skill: commits","toolCallId":"toolu_skill"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawOutput":"Launching skill: commits","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_skill"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"a2","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Background review"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"a2","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Background review"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Review the diff","type":"text"}],"messageId":"toolu_agent","recipientMessageId":"toolu_agent","recipientSessionId":"a2","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"content":[{"text":"Review the diff","type":"text"}],"messageId":"toolu_agent","recipientSessionId":"a2","senderMessageId":"toolu_agent","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_agent"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_agent"}},"content":{"text":"Reviewi","type":"text"},"messageId":"msg_async_sub","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_agent"}},"content":{"text":"ng now.","type":"text"},"messageId":"msg_async_sub","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"a2","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"a2","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"a2","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"agent_late","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Check the logs"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"agent_late","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Check the logs"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Check logs","type":"text"}],"messageId":"toolu_late","recipientMessageId":"toolu_late","recipientSessionId":"agent_late","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"content":[{"text":"Check logs","type":"text"}],"messageId":"toolu_late","recipientSessionId":"agent_late","senderMessageId":"toolu_late","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_late"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_late"}},"content":[],"kind":"read","locations":[],"name":"Read","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Read File","toolCallId":"toolu_late_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"locations":[{"line":1,"path":"/var/log/app.log"}],"rawInput":{"file_path":"/var/log/app.log"},"sessionUpdate":"tool_call_update","title":"Read /var/log/app.log","toolCallId":"toolu_late_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"The logs are clean.","type":"text"}],"messageId":"toolu_late:reply","recipientSessionId":"<session>","senderSessionId":"agent_late","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_late","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_late","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_late","toolResponse":{"elapsedTimeSeconds":4}}},"sessionUpdate":"tool_call_update","status":"in_progress","toolCallId":"toolu_late_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_late","update":{"content":[{"content":{"text":"```\n1\tok\n```","type":"text"},"type":"content"}],"rawOutput":"1\tok","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_late_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Fix the build"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"general-purpose","sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Fix the build"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Make the build pass","type":"text"}],"messageId":"toolu_native","recipientMessageId":"toolu_native","recipientSessionId":"agent_n","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"content":[{"text":"Make the build pass","type":"text"}],"messageId":"toolu_native","recipientSessionId":"agent_n","senderMessageId":"toolu_native","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_native"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
@@ -21,17 +21,17 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"command":"make","sessionUpdate":"terminal_update","terminalId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"rawInput":{"command":"make"},"sessionUpdate":"tool_call_update","title":"make","toolCallId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"rawInput":{"command":"make","description":"Build"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"background":[],"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"agent_n","subject":{"toolCall":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_native"}},"content":[{"terminalId":"toolu_native_bash","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{"command":"make","description":"Build"},"title":"make","toolCallId":"toolu_native_bash"},"type":"tool_call"},"title":"make"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"output":{"data":"bWFrZTogKioqIEVycm9yIDI="},"sessionUpdate":"terminal_update","terminalId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"exitStatus":{},"sessionUpdate":"terminal_update","terminalId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"sessionUpdate":"tool_call_update","status":"failed","toolCallId":"toolu_native_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"error"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"error"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_n","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"error"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_n","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"error"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Plan","sessionId":"agent_outer","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Plan the work"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Plan","sessionId":"agent_outer","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Plan the work"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Plan it","type":"text"}],"messageId":"toolu_outer","recipientMessageId":"toolu_outer","recipientSessionId":"agent_outer","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"content":[{"text":"Plan it","type":"text"}],"messageId":"toolu_outer","recipientSessionId":"agent_outer","senderMessageId":"toolu_outer","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_outer"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_inner","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Read the spec"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_inner","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Read the spec"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"content":[{"text":"Read spec.md","type":"text"}],"messageId":"toolu_inner","recipientMessageId":"toolu_inner","recipientSessionId":"agent_inner","senderSessionId":"agent_outer","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"content":[{"text":"Read spec.md","type":"text"}],"messageId":"toolu_inner","recipientSessionId":"agent_inner","senderMessageId":"toolu_inner","senderSessionId":"agent_outer","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_inner"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
@@ -19,12 +19,12 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"locations":[{"line":1,"path":"/spec.md"}],"rawInput":{"file_path":"/spec.md"},"sessionUpdate":"tool_call_update","title":"Read /spec.md","toolCallId":"toolu_grandchild_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"content":[{"content":{"text":"```\n1\tspec\n```","type":"text"},"type":"content"}],"rawOutput":"1\tspec","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_grandchild_read"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"content":[{"text":"The spec says X.","type":"text"}],"messageId":"toolu_inner:reply","recipientSessionId":"agent_outer","senderSessionId":"agent_inner","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"sessionId":"agent_inner","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"sessionId":"agent_inner","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_inner","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_outer"}},"content":{"text":"Plan:","type":"text"},"messageId":"msg_outer_text","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_outer"}},"content":{"text":" do X.","type":"text"},"messageId":"msg_outer_text","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Plan: do X.","type":"text"}],"messageId":"toolu_outer:reply","recipientSessionId":"<session>","senderSessionId":"agent_outer","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_outer","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_outer","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_outer","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Explore code"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Explore code"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Find the parser","type":"text"}],"messageId":"toolu_task","recipientMessageId":"toolu_task","recipientSessionId":"agent_1","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"content":[{"text":"Find the parser","type":"text"}],"messageId":"toolu_task","recipientSessionId":"agent_1","senderMessageId":"toolu_task","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_task"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
@@ -20,13 +20,13 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"command":"rg parser","sessionUpdate":"terminal_update","terminalId":"toolu_sub_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"rawInput":{"command":"rg parser"},"sessionUpdate":"tool_call_update","title":"rg parser","toolCallId":"toolu_sub_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"rawInput":{"command":"rg parser","description":"Search"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_sub_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"agent_1","subject":{"toolCall":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_task"}},"content":[{"terminalId":"toolu_sub_bash","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{"command":"rg parser","description":"Search"},"title":"rg parser","toolCallId":"toolu_sub_bash"},"type":"tool_call"},"title":"rg parser"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"output":{"data":"eC50cw=="},"sessionUpdate":"terminal_update","terminalId":"toolu_sub_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"exitStatus":{"exitCode":0},"sessionUpdate":"terminal_update","terminalId":"toolu_sub_bash"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_sub_bash"}}}
|
||||
@@ -34,19 +34,19 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"locations":[{"path":"<cwd>/x.ts"}],"rawInput":{"file_path":"<cwd>/x.ts"},"sessionUpdate":"tool_call_update","title":"Edit x.ts","toolCallId":"toolu_sub_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"rawInput":{"file_path":"<cwd>/x.ts","old_string":"a"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_sub_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"rawInput":{"file_path":"<cwd>/x.ts","new_string":"b","old_string":"a"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_sub_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"requires_action"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"agent_1","subject":{"toolCall":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_task"}},"content":[],"kind":"edit","locations":[{"path":"<cwd>/x.ts"}],"name":"Edit","rawInput":{"file_path":"<cwd>/x.ts","new_string":"b","old_string":"a"},"title":"Edit x.ts","toolCallId":"toolu_sub_edit"},"type":"tool_call"},"title":"Edit x.ts"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"rawOutput":"The file has been updated.","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_sub_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"content":[{"changes":[{"fileType":"text","operation":"modify","path":"<cwd>/x.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/x.ts <cwd>/x.ts\n--- <cwd>/x.ts\n+++ <cwd>/x.ts\n@@ -1 +1 @@\n-a\n+b\n"},"type":"diff"}],"locations":[{"line":1,"path":"<cwd>/x.ts"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_sub_edit"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_task"}},"content":{"text":"Foun","type":"text"},"messageId":"msg_sub_2","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_task"}},"content":{"text":"d it.","type":"text"},"messageId":"msg_sub_2","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"The parser is in x.ts.","type":"text"}],"messageId":"toolu_task:reply","recipientSessionId":"<session>","senderSessionId":"agent_1","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_1","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_1","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_t","sessionUpdate":"subagent_update","state":{"state":"running"},"title":"Summarize"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"capabilities":{"cancel":{}},"description":"Explore","sessionId":"agent_t","sessionUpdate":"subagent_update","state":{"background":[],"state":"running"},"title":"Summarize"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Summarize the repo","type":"text"}],"messageId":"toolu_transcript","recipientMessageId":"toolu_transcript","recipientSessionId":"agent_t","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"content":[{"text":"Summarize the repo","type":"text"}],"messageId":"toolu_transcript","recipientSessionId":"agent_t","senderMessageId":"toolu_transcript","senderSessionId":"<session>","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"_meta":{"claudeCode":{"parentToolUseId":"toolu_transcript"}},"configOptions":[{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","name":"Model","options":[{"name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionUpdate":"config_option_update"}}}
|
||||
@@ -18,7 +18,7 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"rawInput":{"pattern":"*"},"sessionUpdate":"tool_call_update","title":"Find `*`","toolCallId":"toolu_transcript_glob"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"content":[{"content":{"text":"a\nb","type":"text"},"type":"content"}],"rawOutput":"a\nb","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_transcript_glob"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"Two packages.","type":"text"}],"messageId":"toolu_transcript:reply","recipientSessionId":"<session>","senderSessionId":"agent_t","sessionUpdate":"session_message"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_t","sessionUpdate":"subagent_update","state":{"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionId":"agent_t","sessionUpdate":"subagent_update","state":{"background":[],"state":"idle","stopReason":"end_turn"}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"agent_t","update":{"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"plan":{"entries":[{"content":"Write tests","priority":"medium","status":"pending"}],"planId":"plan","type":"items"},"sessionUpdate":"plan_update"}}}
|
||||
@@ -13,13 +13,13 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"plan":{"entries":[{"content":"Write tests","priority":"medium","status":"completed"}],"planId":"plan","type":"items"},"sessionUpdate":"plan_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"plan":{"entries":[{"content":"Write tests","priority":"medium","status":"completed"}],"planId":"plan","type":"items"},"sessionUpdate":"plan_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 2","type":"text"}],"messageId":"<id-2>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-2>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"All ","type":"text"},"messageId":"msg_follow","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"done.","type":"text"},"messageId":"msg_follow","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"other","name":"TaskOutput","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"TaskOutput","toolCallId":"toolu_out"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"task_id":"bash_1"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_out"}}}
|
||||
@@ -14,4 +14,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"task_id":"bash_1"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_stop"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"Successfully stopped task: bash_1","type":"text"},"type":"content"}],"rawOutput":"Successfully stopped task: bash_1","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_stop"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"Let me thin","type":"text"},"messageId":"msg_text","sessionUpdate":"agent_thought_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"k about it.","type":"text"},"messageId":"msg_text","sessionUpdate":"agent_thought_chunk"}}}
|
||||
@@ -10,4 +10,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":{"text":"he answer.","type":"text"},"messageId":"msg_text","sessionUpdate":"agent_message_chunk"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"plan":{"entries":[{"content":"Writing tests","priority":"medium","status":"in_progress"},{"content":"Ship","priority":"medium","status":"pending"}],"planId":"plan","type":"items"},"sessionUpdate":"plan_update"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"terminal_update","terminalId":"toolu_slow"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"terminalId":"toolu_slow","type":"terminal"}],"kind":"execute","name":"Bash","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Terminal","toolCallId":"toolu_slow"}}}
|
||||
@@ -16,4 +16,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"exitStatus":{"exitCode":0},"sessionUpdate":"terminal_update","terminalId":"toolu_slow"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_slow"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"fetch","name":"WebFetch","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Fetch","toolCallId":"toolu_fetch"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"url":"https://example.com"},"sessionUpdate":"tool_call_update","title":"Fetch https://example.com","toolCallId":"toolu_fetch"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"Summarize the page","type":"text"},"type":"content"}],"rawInput":{"prompt":"Summarize the page","url":"https://example.com"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_fetch"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"allow_always","name":"Yes, and don't ask again for example.com","optionId":"allow-with-updates"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"content":{"text":"Summarize the page","type":"text"},"type":"content"}],"kind":"fetch","name":"WebFetch","rawInput":{"prompt":"Summarize the page","url":"https://example.com"},"title":"Fetch https://example.com","toolCallId":"toolu_fetch"},"type":"tool_call"},"title":"Fetch https://example.com"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"The page is an example.","type":"text"},"type":"content"}],"rawOutput":"The page is an example.","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_fetch"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"fetch","name":"WebSearch","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Web search","toolCallId":"toolu_search"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"query":"acp protocol"},"sessionUpdate":"tool_call_update","title":"Search \"acp protocol\"","toolCallId":"toolu_search"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"content":{"text":"ACP (https://agentclientprotocol.com)\nA summary.","type":"text"},"type":"content"}],"rawOutput":"Web search results for query: \"acp protocol\"\n\nLinks: [...]","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_search"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"edit","locations":[],"name":"Write","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Preparing file…","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"path":"<cwd>/old.ts"}],"rawInput":{"file_path":"<cwd>/old.ts"},"sessionUpdate":"tool_call_update","title":"Write old.ts","toolCallId":"toolu_write"}}}
|
||||
@@ -12,4 +12,4 @@
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawOutput":"The file <cwd>/old.ts has been updated successfully.","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"line":1,"path":"<cwd>/old.ts"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp","type":"command"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
||||
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[],"kind":"edit","locations":[],"name":"Write","rawInput":{},"sessionUpdate":"tool_call_update","status":"pending","title":"Preparing file…","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"locations":[{"path":"<cwd>/new.ts"}],"rawInput":{"file_path":"<cwd>/new.ts"},"sessionUpdate":"tool_call_update","title":"Write new.ts","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"sessionUpdate":"usage_update","size":200000,"used":3}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawInput":{"content":"export const x = 1;\n","file_path":"<cwd>/new.ts"},"sessionUpdate":"tool_call_update","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"changes":[{"fileType":"text","operation":"add","path":"<cwd>/new.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/new.ts <cwd>/new.ts\nnew file mode 100644\n--- /dev/null\n+++ <cwd>/new.ts\n@@ -0,0 +1 @@\n+export const x = 1;\n"},"type":"diff"}],"sessionUpdate":"tool_call_update","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"requires_action"}}}
|
||||
{"kind":"request","method":"session/request_permission","payload":{"options":[{"kind":"allow_once","name":"Yes","optionId":"allow-once"},{"kind":"reject_once","name":"No","optionId":"reject"}],"sessionId":"<session>","subject":{"toolCall":{"content":[{"changes":[{"fileType":"text","operation":"add","path":"<cwd>/new.ts"}],"patch":{"format":"git_patch","text":"diff --git <cwd>/new.ts <cwd>/new.ts\nnew file mode 100644\n--- /dev/null\n+++ <cwd>/new.ts\n@@ -0,0 +1 @@\n+export const x = 1;\n"},"type":"diff"}],"kind":"edit","locations":[{"path":"<cwd>/new.ts"}],"name":"Write","rawInput":{"content":"export const x = 1;\n","file_path":"<cwd>/new.ts"},"title":"Write new.ts","toolCallId":"toolu_write"},"type":"tool_call"},"title":"Write new.ts"}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"background":[],"sessionUpdate":"state_update","state":"running"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"rawOutput":"File created successfully at: <cwd>/new.ts","sessionUpdate":"tool_call_update","status":"completed","toolCallId":"toolu_write"}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"_claude/model":"claude-sonnet-4-6"},"cost":{"amount":0,"currency":"USD"},"sessionUpdate":"usage_update","size":200000,"used":2}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"background":[],"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
v1SetSessionConfigOptionRequest,
|
||||
v2ConfigOptions,
|
||||
} from "../v2/session.js";
|
||||
import { startupFailure } from "./helpers.js";
|
||||
import packageJson from "../../package.json" with { type: "json" };
|
||||
|
||||
const execFileSpy = vi.hoisted(() => vi.fn());
|
||||
@@ -60,6 +61,16 @@ const sdk = vi.hoisted(() => ({
|
||||
stopTask: async (_taskId: string): Promise<void> => {},
|
||||
/** The query is closed, as `session/close` closes it. */
|
||||
close: (): void => {},
|
||||
initializationResult: async (): Promise<Record<string, unknown>> => ({
|
||||
models: [
|
||||
{
|
||||
value: "claude-sonnet-4-6",
|
||||
displayName: "Claude Sonnet",
|
||||
description: "Fast",
|
||||
supportsAutoMode: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
mcpServerStatus: async (): Promise<Array<{ name: string; status: string }>> => [],
|
||||
supportedCommands: async (): Promise<
|
||||
Array<{ name: string; description: string; argumentHint: string }>
|
||||
@@ -86,16 +97,7 @@ vi.mock("@anthropic-ai/claude-agent-sdk", async () => {
|
||||
const messages = sdk.run(prompt, options);
|
||||
const controls = makeMockQuery({
|
||||
[Symbol.asyncIterator]: () => messages,
|
||||
initializationResult: async () => ({
|
||||
models: [
|
||||
{
|
||||
value: "claude-sonnet-4-6",
|
||||
displayName: "Claude Sonnet",
|
||||
description: "Fast",
|
||||
supportsAutoMode: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
initializationResult: () => sdk.initializationResult(),
|
||||
supportedCommands: () => sdk.supportedCommands(),
|
||||
mcpServerStatus: () => sdk.mcpServerStatus(),
|
||||
mcpAuthenticate: (serverName: string) => sdk.mcpAuthenticate(serverName),
|
||||
@@ -192,6 +194,19 @@ function v2Client({
|
||||
const elicitations: v2.CreateElicitationRequest[] = [];
|
||||
const completedElicitations: v2.CompleteElicitationNotification[] = [];
|
||||
const permissionRequests: v2.RequestPermissionRequest[] = [];
|
||||
/** The methods of the requests that the agent cancelled with `$/cancel_request`. */
|
||||
const cancelledRequests: string[] = [];
|
||||
// The request's signal also aborts when the connection closes, with another reason.
|
||||
const recordCancel = (method: string, signal: AbortSignal) =>
|
||||
signal.addEventListener(
|
||||
"abort",
|
||||
() => {
|
||||
if ((signal.reason as { code?: unknown } | undefined)?.code === -32800) {
|
||||
cancelledRequests.push(method);
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
let notifyAuthUpdate = () => {};
|
||||
const app = v2
|
||||
.client({ name: V2_CLIENT_INFO.name })
|
||||
@@ -206,15 +221,17 @@ function v2Client({
|
||||
.onNotification(v2.methods.client.session.update, ({ params }) => {
|
||||
sessionUpdates.push(params);
|
||||
})
|
||||
.onRequest(v2.methods.client.elicitation.create, ({ params }) => {
|
||||
.onRequest(v2.methods.client.elicitation.create, ({ params, signal }) => {
|
||||
elicitations.push(params);
|
||||
recordCancel(v2.methods.client.elicitation.create, signal);
|
||||
return answerElicitation(params);
|
||||
})
|
||||
.onNotification(v2.methods.client.elicitation.complete, ({ params }) => {
|
||||
completedElicitations.push(params);
|
||||
})
|
||||
.onRequest(v2.methods.client.session.requestPermission, ({ params }) => {
|
||||
.onRequest(v2.methods.client.session.requestPermission, ({ params, signal }) => {
|
||||
permissionRequests.push(params);
|
||||
recordCancel(v2.methods.client.session.requestPermission, signal);
|
||||
return answerPermission(params);
|
||||
});
|
||||
/** Resolves once the client has received `count` auth status updates. */
|
||||
@@ -243,6 +260,7 @@ function v2Client({
|
||||
elicitations,
|
||||
completedElicitations,
|
||||
permissionRequests,
|
||||
cancelledRequests,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -481,6 +499,22 @@ describe("ACP v2 sessions", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("rejects session/new with the reason Claude Code gave for not starting", async () => {
|
||||
sdk.initializationResult = async () => {
|
||||
throw startupFailure("proxy_invalid", 'Invalid proxy URL in HTTPS_PROXY: "not a url".');
|
||||
};
|
||||
const { app, authUpdate } = v2Client();
|
||||
await app.connectWith(connectRouter(), async (agent) => {
|
||||
await initializeV2(agent);
|
||||
await expect(agent.request(v2.methods.agent.session.new, { cwd })).rejects.toMatchObject({
|
||||
code: -32603,
|
||||
message: 'Internal error: Invalid proxy URL in HTTPS_PROXY: "not a url".',
|
||||
data: { startupFailureReason: "proxy_invalid" },
|
||||
});
|
||||
await authUpdate(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects an MCP transport that v1 cannot express", async () => {
|
||||
const { app, authUpdate } = v2Client();
|
||||
await app.connectWith(connectRouter(), async (agent) => {
|
||||
@@ -1394,9 +1428,9 @@ describe("ACP v2 prompts", () => {
|
||||
messageId: "msg_child",
|
||||
content: text("Child report.")[0],
|
||||
}),
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn" },
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn", background: [] },
|
||||
{ sessionUpdate: "response" },
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn" },
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn", background: [] },
|
||||
]);
|
||||
// The current state on the parent grants nothing: the child cannot run again here.
|
||||
expect(
|
||||
@@ -1588,7 +1622,7 @@ describe("ACP v2 prompts", () => {
|
||||
summary: text("1. Primary Request and Intent:\n Count upward."),
|
||||
},
|
||||
{ sessionUpdate: "agent_message", messageId: "msg_after", content: [] },
|
||||
{ sessionUpdate: "state_update", state: "idle" },
|
||||
{ sessionUpdate: "state_update", state: "idle", background: [] },
|
||||
]);
|
||||
await client.authUpdate(1);
|
||||
});
|
||||
@@ -1642,7 +1676,7 @@ describe("ACP v2 prompts", () => {
|
||||
content: text("Hello!")[0],
|
||||
},
|
||||
// The current foreground state, after the replay and before the response.
|
||||
{ sessionUpdate: "state_update", state: "idle" },
|
||||
{ sessionUpdate: "state_update", state: "idle", background: [] },
|
||||
]);
|
||||
|
||||
// Live chunks after the replay get no clear.
|
||||
@@ -1686,7 +1720,7 @@ describe("ACP v2 prompts", () => {
|
||||
await agent.request(v2.methods.agent.session.resume, { sessionId, cwd });
|
||||
expect(client.sessionUpdates.slice(before).map(({ update }) => update)).toEqual([
|
||||
info,
|
||||
{ sessionUpdate: "state_update", state: "idle" },
|
||||
{ sessionUpdate: "state_update", state: "idle", background: [] },
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1727,7 +1761,7 @@ describe("ACP v2 prompts", () => {
|
||||
const before = client.sessionUpdates.length;
|
||||
await agent.request(v2.methods.agent.session.resume, { sessionId, cwd });
|
||||
expect(client.sessionUpdates.slice(before).map(({ update }) => update)).toEqual([
|
||||
{ sessionUpdate: "state_update", state: "running" },
|
||||
{ sessionUpdate: "state_update", state: "running", background: [] },
|
||||
]);
|
||||
|
||||
answer.resolve();
|
||||
@@ -2506,6 +2540,7 @@ describe("ACP v2 prompts", () => {
|
||||
state: "idle",
|
||||
stopReason: "error",
|
||||
error: expect.objectContaining({ code: v1Error.code, message: v1Error.message }),
|
||||
background: [],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4199,6 +4234,264 @@ describe("ACP v2 requests that subagents make", () => {
|
||||
state: "idle",
|
||||
stopReason: "error",
|
||||
error: { code: -32603, message: "The model is overloaded" },
|
||||
background: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("background work", () => {
|
||||
/** Claude Code's live background task set. */
|
||||
const level = (options: Options, tasks: Array<Record<string, unknown>>) => ({
|
||||
type: "system",
|
||||
subtype: "background_tasks_changed",
|
||||
tasks: tasks.map((fields) => ({ description: "Explore the project", ...fields })),
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
});
|
||||
const agent1 = { task_id: "agent-1", task_type: "local_agent", subagent_type: "Explore" };
|
||||
/** The root starts the subagent `agent-1` in the background. */
|
||||
const agentUse = (options: Options) => ({
|
||||
type: "assistant",
|
||||
message: {
|
||||
id: "msg_agent",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-sonnet-4-6",
|
||||
content: [
|
||||
{
|
||||
type: "tool_use",
|
||||
id: "toolu_agent-1",
|
||||
name: "Agent",
|
||||
input: {
|
||||
description: "Explore the project",
|
||||
prompt: "Look around",
|
||||
run_in_background: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
stop_reason: "tool_use",
|
||||
stop_sequence: null,
|
||||
usage: { input_tokens: 3, output_tokens: 2 },
|
||||
},
|
||||
parent_tool_use_id: null,
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
});
|
||||
const taskEnd = (options: Options, taskId: string, toolUseId: string) => ({
|
||||
type: "system",
|
||||
subtype: "task_notification",
|
||||
task_id: taskId,
|
||||
tool_use_id: toolUseId,
|
||||
status: "completed",
|
||||
output_file: `/tmp/tasks/${taskId}.output`,
|
||||
summary: "Done",
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
});
|
||||
|
||||
/** The states of each session with their lists, and the subagent's mirrored states. */
|
||||
const trace = (client: ReturnType<typeof v2Client>, root: string) =>
|
||||
client.sessionUpdates.flatMap(({ sessionId, update }) => {
|
||||
if (update.sessionUpdate === "subagent_update") {
|
||||
return [`subagent ${(update.state as { state?: string } | undefined)?.state ?? ""}`];
|
||||
}
|
||||
if (update.sessionUpdate === "terminal_update" && update.exitStatus) {
|
||||
return [`${sessionId} exit`];
|
||||
}
|
||||
if (update.sessionUpdate !== "state_update") return [];
|
||||
const { background } = update as { background?: v2.BackgroundWork[] };
|
||||
const items = background?.map((item) =>
|
||||
"sessionId" in item
|
||||
? String(item.sessionId)
|
||||
: "terminalId" in item
|
||||
? String(item.terminalId)
|
||||
: "",
|
||||
);
|
||||
return [`${sessionId === root ? "root" : sessionId} ${update.state} [${items ?? "none"}]`];
|
||||
});
|
||||
|
||||
/** Prompts once, and runs `during` once the trace holds `until`. */
|
||||
async function promptUntil(
|
||||
until: string,
|
||||
during: (
|
||||
agent: v2.ClientContext,
|
||||
root: string,
|
||||
client: ReturnType<typeof v2Client>,
|
||||
) => Promise<unknown> = async () => {},
|
||||
) {
|
||||
const client = v2Client();
|
||||
let root = "";
|
||||
await client.app.connectWith(connectRouter(), async (agent) => {
|
||||
await initializeV2(agent);
|
||||
({ sessionId: root } = await agent.request(v2.methods.agent.session.new, { cwd }));
|
||||
await agent.request(v2.methods.agent.session.prompt, {
|
||||
sessionId: root,
|
||||
prompt: text("hi"),
|
||||
});
|
||||
await vi.waitFor(() => expect(trace(client, root)).toContain(until));
|
||||
await during(agent, root, client);
|
||||
});
|
||||
return { client, root };
|
||||
}
|
||||
|
||||
it("lists a background subagent's session in the root's list until it reports idle", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield agentUse(options);
|
||||
yield level(options, [agent1]);
|
||||
yield taskStarted(options, "agent-1", { prompt: "Look around", is_backgrounded: true });
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
yield taskEnd(options, "agent-1", "toolu_agent-1");
|
||||
// The level that drops the subagent can come later: the SDK leaves its
|
||||
// order against the task's end open. The child's idle drops it already.
|
||||
});
|
||||
const { client, root } = await promptUntil("root idle []");
|
||||
|
||||
// The child's own idle comes before the list that drops it. The child
|
||||
// reports its own list, which is empty.
|
||||
expect(trace(client, root)).toEqual([
|
||||
"root running []",
|
||||
"subagent running",
|
||||
"agent-1 running []",
|
||||
"root running [agent-1]",
|
||||
"root idle [agent-1]",
|
||||
"subagent idle",
|
||||
"agent-1 idle []",
|
||||
"root idle []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps an idle subagent listed while its own command runs in the background", async () => {
|
||||
const childMessage = (options: Options, message: Record<string, unknown>) => ({
|
||||
...message,
|
||||
parent_tool_use_id: "toolu_agent-1",
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
});
|
||||
const bash = { task_id: "bg1", task_type: "local_bash", parent_task_id: "agent-1" };
|
||||
scriptTurns(async function* (options) {
|
||||
yield agentUse(options);
|
||||
yield level(options, [agent1]);
|
||||
yield taskStarted(options, "agent-1", { prompt: "Look around", is_backgrounded: true });
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
// The subagent runs a command in the background, and finishes.
|
||||
yield childMessage(options, {
|
||||
type: "assistant",
|
||||
message: {
|
||||
id: "msg_child_bash",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-sonnet-4-6",
|
||||
content: [
|
||||
{
|
||||
type: "tool_use",
|
||||
id: "toolu_bg",
|
||||
name: "Bash",
|
||||
input: { command: "make test", run_in_background: true },
|
||||
},
|
||||
],
|
||||
stop_reason: "tool_use",
|
||||
stop_sequence: null,
|
||||
usage: { input_tokens: 1, output_tokens: 1 },
|
||||
},
|
||||
});
|
||||
yield level(options, [agent1, bash]);
|
||||
yield {
|
||||
type: "system",
|
||||
subtype: "task_started",
|
||||
task_id: "bg1",
|
||||
task_type: "local_bash",
|
||||
description: "make test",
|
||||
tool_use_id: "toolu_bg",
|
||||
parent_task_id: "agent-1",
|
||||
is_backgrounded: true,
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
};
|
||||
yield childMessage(options, {
|
||||
type: "user",
|
||||
message: {
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "tool_result",
|
||||
tool_use_id: "toolu_bg",
|
||||
content: "Command running in background with ID: bg1.",
|
||||
},
|
||||
],
|
||||
},
|
||||
tool_use_result: {
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
interrupted: false,
|
||||
isImage: false,
|
||||
backgroundTaskId: "bg1",
|
||||
},
|
||||
});
|
||||
yield taskEnd(options, "agent-1", "toolu_agent-1");
|
||||
yield level(options, [bash]);
|
||||
// The command ends later.
|
||||
yield taskEnd(options, "bg1", "toolu_bg");
|
||||
yield level(options, []);
|
||||
});
|
||||
const { client, root } = await promptUntil("root idle []");
|
||||
|
||||
expect(trace(client, root).slice(5)).toEqual([
|
||||
"subagent running",
|
||||
"agent-1 running [toolu_bg]",
|
||||
"subagent idle",
|
||||
"agent-1 idle [toolu_bg]",
|
||||
"agent-1 exit",
|
||||
"subagent idle",
|
||||
"agent-1 idle []",
|
||||
"root idle []",
|
||||
]);
|
||||
expect(trace(client, root).slice(0, 5)).toEqual([
|
||||
"root running []",
|
||||
"subagent running",
|
||||
"agent-1 running []",
|
||||
"root running [agent-1]",
|
||||
"root idle [agent-1]",
|
||||
]);
|
||||
});
|
||||
|
||||
it("sends the current state of each listed subagent before the state snapshot of session/resume", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield agentUse(options);
|
||||
yield level(options, [agent1]);
|
||||
yield taskStarted(options, "agent-1", { prompt: "Look around", is_backgrounded: true });
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
});
|
||||
let resumed: v2.UpdateSessionNotification[] = [];
|
||||
await promptUntil("root idle [agent-1]", async (agent, root, client) => {
|
||||
const before = client.sessionUpdates.length;
|
||||
await agent.request(v2.methods.agent.session.resume, { sessionId: root, cwd });
|
||||
resumed = client.sessionUpdates.slice(before);
|
||||
});
|
||||
|
||||
expect(resumed.map(({ update }) => update)).toEqual([
|
||||
{
|
||||
sessionUpdate: "subagent_update",
|
||||
sessionId: "agent-1",
|
||||
title: "Explore the project",
|
||||
description: "Explore",
|
||||
capabilities: { cancel: {} },
|
||||
state: { state: "running", background: [] },
|
||||
},
|
||||
// The child's own stream gets its state too, as for every subagent_update.
|
||||
{ sessionUpdate: "state_update", state: "running", background: [] },
|
||||
{
|
||||
sessionUpdate: "state_update",
|
||||
state: "idle",
|
||||
background: [{ type: "subagent", sessionId: "agent-1" }],
|
||||
},
|
||||
]);
|
||||
expect(resumed.map(({ sessionId }) => sessionId)).toEqual([
|
||||
expect.not.stringMatching(/^agent-1$/),
|
||||
"agent-1",
|
||||
expect.not.stringMatching(/^agent-1$/),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4294,7 +4587,7 @@ describe("ACP v2 requests that subagents make", () => {
|
||||
expect(subagentUpdates.at(-1)).toEqual({
|
||||
sessionUpdate: "subagent_update",
|
||||
sessionId: "agent-1",
|
||||
state: { state: "idle", stopReason: "cancelled" },
|
||||
state: { state: "idle", stopReason: "cancelled", background: [] },
|
||||
});
|
||||
expect(
|
||||
client.sessionUpdates
|
||||
@@ -4304,8 +4597,8 @@ describe("ACP v2 requests that subagents make", () => {
|
||||
)
|
||||
.map(({ update }) => update),
|
||||
).toEqual([
|
||||
{ sessionUpdate: "state_update", state: "running" },
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "cancelled" },
|
||||
{ sessionUpdate: "state_update", state: "running", background: [] },
|
||||
{ sessionUpdate: "state_update", state: "idle", stopReason: "cancelled", background: [] },
|
||||
]);
|
||||
// The turn goes on, and ends as Claude Code ends it.
|
||||
expect(turnTrace(client.sessionUpdates).at(-1)).toBe("idle end_turn");
|
||||
@@ -4781,6 +5074,8 @@ describe("ACP v2 requests that a cancel withdraws", () => {
|
||||
});
|
||||
|
||||
expect(trace).toEqual(["user_message", "running", "requires_action", "idle cancelled"]);
|
||||
// The client does not answer the request, so the agent cancels it.
|
||||
expect(client.cancelledRequests).toHaveLength(1);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -4800,14 +5095,18 @@ describe("ACP v2 requests that a cancel withdraws", () => {
|
||||
const client = holdingClient();
|
||||
|
||||
let atClose: string[] = [];
|
||||
let cancelledAtClose: string[] = [];
|
||||
await runTurn(client, async (agent, sessionId) => {
|
||||
await awaitsUser(client);
|
||||
await agent.request(v2.methods.agent.session.close, { sessionId });
|
||||
atClose = turnTrace(client.sessionUpdates);
|
||||
cancelledAtClose = [...client.cancelledRequests];
|
||||
});
|
||||
closed.resolve();
|
||||
|
||||
expect(atClose).toEqual(["user_message", "running", "requires_action", "idle cancelled"]);
|
||||
// The request is cancelled with `$/cancel_request` before session/close responds.
|
||||
expect(cancelledAtClose).toHaveLength(1);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -5189,6 +5488,510 @@ describe("ACP v2 terminal of a command in the background", () => {
|
||||
expect(trace.filter((entry) => entry === "exit")).toHaveLength(1);
|
||||
expect(trace.indexOf("exit")).toBeLessThan(trace.indexOf("idle end_turn"));
|
||||
});
|
||||
|
||||
describe("background work", () => {
|
||||
/** Claude Code's live background task set. A task joins it before its
|
||||
* `task_started`, and leaves it after its `task_notification`. */
|
||||
const level = (options: Options, tasks: Array<Record<string, unknown>>) => ({
|
||||
type: "system",
|
||||
subtype: "background_tasks_changed",
|
||||
tasks: tasks.map((fields) => ({
|
||||
task_id: "bg1",
|
||||
task_type: "local_bash",
|
||||
description: "make test",
|
||||
...fields,
|
||||
})),
|
||||
uuid: randomUUID(),
|
||||
session_id: options.sessionId,
|
||||
});
|
||||
|
||||
/** The session's states with their `background` lists, and the terminal
|
||||
* updates that change whether it can be cancelled or end it. */
|
||||
const backgroundTrace = (client: ReturnType<typeof v2Client>) =>
|
||||
client.sessionUpdates.flatMap(({ update }) => {
|
||||
if (update.sessionUpdate === "terminal_update") {
|
||||
if (update.exitStatus) return [update.capabilities === null ? "exit, no cancel" : "exit"];
|
||||
const capabilities = update.capabilities as { cancel?: unknown } | null | undefined;
|
||||
return capabilities?.cancel ? ["cancel"] : [];
|
||||
}
|
||||
if (update.sessionUpdate !== "state_update") return [];
|
||||
const stopReason =
|
||||
"stopReason" in update && update.stopReason ? ` ${update.stopReason}` : "";
|
||||
const { background } = update as { background?: v2.BackgroundWork[] | null };
|
||||
const items = (background ?? []).map((item) =>
|
||||
"terminalId" in item
|
||||
? String(item.terminalId)
|
||||
: "toolCallId" in item
|
||||
? String(item.toolCallId)
|
||||
: String(item.type),
|
||||
);
|
||||
return [`${update.state}${stopReason} [${items.join(",")}]`];
|
||||
});
|
||||
|
||||
/** Prompts once, and runs `during` once the trace holds `until`. */
|
||||
async function promptUntil(
|
||||
until: string,
|
||||
during: (
|
||||
agent: v2.ClientContext,
|
||||
sessionId: string,
|
||||
client: ReturnType<typeof v2Client>,
|
||||
) => Promise<unknown> = async () => {},
|
||||
) {
|
||||
const client = v2Client();
|
||||
await client.app.connectWith(connectRouter(), async (agent) => {
|
||||
await initializeV2(agent);
|
||||
const { sessionId } = await agent.request(v2.methods.agent.session.new, { cwd });
|
||||
await agent.request(v2.methods.agent.session.prompt, { sessionId, prompt: text("hi") });
|
||||
await vi.waitFor(() => expect(backgroundTrace(client)).toContain(until));
|
||||
await during(agent, sessionId, client);
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
it("lists the terminal from the Bash result until the command's task ends, and lets the client cancel it meanwhile", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
yield* taskEnded(options);
|
||||
yield level(options, []);
|
||||
yield assistantText(options, "The tests failed.", "msg_followup");
|
||||
yield result(options, { origin: { kind: "task-notification" } });
|
||||
yield idleState(options);
|
||||
});
|
||||
const client = await promptUntil("idle end_turn []");
|
||||
|
||||
// The terminal can be cancelled before a list names it, and no longer
|
||||
// once it exits, before the list drops it. A repeated state has no stop
|
||||
// reason.
|
||||
expect(backgroundTrace(client)).toEqual([
|
||||
"running []",
|
||||
"cancel",
|
||||
"running [toolu_bg]",
|
||||
"idle end_turn [toolu_bg]",
|
||||
"exit, no cancel",
|
||||
"idle []",
|
||||
"running []",
|
||||
"idle end_turn []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("ends the terminal before the list drops it when Claude Code reports no end for its task", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
yield level(options, []);
|
||||
});
|
||||
const client = await promptUntil("idle []");
|
||||
|
||||
expect(backgroundTrace(client).slice(-3)).toEqual([
|
||||
"idle end_turn [toolu_bg]",
|
||||
"exit, no cancel",
|
||||
"idle []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("ends the listed terminals when the query ends, as its background tasks end with it", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
throw new Error("The Claude Code process exited");
|
||||
});
|
||||
const client = await promptUntil("idle []");
|
||||
|
||||
expect(backgroundTrace(client).slice(-3)).toEqual([
|
||||
"idle end_turn [toolu_bg]",
|
||||
"exit, no cancel",
|
||||
"idle []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("reports no list when the session's interrupt would stop background tasks", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
});
|
||||
const client = v2Client();
|
||||
await client.app.connectWith(connectRouter(), async (agent) => {
|
||||
await initializeV2(agent);
|
||||
// Without the declaration, Claude Code's interrupt kills background
|
||||
// tasks, so session/cancel could not leave listed work running.
|
||||
const { sessionId } = await agent.request(v2.methods.agent.session.new, {
|
||||
cwd,
|
||||
_meta: { claudeCode: { options: { perTaskStopAffordance: false } } },
|
||||
});
|
||||
await agent.request(v2.methods.agent.session.prompt, { sessionId, prompt: text("hi") });
|
||||
await vi.waitFor(() => expect(turnTrace(client.sessionUpdates)).toContain("idle end_turn"));
|
||||
await expect(
|
||||
agent.request(v2.methods.agent.terminal.cancel, { sessionId, terminalId: "toolu_bg" }),
|
||||
).rejects.toMatchObject({ code: -32602 });
|
||||
});
|
||||
|
||||
expect(sdk.queryOptions.at(-1)?.perTaskStopAffordance).toBe(false);
|
||||
expect(client.updates("state_update").filter((update) => "background" in update)).toEqual([]);
|
||||
expect(backgroundTrace(client)).not.toContain("cancel");
|
||||
});
|
||||
|
||||
it("leaves out a task that Claude Code marks ambient", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{ ambient: true }]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
});
|
||||
const client = await promptUntil("idle end_turn []");
|
||||
|
||||
expect(backgroundTrace(client)).toEqual(["running []", "idle end_turn []"]);
|
||||
});
|
||||
|
||||
it("stops the command's task on terminal/cancel, and rejects a terminal that is not listed", async () => {
|
||||
const stopped = Promise.withResolvers<string>();
|
||||
sdk.stopTask = async (taskId) => stopped.resolve(taskId);
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
await stopped.promise;
|
||||
yield taskEvent(options, "task_notification", {
|
||||
tool_use_id: "toolu_bg",
|
||||
status: "stopped",
|
||||
output_file: "/tmp/tasks/bg1.output",
|
||||
summary: "Stopped",
|
||||
});
|
||||
yield level(options, []);
|
||||
});
|
||||
let rejected: unknown;
|
||||
const client = await promptUntil(
|
||||
"idle end_turn [toolu_bg]",
|
||||
async (agent, sessionId, client) => {
|
||||
await expect(
|
||||
agent.request(v2.methods.agent.terminal.cancel, { sessionId, terminalId: "toolu_bg" }),
|
||||
).resolves.toEqual({});
|
||||
expect(await stopped.promise).toBe("bg1");
|
||||
await vi.waitFor(() => expect(backgroundTrace(client)).toContain("idle []"));
|
||||
rejected = await agent
|
||||
.request(v2.methods.agent.terminal.cancel, { sessionId, terminalId: "toolu_bg" })
|
||||
.catch((error: unknown) => error);
|
||||
},
|
||||
);
|
||||
|
||||
// The response does not wait for the command to stop: its exit follows.
|
||||
expect(backgroundTrace(client).slice(-2)).toEqual(["exit, no cancel", "idle []"]);
|
||||
expect(rejected).toMatchObject({ code: -32602 });
|
||||
});
|
||||
|
||||
describe("a task that a tool call started", () => {
|
||||
const monitor = {
|
||||
task_id: "mon1",
|
||||
task_type: "local_monitor",
|
||||
description: "Watch the logs",
|
||||
};
|
||||
const workflow = { task_id: "wf1", task_type: "local_workflow", description: "Review" };
|
||||
/** A Monitor call whose task `mon1` runs on after the call returns. The
|
||||
* tool starts the task, which joins the level before its
|
||||
* `task_started`, and returns. */
|
||||
async function* monitorStarts(options: Options) {
|
||||
yield toolUseMessage(options, "toolu_mon", "Monitor", { command: "tail -f app.log" });
|
||||
yield level(options, [monitor]);
|
||||
yield taskEvent(options, "task_started", { ...monitor, tool_use_id: "toolu_mon" });
|
||||
yield {
|
||||
...toolResultMessage(options, "toolu_mon", { content: "Monitor started (task mon1)." }),
|
||||
tool_use_result: { taskId: "mon1", timeoutMs: 0, persistent: true },
|
||||
};
|
||||
}
|
||||
const monitorEvent = (options: Options, subtype: string, fields: Record<string, unknown>) =>
|
||||
taskEvent(options, subtype, { ...fields, task_id: "mon1" });
|
||||
|
||||
/** The states with their lists, and the Monitor call's statuses and capability. */
|
||||
const toolCallTrace = (client: ReturnType<typeof v2Client>) =>
|
||||
client.sessionUpdates.flatMap(({ update }) => {
|
||||
if (update.sessionUpdate === "tool_call_update" && update.toolCallId === "toolu_mon") {
|
||||
const capabilities = update.capabilities as { cancel?: unknown } | null | undefined;
|
||||
return [
|
||||
...(update.status ? [String(update.status)] : []),
|
||||
...(capabilities === null ? ["no cancel"] : capabilities?.cancel ? ["cancel"] : []),
|
||||
];
|
||||
}
|
||||
if (update.sessionUpdate !== "state_update") return [];
|
||||
const stopReason =
|
||||
"stopReason" in update && update.stopReason ? ` ${update.stopReason}` : "";
|
||||
const { background } = update as { background?: v2.BackgroundWork[] | null };
|
||||
const items = (background ?? []).map((item) =>
|
||||
"toolCallId" in item ? String(item.toolCallId) : String(item.type),
|
||||
);
|
||||
return [`${update.state}${stopReason} [${items.join(",")}]`];
|
||||
});
|
||||
|
||||
it("keeps the call in_progress and listed until its task ends, and paused while the task is", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield* monitorStarts(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
yield monitorEvent(options, "task_updated", { patch: { status: "paused" } });
|
||||
yield monitorEvent(options, "task_updated", { patch: { status: "running" } });
|
||||
yield monitorEvent(options, "task_notification", {
|
||||
tool_use_id: "toolu_mon",
|
||||
status: "completed",
|
||||
output_file: "/tmp/tasks/mon1.output",
|
||||
summary: "Done",
|
||||
});
|
||||
yield level(options, []);
|
||||
});
|
||||
const client = await promptUntil("idle end_turn [toolu_mon]");
|
||||
await vi.waitFor(() => expect(toolCallTrace(client)).toContain("idle []"));
|
||||
|
||||
// The task is part of the call until the call returns, so nothing is
|
||||
// listed before. The call can be cancelled before a list names it, and
|
||||
// no longer once it ends, before the list drops it.
|
||||
expect(toolCallTrace(client)).toEqual([
|
||||
"running []",
|
||||
"pending",
|
||||
"in_progress",
|
||||
"cancel",
|
||||
"running [toolu_mon]",
|
||||
"idle end_turn [toolu_mon]",
|
||||
"paused",
|
||||
"in_progress",
|
||||
"completed",
|
||||
"no cancel",
|
||||
"idle []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("stops the task on tool_call/cancel, and reports the call cancelled", async () => {
|
||||
const stopped = Promise.withResolvers<string>();
|
||||
sdk.stopTask = async (taskId) => stopped.resolve(taskId);
|
||||
scriptTurns(async function* (options) {
|
||||
yield* monitorStarts(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
await stopped.promise;
|
||||
// Claude Code reports a stopped task as killed first.
|
||||
yield monitorEvent(options, "task_updated", { patch: { status: "killed" } });
|
||||
yield monitorEvent(options, "task_notification", {
|
||||
tool_use_id: "toolu_mon",
|
||||
status: "stopped",
|
||||
output_file: "/tmp/tasks/mon1.output",
|
||||
summary: "Stopped",
|
||||
});
|
||||
yield level(options, []);
|
||||
});
|
||||
let rejected: unknown;
|
||||
const client = await promptUntil(
|
||||
"idle end_turn [toolu_mon]",
|
||||
async (agent, sessionId, client) => {
|
||||
await expect(
|
||||
agent.request(v2.methods.agent.toolCall.cancel, {
|
||||
sessionId,
|
||||
toolCallId: "toolu_mon",
|
||||
}),
|
||||
).resolves.toEqual({});
|
||||
expect(await stopped.promise).toBe("mon1");
|
||||
await vi.waitFor(() => expect(toolCallTrace(client)).toContain("idle []"));
|
||||
rejected = await agent
|
||||
.request(v2.methods.agent.toolCall.cancel, { sessionId, toolCallId: "toolu_mon" })
|
||||
.catch((error: unknown) => error);
|
||||
},
|
||||
);
|
||||
|
||||
expect(toolCallTrace(client).slice(-3)).toEqual(["cancelled", "no cancel", "idle []"]);
|
||||
expect(rejected).toMatchObject({ code: -32602 });
|
||||
});
|
||||
|
||||
it("cancels the call when the query ends, as its task ends with it", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield* monitorStarts(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
throw new Error("The Claude Code process exited");
|
||||
});
|
||||
const client = await promptUntil("idle []");
|
||||
|
||||
expect(toolCallTrace(client).slice(-4)).toEqual([
|
||||
"idle end_turn [toolu_mon]",
|
||||
"cancelled",
|
||||
"no cancel",
|
||||
"idle []",
|
||||
]);
|
||||
});
|
||||
|
||||
it("leaves a listed Workflow running on session/cancel", async () => {
|
||||
const interrupted = Promise.withResolvers<void>();
|
||||
sdk.interrupt = async () => interrupted.resolve();
|
||||
const stopTask = vi.fn(async () => {});
|
||||
sdk.stopTask = stopTask;
|
||||
scriptTurns(async function* (options) {
|
||||
yield toolUseMessage(options, "toolu_wf", "Workflow", { script: "review" });
|
||||
yield level(options, [workflow]);
|
||||
yield taskEvent(options, "task_started", { ...workflow, tool_use_id: "toolu_wf" });
|
||||
yield {
|
||||
...toolResultMessage(options, "toolu_wf", { content: "Workflow launched." }),
|
||||
tool_use_result: {
|
||||
status: "async_launched",
|
||||
taskId: "wf1",
|
||||
taskType: "local_workflow",
|
||||
},
|
||||
};
|
||||
await interrupted.promise;
|
||||
yield result(options, ABORTED_TOOLS);
|
||||
yield idleState(options);
|
||||
});
|
||||
const client = await promptUntil("running [toolu_wf]", async (agent, sessionId, client) => {
|
||||
await agent.notify(v2.methods.agent.session.cancel, { sessionId });
|
||||
await vi.waitFor(() =>
|
||||
expect(backgroundTrace(client)).toContain("idle cancelled [toolu_wf]"),
|
||||
);
|
||||
});
|
||||
|
||||
expect(stopTask).not.toHaveBeenCalled();
|
||||
expect(
|
||||
client
|
||||
.updates("tool_call_update")
|
||||
.filter((update) => update.toolCallId === "toolu_wf" && update.status)
|
||||
.map((update) => update.status),
|
||||
).toEqual(["pending", "in_progress"]);
|
||||
});
|
||||
|
||||
it("sends each listed call's current state before the state snapshot of session/resume", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield* monitorStarts(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
yield monitorEvent(options, "task_updated", { patch: { status: "paused" } });
|
||||
});
|
||||
let resumed: v2.SessionUpdate[] = [];
|
||||
await promptUntil("idle end_turn [toolu_mon]", async (agent, sessionId, client) => {
|
||||
await vi.waitFor(() => expect(toolCallTrace(client)).toContain("paused"));
|
||||
const before = client.sessionUpdates.length;
|
||||
await agent.request(v2.methods.agent.session.resume, { sessionId, cwd });
|
||||
resumed = client.sessionUpdates.slice(before).map(({ update }) => update);
|
||||
});
|
||||
|
||||
// The call as its tool use shows it, with its status now, then its
|
||||
// capability.
|
||||
expect(resumed).toEqual([
|
||||
expect.objectContaining({
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: "toolu_mon",
|
||||
name: "Monitor",
|
||||
status: "paused",
|
||||
rawInput: { command: "tail -f app.log" },
|
||||
}),
|
||||
{
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: "toolu_mon",
|
||||
capabilities: { cancel: {} },
|
||||
},
|
||||
{
|
||||
sessionUpdate: "state_update",
|
||||
state: "idle",
|
||||
background: [{ type: "tool_call", toolCallId: "toolu_mon" }],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("lists a task without such a call as a _claude/task item", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [monitor]);
|
||||
// No tool call started it, such as a task that a hook started.
|
||||
yield taskEvent(options, "task_started", monitor);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
});
|
||||
const client = await promptUntil("idle end_turn [_claude/task]");
|
||||
|
||||
expect(backgroundTrace(client)).toEqual([
|
||||
"running []",
|
||||
"running [_claude/task]",
|
||||
"idle end_turn [_claude/task]",
|
||||
]);
|
||||
expect(client.updates("state_update").at(-1)).toMatchObject({
|
||||
background: [{ type: "_claude/task", taskId: "mon1", description: "Watch the logs" }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects terminal/cancel with -32602 when the command ends before Claude Code stops it", async () => {
|
||||
const ended = Promise.withResolvers<void>();
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
await ended.promise;
|
||||
yield* taskEnded(options);
|
||||
yield level(options, []);
|
||||
});
|
||||
let rejected: unknown;
|
||||
await promptUntil("idle end_turn [toolu_bg]", async (agent, sessionId, client) => {
|
||||
// The command ends while Claude Code handles the stop, which then
|
||||
// finds no task.
|
||||
sdk.stopTask = async () => {
|
||||
ended.resolve();
|
||||
await vi.waitFor(() => expect(backgroundTrace(client)).toContain("idle []"));
|
||||
throw new Error("No task bg1");
|
||||
};
|
||||
rejected = await agent
|
||||
.request(v2.methods.agent.terminal.cancel, { sessionId, terminalId: "toolu_bg" })
|
||||
.catch((error: unknown) => error);
|
||||
});
|
||||
|
||||
expect(rejected).toMatchObject({ code: -32602 });
|
||||
});
|
||||
|
||||
it("sends each listed terminal's current state before the state snapshot of session/resume", async () => {
|
||||
scriptTurns(async function* (options) {
|
||||
yield level(options, [{}]);
|
||||
yield taskStarted(options);
|
||||
yield bashUse(options);
|
||||
yield backgrounded(options);
|
||||
yield result(options);
|
||||
yield idleState(options);
|
||||
});
|
||||
let resumed: v2.SessionUpdate[] = [];
|
||||
await promptUntil("idle end_turn [toolu_bg]", async (agent, sessionId, client) => {
|
||||
const before = client.sessionUpdates.length;
|
||||
await agent.request(v2.methods.agent.session.resume, { sessionId, cwd });
|
||||
resumed = client.sessionUpdates.slice(before).map(({ update }) => update);
|
||||
});
|
||||
|
||||
expect(resumed).toEqual([
|
||||
{
|
||||
sessionUpdate: "terminal_update",
|
||||
terminalId: "toolu_bg",
|
||||
command: "make test",
|
||||
capabilities: { cancel: {} },
|
||||
},
|
||||
{
|
||||
sessionUpdate: "state_update",
|
||||
state: "idle",
|
||||
background: [{ type: "terminal", terminalId: "toolu_bg" }],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("ACP v2 session translation", () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import type { AcpClient, ClaudeAcpAgent as ClaudeAcpAgentType } from "../acp-age
|
||||
import type { AcpSessionNotification } from "../acp-subagents.js";
|
||||
import { ALLOW_BYPASS } from "../permissions/modes.js";
|
||||
import { NativeSubagentRuntime } from "../native-subagents.js";
|
||||
import { startupFailure } from "./helpers.js";
|
||||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
@@ -1401,6 +1402,36 @@ describe("createSession options merging", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("startup failures", () => {
|
||||
it("asks Claude Code to report why it could not start", async () => {
|
||||
await agent.newSession({ cwd: process.cwd(), mcpServers: [] });
|
||||
expect(capturedOptions?.env?.CLAUDE_CODE_STARTUP_FAILURE_RESULTS).toBe("1");
|
||||
});
|
||||
|
||||
it.each([
|
||||
["proxy_invalid", RequestError.internalError().code, "Internal error"],
|
||||
["gateway_signin_required", RequestError.authRequired().code, "Authentication required"],
|
||||
["org_pin_mismatch", RequestError.authRequired().code, "Authentication required"],
|
||||
["org_config_refused", RequestError.authRequired().code, "Authentication required"],
|
||||
["cwd_unavailable", RequestError.invalidParams().code, "Invalid params"],
|
||||
])("rejects with %s as code %i", async (reason, code, prefix) => {
|
||||
initError = startupFailure(reason, "Fix the setting and restart Claude Code.");
|
||||
await expect(agent.newSession({ cwd: process.cwd(), mcpServers: [] })).rejects.toMatchObject({
|
||||
code,
|
||||
message: `${prefix}: Fix the setting and restart Claude Code.`,
|
||||
data: { startupFailureReason: reason },
|
||||
});
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("passes on an exit error that names no reason", async () => {
|
||||
initError = new Error("Claude Code process exited with code 1. stderr: boom");
|
||||
await expect(agent.newSession({ cwd: process.cwd(), mcpServers: [] })).rejects.toBe(
|
||||
initError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("elicitation", () => {
|
||||
it("keeps AskUserQuestion disabled and omits callbacks without elicitation capability", async () => {
|
||||
await agent.initialize({ protocolVersion: 1, clientCapabilities: {} });
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
* their own vi.fn spies via `overrides`.
|
||||
*/
|
||||
|
||||
import type { ClientCapabilities, InitializeRequest } from "@agentclientprotocol/sdk/unstable";
|
||||
import {
|
||||
RequestError,
|
||||
type ClientCapabilities,
|
||||
type InitializeRequest,
|
||||
} from "@agentclientprotocol/sdk/unstable";
|
||||
|
||||
/** The context-usage report the base mock query returns. `rawMaxTokens`
|
||||
* matches the agent's DEFAULT_CONTEXT_WINDOW so window-related assertions
|
||||
@@ -41,6 +45,19 @@ export function makeMockQuery(overrides: Record<string, unknown> = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The error `initializationResult()` rejects with when Claude Code refuses to
|
||||
* start with `CLAUDE_CODE_STARTUP_FAILURE_RESULTS` set, as SDK 0.3.316 builds
|
||||
* it from the CLI's error result (same message prefix and fields).
|
||||
*/
|
||||
export function startupFailure(reason: string, cliMessage: string): Error {
|
||||
return Object.assign(new Error(`Claude Code returned an error result: ${cliMessage}`), {
|
||||
telemetryMessage: "Claude Code returned an error result",
|
||||
errorClass: "error_result",
|
||||
startupFailureReason: reason,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares the client capabilities through `initialize`, as a real client
|
||||
* does. The agent reads its capability choices only there.
|
||||
@@ -51,3 +68,16 @@ export async function initializeClient(
|
||||
): Promise<void> {
|
||||
await agent.initialize({ protocolVersion: 1, clientCapabilities });
|
||||
}
|
||||
|
||||
/**
|
||||
* A request to a client that never answers it, as the SDK connection returns
|
||||
* it with `stopWaitingOnCancel`: it rejects with `-32800` once `signal`
|
||||
* aborts. The real connection also sends `$/cancel_request` then.
|
||||
*/
|
||||
export function heldRequest<T>(_params?: unknown, signal?: AbortSignal): Promise<T> {
|
||||
return new Promise<T>((_resolve, reject) => {
|
||||
const cancel = () => reject(RequestError.requestCancelled(signal?.reason));
|
||||
if (signal?.aborted) cancel();
|
||||
else signal?.addEventListener("abort", cancel, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,3 +72,27 @@ export function withRunningTerminal(
|
||||
if (Object.keys(meta).length === 0) delete next._meta;
|
||||
return { ...notification, update: next };
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps the tool call of a task that went on in the background running: the
|
||||
* tool result update of a tool call in `toolCallIds` reports `in_progress`
|
||||
* instead of `completed`.
|
||||
*
|
||||
* A Monitor or Workflow call returns as soon as its task starts. The consumer
|
||||
* reports the task's end, or its pause, on the tool call (see
|
||||
* `Session.backgroundToolCalls`).
|
||||
*/
|
||||
export function withRunningToolCall(
|
||||
notification: SessionNotification,
|
||||
toolCallIds: ReadonlySet<string>,
|
||||
): SessionNotification {
|
||||
const update = notification.update;
|
||||
if (
|
||||
update.sessionUpdate !== "tool_call_update" ||
|
||||
!toolCallIds.has(update.toolCallId) ||
|
||||
update.status !== "completed"
|
||||
) {
|
||||
return notification;
|
||||
}
|
||||
return { ...notification, update: { ...update, status: "in_progress" } };
|
||||
}
|
||||
|
||||
@@ -29,12 +29,13 @@ export type ToolCallUpdate = SessionNotification["update"];
|
||||
const PLAN_FILE_CLEAR_SUFFIX = ":plan-file-clear";
|
||||
|
||||
/**
|
||||
* ACP v2's `cancelled` tool call status. v1's statuses have no such value, and
|
||||
* the agent builds its reports in v1 types, so it travels as a v1 status. Only
|
||||
* a v2 client gets it, and the v2 surface sends it as it is
|
||||
* (`src/v2/tool-call.ts`).
|
||||
* ACP v2's `cancelled` and `paused` tool call statuses. v1's statuses have no
|
||||
* such values, and the agent builds its reports in v1 types, so they travel as
|
||||
* v1 statuses. Only a v2 client gets them, and the v2 surface sends them as
|
||||
* they are (`src/v2/tool-call.ts`).
|
||||
*/
|
||||
const V2_CANCELLED = "cancelled" as unknown as ToolCallStatus;
|
||||
export const V2_CANCELLED = "cancelled" as unknown as ToolCallStatus;
|
||||
export const V2_PAUSED = "paused" as unknown as ToolCallStatus;
|
||||
|
||||
/** Whether `status` ends a tool call: `completed`, `failed`, or, on v2, `cancelled`. */
|
||||
export function isFinalToolCallStatus(status: ToolCallStatus | null | undefined): boolean {
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as v2 from "@agentclientprotocol/sdk/experimental/v2/unstable";
|
||||
import { ClaudeAcpAgent, type AcpClient, type Logger } from "../acp-agent.js";
|
||||
import type { AcpSessionNotification } from "../acp-subagents.js";
|
||||
import type { AcpPermissionRequest } from "../permissions/presentation.js";
|
||||
import { stateUpdate, V2Background } from "./background.js";
|
||||
import { v1InitializeRequest, v2InitializeResponse } from "./initialize.js";
|
||||
import { v1PermissionResponse, v2PermissionRequest } from "./permission.js";
|
||||
import { v2Foreground, v2Prompt } from "./prompt.js";
|
||||
@@ -61,6 +62,14 @@ export function v2AgentApp(
|
||||
v2Foreground((update) => {
|
||||
void client.send({ sessionId, update });
|
||||
}),
|
||||
background: {
|
||||
changed: (report) => {
|
||||
for (const notification of client.background.changed(report)) {
|
||||
void client.send(notification);
|
||||
}
|
||||
},
|
||||
forget: (sessionId) => client.background.forget(sessionId),
|
||||
},
|
||||
});
|
||||
onAgent(agent);
|
||||
})
|
||||
@@ -96,10 +105,23 @@ export function v2AgentApp(
|
||||
await agent.publishCurrentSessionInfo(params.sessionId);
|
||||
// v2 requires a snapshot of the foreground state after the replay and
|
||||
// before the response, also without a replay: a resumed live session can
|
||||
// be running a turn, or waiting on a permission request.
|
||||
// be running a turn, or waiting on a permission request. The current
|
||||
// state of each subagent, terminal and tool call it lists comes first,
|
||||
// as v2 requires. The subagents' go again after the response (see below).
|
||||
await agent.publishLiveSubagents(
|
||||
params.sessionId,
|
||||
client.background.listedSubagents(params.sessionId),
|
||||
);
|
||||
await agent.publishBackgroundToolCalls(
|
||||
params.sessionId,
|
||||
client.background.listedToolCalls(params.sessionId),
|
||||
);
|
||||
for (const notification of client.background.currentItems(params.sessionId)) {
|
||||
void client.send(notification);
|
||||
}
|
||||
void client.send({
|
||||
sessionId: params.sessionId,
|
||||
update: stateSnapshot(agent.foregroundState(params.sessionId)),
|
||||
update: stateUpdate(agent.foregroundState(params.sessionId)),
|
||||
});
|
||||
const commands = await setupCommands(agent, params.sessionId, logger);
|
||||
// The response ends a replay. The subagents RFD treats the replayed
|
||||
@@ -155,16 +177,17 @@ export function v2AgentApp(
|
||||
void client.send({ sessionId: params.sessionId, update });
|
||||
}),
|
||||
)
|
||||
.onRequest(v2.methods.agent.terminal.cancel, async ({ params }) => {
|
||||
await agent.cancelBackgroundTerminal(params);
|
||||
return {};
|
||||
})
|
||||
.onRequest(v2.methods.agent.toolCall.cancel, async ({ params }) => {
|
||||
await agent.cancelBackgroundToolCall(params);
|
||||
return {};
|
||||
})
|
||||
.onNotification(v2.methods.agent.session.cancel, ({ params }) => agent.cancel(params));
|
||||
}
|
||||
|
||||
/** The `state_update` that reports `state` as the current foreground state. */
|
||||
function stateSnapshot(state: "idle" | "running" | "requires_action"): v2.SessionUpdate {
|
||||
if (state === "idle") return { sessionUpdate: "state_update", state: "idle" };
|
||||
if (state === "running") return { sessionUpdate: "state_update", state: "running" };
|
||||
return { sessionUpdate: "state_update", state: "requires_action" };
|
||||
}
|
||||
|
||||
/**
|
||||
* The `availableCommands` of a setup response, which v2 requires when the
|
||||
* session has commands. The agent sends a v1 client the same list as an
|
||||
@@ -249,6 +272,9 @@ class V2ClientConnection implements AcpClient {
|
||||
/** The `_meta` that the client stores for each tool call. */
|
||||
readonly toolCallMeta = new V2ToolCallMeta();
|
||||
|
||||
/** The `background` list of each session's `state_update`s. */
|
||||
readonly background = new V2Background(this.terminals);
|
||||
|
||||
constructor(
|
||||
private readonly ctx: v2.AgentContext,
|
||||
private readonly logger: Logger,
|
||||
@@ -296,9 +322,11 @@ class V2ClientConnection implements AcpClient {
|
||||
* request opening.)
|
||||
*/
|
||||
send(notification: v2.UpdateSessionNotification): Promise<void> {
|
||||
return this.ctx.notify(v2.methods.client.session.update, notification).catch((error) => {
|
||||
this.logger.error(`Failed to send a ${notification.update.sessionUpdate} update:`, error);
|
||||
});
|
||||
return this.ctx
|
||||
.notify(v2.methods.client.session.update, this.background.stamp(notification))
|
||||
.catch((error) => {
|
||||
this.logger.error(`Failed to send a ${notification.update.sessionUpdate} update:`, error);
|
||||
});
|
||||
}
|
||||
|
||||
extNotification(method: string, params: Record<string, unknown>): Promise<void> {
|
||||
@@ -335,13 +363,17 @@ class V2ClientConnection implements AcpClient {
|
||||
childState = undefined;
|
||||
}
|
||||
// Every update goes to the connection before any is awaited, so an update
|
||||
// that another call sends meanwhile cannot come between them.
|
||||
await Promise.all([
|
||||
...updates.map((v2Update) =>
|
||||
this.ctx.notify(v2.methods.client.session.update, { ...notification, update: v2Update }),
|
||||
// that another call sends meanwhile cannot come between them. The parent's
|
||||
// copy is stamped first: a child's announcement starts its list.
|
||||
const stamped = [
|
||||
...updates.map((v2Update) => this.background.stamp({ ...notification, update: v2Update })),
|
||||
...(childState ? [this.background.stamp(childState)] : []),
|
||||
];
|
||||
await Promise.all(
|
||||
stamped.map((v2Notification) =>
|
||||
this.ctx.notify(v2.methods.client.session.update, v2Notification),
|
||||
),
|
||||
...(childState ? [this.ctx.notify(v2.methods.client.session.update, childState)] : []),
|
||||
]);
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,7 +437,7 @@ class V2ClientConnection implements AcpClient {
|
||||
const response = await this.ctx.request(
|
||||
v2.methods.client.session.requestPermission,
|
||||
v2PermissionRequest({ ...params, toolCall }),
|
||||
{ cancellationSignal: signal },
|
||||
{ cancellationSignal: signal, stopWaitingOnCancel: true },
|
||||
);
|
||||
return v1PermissionResponse(response);
|
||||
}
|
||||
@@ -421,7 +453,7 @@ class V2ClientConnection implements AcpClient {
|
||||
// one only in a received value. As on v1, an MCP server's schema is
|
||||
// relayed here unchanged, so this cast does not check it.
|
||||
params as v2.CreateElicitationRequest,
|
||||
{ cancellationSignal: signal },
|
||||
{ cancellationSignal: signal, stopWaitingOnCancel: true },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
199
src/v2/background.ts
Normal file
199
src/v2/background.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* The `background` lists of the v2 sessions of a connection (see
|
||||
* `background-work.ts`, which builds them).
|
||||
*
|
||||
* A session that reports its background work gets its list on every
|
||||
* `state_update` of its own stream, as v2 requires, from the list the agent
|
||||
* reports when the session starts. A subagent session of such a session
|
||||
* reports its own list from its announcement on, also in the parent's mirror
|
||||
* of its state (`subagent_update.state`).
|
||||
*/
|
||||
import type * as v2 from "@agentclientprotocol/sdk/experimental/v2/unstable";
|
||||
import type { BackgroundItem, BackgroundReport, WorkStateName } from "../background-work.js";
|
||||
import type { V2Terminals } from "./terminal.js";
|
||||
|
||||
/** `state` as the current work state of a session, with no stop reason. */
|
||||
function currentState(state: WorkStateName): v2.StateUpdate {
|
||||
if (state === "idle") return { state: "idle" };
|
||||
if (state === "running") return { state: "running" };
|
||||
if (state === "requires_action") return { state: "requires_action" };
|
||||
return { state: "unknown" };
|
||||
}
|
||||
|
||||
/** The `state_update` that reports `state` as the session's current work state. */
|
||||
export function stateUpdate(state: WorkStateName): v2.SessionUpdate {
|
||||
return { sessionUpdate: "state_update", ...currentState(state) };
|
||||
}
|
||||
|
||||
/** `state` with the list `background`. */
|
||||
function withBackground(state: v2.StateUpdate, background: BackgroundItem[]): v2.StateUpdate {
|
||||
return { ...state, background } as v2.StateUpdate;
|
||||
}
|
||||
|
||||
/** The final tool call statuses. */
|
||||
const FINAL_STATUSES = new Set(["completed", "failed", "cancelled"]);
|
||||
|
||||
export class V2Background {
|
||||
/**
|
||||
* The latest list of each session that reports one, whether a state of the
|
||||
* session carried it, and the parent of a subagent session.
|
||||
*/
|
||||
private readonly sessions = new Map<
|
||||
string,
|
||||
{ items: BackgroundItem[]; reported: boolean; parent?: string }
|
||||
>();
|
||||
|
||||
/**
|
||||
* The tool calls that advertise `cancel`, by session and tool call. Like a
|
||||
* terminal's (see `V2Terminals.advertiseCancel`), the capability goes with
|
||||
* the final status.
|
||||
*/
|
||||
private readonly cancellableToolCalls = new Set<string>();
|
||||
|
||||
constructor(private readonly terminals: V2Terminals) {}
|
||||
|
||||
/**
|
||||
* `notification` with the session's list, when it is a `state_update` of a
|
||||
* session that reports one, or a `subagent_update` that mirrors the state of
|
||||
* such a child. A child of a session that reports its list reports its own
|
||||
* from its announcement on: empty, until the agent reports it.
|
||||
*/
|
||||
stamp(notification: v2.UpdateSessionNotification): v2.UpdateSessionNotification {
|
||||
const { sessionId, update } = notification;
|
||||
if (
|
||||
update.sessionUpdate === "tool_call_update" &&
|
||||
FINAL_STATUSES.has(String(update.status)) &&
|
||||
this.cancellableToolCalls.delete(`${sessionId} ${update.toolCallId}`)
|
||||
) {
|
||||
// A tool call that reached its final status can no longer be cancelled.
|
||||
return { ...notification, update: { ...update, capabilities: null } };
|
||||
}
|
||||
if (update.sessionUpdate === "state_update") {
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (!session) return notification;
|
||||
session.reported = true;
|
||||
return { ...notification, update: { ...update, background: session.items } };
|
||||
}
|
||||
if (update.sessionUpdate === "subagent_update" && this.sessions.has(sessionId)) {
|
||||
const subagent = update as Extract<v2.SessionUpdate, { sessionUpdate: "subagent_update" }>;
|
||||
let child = this.sessions.get(subagent.sessionId);
|
||||
if (!child) {
|
||||
child = { items: [], reported: false, parent: sessionId };
|
||||
this.sessions.set(subagent.sessionId, child);
|
||||
}
|
||||
if (subagent.state) {
|
||||
return {
|
||||
...notification,
|
||||
update: { ...subagent, state: withBackground(subagent.state, child.items) },
|
||||
};
|
||||
}
|
||||
}
|
||||
return notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the new list of a session, and returns the updates that report it:
|
||||
*
|
||||
* - For each terminal or tool call that the list adds, a `terminal_update`
|
||||
* or `tool_call_update` that lets the client cancel it. It comes before
|
||||
* the first list that names it, as v2 requires of an announcement: its
|
||||
* own updates came earlier.
|
||||
* - Once a state of the session carried a list, the state again with the
|
||||
* new list, without a stop reason: a repeated `idle` is no new
|
||||
* completion. A subagent's goes to its parent's mirror first, as its
|
||||
* other states do.
|
||||
*/
|
||||
changed(report: BackgroundReport): v2.UpdateSessionNotification[] {
|
||||
const { sessionId, items, state, parentSessionId } = report;
|
||||
const session = this.sessions.get(sessionId);
|
||||
const unchanged = session && JSON.stringify(session.items) === JSON.stringify(items);
|
||||
this.sessions.set(sessionId, {
|
||||
items,
|
||||
reported: session?.reported ?? false,
|
||||
parent: parentSessionId ?? session?.parent,
|
||||
});
|
||||
const known = new Set((session?.items ?? []).map((item) => JSON.stringify(item)));
|
||||
const updates: v2.UpdateSessionNotification[] = items.flatMap((item) =>
|
||||
known.has(JSON.stringify(item)) ? [] : this.advertiseCancel(sessionId, item, false),
|
||||
);
|
||||
if (session?.reported && state && !unchanged) {
|
||||
if (parentSessionId) {
|
||||
updates.push({
|
||||
sessionId: parentSessionId,
|
||||
update: { sessionUpdate: "subagent_update", sessionId, state: currentState(state) },
|
||||
});
|
||||
}
|
||||
updates.push({ sessionId, update: stateUpdate(state) });
|
||||
}
|
||||
return updates;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current `terminal_update` of each terminal that the session
|
||||
* `sessionId` lists, and the `cancel` capability of each tool call that it
|
||||
* lists, whose other fields the agent sends (see
|
||||
* `ClaudeAcpAgent.publishBackgroundToolCalls`). v2 requires them before the
|
||||
* state snapshot of `session/resume`, as a replay may not have delivered
|
||||
* them.
|
||||
*/
|
||||
currentItems(sessionId: string): v2.UpdateSessionNotification[] {
|
||||
return (this.sessions.get(sessionId)?.items ?? []).flatMap((item) =>
|
||||
this.advertiseCancel(sessionId, item, true),
|
||||
);
|
||||
}
|
||||
|
||||
/** The tool calls that the session `sessionId` lists. */
|
||||
listedToolCalls(sessionId: string): string[] {
|
||||
return (this.sessions.get(sessionId)?.items ?? []).flatMap((item) =>
|
||||
item.type === "tool_call" ? [item.toolCallId] : [],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The update that lets the client cancel the listed terminal or tool call
|
||||
* `item`, unless it advertises that already. `again` sends it anyway, as
|
||||
* the item's current state.
|
||||
*/
|
||||
private advertiseCancel(
|
||||
sessionId: string,
|
||||
item: BackgroundItem,
|
||||
again: boolean,
|
||||
): v2.UpdateSessionNotification[] {
|
||||
if (item.type === "terminal") {
|
||||
const update = this.terminals.advertiseCancel(sessionId, item.terminalId, again);
|
||||
return update ? [{ sessionId, update }] : [];
|
||||
}
|
||||
if (item.type !== "tool_call") return [];
|
||||
const key = `${sessionId} ${item.toolCallId}`;
|
||||
if (this.cancellableToolCalls.has(key) && !again) return [];
|
||||
this.cancellableToolCalls.add(key);
|
||||
return [
|
||||
{
|
||||
sessionId,
|
||||
update: {
|
||||
sessionUpdate: "tool_call_update",
|
||||
toolCallId: item.toolCallId,
|
||||
capabilities: { cancel: {} },
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** The subagent sessions that the session `sessionId` lists. */
|
||||
listedSubagents(sessionId: string): string[] {
|
||||
return (this.sessions.get(sessionId)?.items ?? []).flatMap((item) =>
|
||||
item.type === "subagent" ? [item.sessionId] : [],
|
||||
);
|
||||
}
|
||||
|
||||
/** Forgets the list of a session, and those of its subagent sessions. */
|
||||
forget(sessionId: string): void {
|
||||
this.sessions.delete(sessionId);
|
||||
for (const key of this.cancellableToolCalls) {
|
||||
if (key.startsWith(`${sessionId} `)) this.cancellableToolCalls.delete(key);
|
||||
}
|
||||
for (const [child, { parent }] of this.sessions) {
|
||||
if (parent === sessionId) this.forget(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,10 @@ const TERMINAL_KEYS = [
|
||||
/** The terminal updates of the tool call reports of one v2 connection. */
|
||||
export class V2Terminals {
|
||||
/** The terminal and the last reported command of each running command, by session and tool call. */
|
||||
private readonly running = new Map<string, { terminalId: string; command?: string }>();
|
||||
private readonly running = new Map<
|
||||
string,
|
||||
{ terminalId: string; command?: string; cancellable?: boolean }
|
||||
>();
|
||||
|
||||
/**
|
||||
* The terminal updates that a tool call report carries in the extension's
|
||||
@@ -73,6 +76,8 @@ export class V2Terminals {
|
||||
...(exit.exit_code != null ? { exitCode: exit.exit_code } : {}),
|
||||
...(exit.signal != null ? { signal: exit.signal } : {}),
|
||||
},
|
||||
// An exited terminal can no longer be cancelled.
|
||||
...(running.cancellable ? { capabilities: null } : {}),
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
@@ -89,6 +94,30 @@ export class V2Terminals {
|
||||
return { terminal, report: withoutTerminalKeys(report) };
|
||||
}
|
||||
|
||||
/**
|
||||
* The `terminal_update` that lets the client cancel the running terminal
|
||||
* `terminalId` of the session `sessionId` with `terminal/cancel`, with its
|
||||
* command, or undefined when the terminal is not running. `again` sends it
|
||||
* also when the terminal advertises the capability already, as the current
|
||||
* state of the terminal.
|
||||
*/
|
||||
advertiseCancel(
|
||||
sessionId: string,
|
||||
terminalId: string,
|
||||
again = false,
|
||||
): v2.SessionUpdate | undefined {
|
||||
// The agent names a command's terminal after its tool call.
|
||||
const running = this.running.get(`${sessionId} ${terminalId}`);
|
||||
if (!running || (running.cancellable && !again)) return undefined;
|
||||
running.cancellable = true;
|
||||
return {
|
||||
sessionUpdate: "terminal_update",
|
||||
terminalId,
|
||||
...(running.command !== undefined ? { command: running.command } : {}),
|
||||
capabilities: { cancel: {} },
|
||||
};
|
||||
}
|
||||
|
||||
/** Forgets the terminals of a session. */
|
||||
forget(sessionId: string): void {
|
||||
for (const key of this.running.keys()) {
|
||||
|
||||
Reference in New Issue
Block a user