The error idle of a query that ended went out without the turn-end cleanup
of closeTurn, so a compaction reported in_progress never ended. ended() now
resets it through reports.turnEnded() before the idle.
Co-Authored-By: Claude <noreply@anthropic.com>
A replay of an active session re-rendered a background Bash call's result
with its terminal exit, and the shared V2Terminals replaced the running
entry. Replay now rewrites the results of the session's background work as
the live path does (SessionTasks.replayedBackground), and a replayed
terminal_info keeps the terminal's running entry.
Co-Authored-By: Claude <noreply@anthropic.com>
Keeps isLoginRequiredText re-exported from acp-agent.js after its move to
result-end.ts, and adds the names the v2 agent imports from acp-agent.js
(AUTONOMOUS_RESULT_ORIGINS, getAvailableSlashCommands, isAbortedResult)
to the pinned list.
Co-Authored-By: Claude <noreply@anthropic.com>
Ports #1548 to the v2 agent: sessionModels applies aliasResumedModelRow
before the allowlist and model selection, as ClaudeAcpAgent.createSession
does, so a resumed Fable 5.2 session offers `fable` as a new one does.
Co-Authored-By: Claude <noreply@anthropic.com>
Ports #1554 to the v2 agent: a conversation_reset (such as /clear) sends
plan_removed for the checklist (`plan`) and the approved ExitPlanMode
plan (`plan-mode`) through the shared resetPlanUpdates, as v1 does for a
client with plan operations. Before, it sent an empty plan_update. The
v2 agent publishes approved plans under the plain `plan-mode` id, also
to AIR, so AIR's plan is removed too. The fresh context of a plan
accepted with clearing the context still removes nothing: that plan
becomes the session's plan in it.
Co-Authored-By: Claude <noreply@anthropic.com>
Ports #1550, #1552 and #1556, which changed the v2 output of the old
bridge, to the v2 agent:
- A workflow's task_progress shows on its tool call as its title and
body, with the workflow_progress phases and agents
(workflowCard in workflow-progress.ts). Progress before the launch
result waits for it, and a session/resume snapshot carries it.
- A live background task that no tool call or terminal stands for gets
a tool call of its own (task_<taskId>), sent before the first
background list that names it, instead of a _claude/task item.
- An Edit or Write preview from the PreToolUse hook waits for the tool
call's first publication instead of publishing a call that a
workflow agent never ends.
Co-Authored-By: Claude <noreply@anthropic.com>
Both cores call session-env's configuredSettings, which now applies the
models of CLAUDE_MODEL_CONFIG itself. The v2 wrapper of the same name is
gone.
Co-Authored-By: Claude <noreply@anthropic.com>
resultEnd now makes exactly the decisions of v1's subtype switch, and the
v1 prompt loop calls it, keeping its own session failure categories and
result forwarding. v1 is unchanged. v2 now follows v1 where the copies
differed: a limit result (error_max_turns, error_max_budget_usd,
error_max_structured_output_retries) ignores stop_reason max_tokens, and a
success error with the /login text fails with authRequired even at
max_tokens. isLoginRequiredText moves to result-end.ts.
Co-Authored-By: Claude <noreply@anthropic.com>
A route change (providers/set, providers/disable, an auth/logout that
drops a provider or gateway login, or a resume with new additional
directories) now restarts a session at a turn boundary right away, and
the request waits only for those restarts. A busy session (an open turn,
a pending prompt, a live subagent, or a restart that runs) restarts at
its next turn boundary without the request waiting, and its prompts keep
going to the current query until then. Prompts wait only for a restart
that runs.
Co-Authored-By: Claude <noreply@anthropic.com>
## Summary
Updates `@anthropic-ai/claude-agent-sdk` from 0.3.319 to 0.3.321. It
bundles Claude Code 2.1.321, which adds Fable 5.2 (`claude-fable-5-2`)
as the new default `fable` model. Also bumps these dev dependencies:
`@anthropic-ai/sdk` 1.6.0 → 1.7.0 and `@typescript-eslint/*` 8.72.1 →
8.72.2. `typescript` 7 is left for its own PR.
## Fable 5.2
Checked against the real CLI:
- A new session lists `fable` → `claude-fable-5-2`, and
`claude-fable-5-1` as its own row.
- A resumed Fable 5.2 session lists `claude-fable-5-2` and no `fable`
row, the same pattern 5.1 had.
`aliasResumedModelRow` already handles any version, so the code is
unchanged. Its doc comment and test fixture now describe the 2.1.321
lists. The fixture also covers a resumed Fable 5.1 session keeping
`claude-fable-5-1`, because a newer Fable is listed.
## Changelog review
- No SDK type changes that affect us. The only changes are doc text and
a new optional `endedLoopWakeup` field in `sdk-tools.d.ts`.
- Queued subagent reports in auto mode now share one model call, and all
but the last end in a `num_turns: 0` placeholder result. These results
carry `task-notification` or `peer` origins, which we already treat as
placeholders. That handling dates from CLI 2.1.274, which did the same
for background-task notifications.
- Fixes we pick up: one `undefined` entry in `hooks` no longer drops
every hook; a PreToolUse `ask` is no longer lost when another hook's
`defer` finishes first; project skills and commands no longer go missing
after entering a worktree; MCP OAuth no longer sends refresh tokens to
another host after a redirect.
## Testing
- `npm run build`, `npm run check`, `npm run test:run`
- Real CLI: listed the models for a new session and for a resumed Fable
5.2 session
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Background tasks that have no tool call or terminal on v2 now get a tool
call of their own. Before, they showed up as a `_claude/task` vendor
item. This follows the spec rule in
agentclientprotocol/agent-client-protocol#2786.
Examples: a workflow, or an MCP task that starts after its tool call
already returned, or a task a hook started.
- `BackgroundWork.adoptTasks` starts a tool call `task_<taskId>` for
each such task. It uses the task description as title, `kind: "other"`,
and `in_progress` or `paused`. A subagent's task goes on the subagent's
stream. The message loop sends these calls before `sync`, so a call is
always announced before the first `background` list names it. The same
path covers the `state_update` snapshot on `session/resume`.
- These calls are listed as `tool_call` items, so `tool_call/cancel`
stops the task. When the task ends they get a final status like any
other listed call (`completed`, `failed`, or `cancelled`).
- The `_claude/task` item type is gone. `BackgroundItem` is now
`terminal | tool_call | subagent`.
- Ambient tasks such as the monitor, and tasks whose own tool call is
still open, are unchanged.
`adoptTasks` is synchronous and returns the notifications, so the loop
only awaits when there is something to send. An extra await on every
pass broke the steering-cancel timing in `acp-agent.test.ts`.
## Compatibility
- ACP v1 clients, including JetBrains AIR's `_session/async_task/*`
extension, are unaffected. Background lists, and therefore this path,
only run when the v2 background sink exists and the session has
`perTaskStopAffordance`. On v1, `adoptTasks` returns `[]`.
- v2 clients that saw `_claude/task` items (v0.100.0 to v0.101.1) now
see `task_<id>` tool calls instead.
## Tests
`acp-v2.test.ts` replaces the `_claude/task` tests. New tests cover:
- starting and listing a call for a task that starts after its tool call
returned
- cancelling such a task with `tool_call/cancel`
- the call being sent before the `session/resume` snapshot
- a subagent's task appearing on the subagent's stream
`npm run check`, `build` and `test:run` pass.
Renames v2-native.test.ts to v2.test.ts and v2-native-integration.test.ts
to v2-integration.test.ts, and drops "native" from their describe blocks,
helpers and client names.
Co-Authored-By: Claude <noreply@anthropic.com>
There is one ACP v2 implementation now, so it lives in src/v2/ beside
the v2 wire conversions it uses. src/v2/permission.ts merges into
permissions.ts, which owns the v2 permission requests.
Renames nativeV2AgentApp to v2AgentApp, NativeV2Agent to V2Agent,
NativeSession to V2Session and NativeAuth to V2Auth, and rewords
"native v2 core" comments to "v2 core". No behavior change.
Co-Authored-By: Claude <noreply@anthropic.com>
The file holds the v1 form of the v2 session setup and config requests
and the v2 form of config options and commands. The rename frees
src/v2/session.ts for the v2 session that moves in next.
Co-Authored-By: Claude <noreply@anthropic.com>
Updates `docs/v2-native-core.md` (status, a history note in place of
"Replacing the bridge", the differences from the old bridge in the past
tense, the test setup), the README, the AIR extensions doc and
AGENTS.md, and rewrites code comments that described the bridge.
Co-Authored-By: Claude <noreply@anthropic.com>
Removes the v2 paths that only the deleted bridge reached: the `v2`,
`foreground` and `background` constructor options, `ForegroundEvents` and
the awaiting-user tracking, the background list reporting
(`BackgroundWorkReporter`, `cancelBackgroundWork`, the reported paths of
`SessionBackgroundWork`), the Edit/Write preview hook, `this.v2` branches
in initialize, permissions and setup, and the public methods only the
bridge called (`foregroundState`, `publishLiveSubagents`,
`publishBackgroundToolCalls`, `cancelBackgroundTerminal`,
`cancelBackgroundToolCall`, `authenticateMcpServers`,
`publishCurrentSessionInfo`).
`foregroundWork` stays as the record of who owns the foreground work
(a turn or an autonomous cycle): v1 still reads it in `claudeIsWorking`,
`workEndReported` and `requestOwnerTurn`. The `background` list types
move to `src/v2/background.ts`, next to `V2Background`.
Co-Authored-By: Claude <noreply@anthropic.com>
The protocol router now always serves v2 with `src/v2-native/`. Removes
`CLAUDE_AGENT_ACP_V2_CORE`, `V2Core`, `v2CoreFromEnv`, the bridge's
`src/v2/agent.ts`, the conversions only it used (v1 initialize, restore and
setup responses, the prompt turn events, child state copies) and
`scripts/compare-v2-cores.mjs`. The rest of `src/v2/` stays as the v2 wire
conversions that the native core imports.
The v2 tests and scenarios run once, on the native core, against the
existing golden files.
Co-Authored-By: Claude <noreply@anthropic.com>
A v2 client that declares _meta.jetbrains.air now gets the native core,
which serves it the AIR extensions that ACP v2 does not cover, with the
v1 core's wire output:
- recommendedValue on the model and effort options, and the shown effort
set on the query at the start and at each model switch
- the AIR permission presentation and AIR's permission tool call meta
- AskUserQuestion's custom answer marker
- the predicted follow-up prompt, cleared at the next prompt and at a
conversation reset
- agentFileChangeReport, sent at the end of the turn that serves the
prompt, before its idle, since a v2 prompt is answered at insertion
initialize lists agentFileChangeReport and recommendedValue to an AIR
client only. The extensions that v2 covers (subagent sessions,
background lists, file plans, patches, compaction, systemPrompt, failed
idles) are not served. CLAUDE_AGENT_ACP_V2_CORE=bridge still serves AIR
with the bridge.
Co-Authored-By: Claude <noreply@anthropic.com>
PromptSuggestions holds the prediction a session's client holds and the
window a result opens, which the v1 core kept in two session fields.
airPermissionMeta builds _meta.jetbrains.air.permission apart from the
renderer, so the native v2 core can add it to a v2-rendered request.
Co-Authored-By: Claude <noreply@anthropic.com>
A foreground subagent whose task_started reached the native v2 core after
the root's session/cancel, but before the cancelled work's result, kept
its permission and elicitation requests going to the client and its
consolidated messages going out. SessionTasks now keeps the root's cancel
in effect until the stopped work's result, Claude Code's idle, the next
prompt's start, or a failed interrupt, and stops such a subagent the same
way as one present at the cancel. A request of a subagent whose run a
cancel stops is withdrawn before it goes out.
Co-Authored-By: Claude <noreply@anthropic.com>
- `resolveModelPreference` resolves `best` (and `best[1m]`, whose hint the
CLI ignores) as `opus`, the CLI's flagship fallback, unless an entry's
value is `best`. Its preference words drop leading gateway segments before
`claude-` (`vertex_ai/`, `openrouter/anthropic/`, `litellm/`,
`publishers/anthropic/models/`) and a trailing `-latest`, which resolved
before 51ab745 and gave null since.
- With `v2Core: "native"`, a v2 client that declares `_meta.jetbrains.air`
gets the bridge (`airClientsOnBridge` in serve.ts): the native core serves
no AIR extension, so a v2 AIR client would silently lose sessionFailure
(API retry warnings), prompt suggestions, file change reports and AIR's
subagent form. The docs' "Not served yet" section is corrected.
- `v2-native-integration.test.ts` (RUN_INTEGRATION_TESTS) runs the default
v2 core in the adapter's process against the bundled CLI: insertion,
running -> idle, requires_action at a permission request, and a cancel
that fails a queued prompt with -32800.
## Summary
Follow-up to the [plan operations
RFD](https://agentclientprotocol.com/rfds/plan-operations). The adapter
already sent approved ExitPlanMode plans as `markdown` plans to clients
with the `plan` capability, but two parts of the RFD were unused:
- **The checklist is now a plan operation on v1 too.** Clients with
`plan` (every v2 client, and v1 clients that opt in) get the
TodoWrite/Task checklist as `plan_update` with type `items` and the ID
`plan`. Before, v1 clients with the capability still got an ID-less
legacy `plan` next to the `plan-mode` plan. Clients without the
capability still get the legacy `plan`.
- **`plan_removed` is now sent.**
- An empty checklist sends `plan_removed` for `plan`. v2 clients used to
get a `plan_update` with no entries.
- A conversation reset (`/clear`) removes the checklist and the old
conversation's approved `plan-mode` plan. AIR keeps its approved plans,
which are joined to their approval cards by ID (#1469).
The new `src/plans.ts` builds the checklist updates. All three places
that send the checklist use it, and so does the v2 conversion of a
legacy `plan`, so v1 and v2 follow one rule.
The reset sends `plan_removed` for `plan-mode` even when the session
never published an approved plan. Tracking whether one was published
would be state that a restart loses, so the reset would behave
differently before and after one.
`file` plans are left out. A `file://` URI only works for a client on
the same machine, and v2 has no client filesystem.
## Tests
- `tools.test.ts`: TodoWrite with and without todos, and a TaskCreate
snapshot, for a v1 client with `plan`.
- `acp-agent.test.ts`: the reset test now runs for a client without plan
operations, a client with them, and AIR.
- `acp-v2.test.ts`: v2 end to end, TodoWrite then `/clear`, and an empty
legacy plan converting to `plan_removed`.
CLAUDE_AGENT_ACP_V2_CORE now defaults to native; CLAUDE_AGENT_ACP_V2_CORE=bridge
selects the bridge as a fallback. acpProtocolRouter's v2Core option defaults to
native too. The unit vitest project pins the v2 tests and scenarios to the
bridge, and the v2-native-core project runs them on the native core.
## Summary
Show the phases and agents of a running workflow on its ACP v2 tool
card, not only the current activity and totals.
Claude Code attaches a `workflow_progress` snapshot to some of a
workflow's `task_progress` events: every phase, and every agent with its
label, phase, state, tokens, tool calls, duration and last tool. #1550
deliberately left it out. This change renders it under the existing card
body:
```
**Count**
- two: done · 14,629 tokens · 0 tool calls · 1s
- three: running · Bash: echo 3
**Sum**
- not started
```
### Why an untyped field
The SDK (0.3.319) does not type `workflow_progress`. Workflow agents
also don't stream their messages through the root query, so this
snapshot is the only per-agent data the adapter gets.
`src/workflow-progress.ts` reads the shape the CLI sends and skips
entries that don't match it. If the CLI changes the format, the card
loses the list but still renders. The right long-term fix is for the SDK
to type this field, or to stream workflow agents with a parent id so
each one can become a child session.
### Behavior
- The snapshot is a full list, and the CLI leaves it out of some
reports. A report without one keeps the last list.
- A running agent shows its last tool (e.g. `Bash: echo 3`). A finished
one shows tokens, tool calls and duration.
- Agents with no known phase are listed first. A phase with no agent yet
shows `not started`. A retry shows its attempt. A state other than
`start`/`done` is shown as the CLI sends it.
- The existing duplicate suppression and the `session/resume` snapshot
cover the list too.
- AIR `async_task_progress` is unchanged. Like the rest of the card
progress from #1550, this only reaches v2 clients that get workflow
progress on the card.
Result previews, models and prompt previews are left out to keep the
card short.
## Validation
- Live probe on Claude Code 2.1.319 (SDK `query()`, two-phase
three-agent workflow, permissions limited to `Workflow` and one `echo
3`). It captured the snapshot shape used in the test doubles. Every
captured snapshot rendered through the built module as shown above. This
checked the protocol output, not the Delta UI.
- New v2 scenario built from the captured payload, plus unit cases in
`src/tests/workflow-progress.test.ts`.
- `npm run check`, `npm run build`, `npm run test:run` (3,691 passed, 30
skipped).
As the bridge does: after the root's session/cancel, a foreground child's
consolidated messages are dropped until its run ends, apart from the results
of the tool calls the client holds; a conversation_reset ends each working
child idle with no stop reason and forgets the children. Documents that both
cores reject a replayFrom cursor other than start with -32602, and the
remaining intended differences.
resolveModelPreference matched preference tokens as substrings, so
"not-a-model" resolved to Default ("a" is inside "default") and
"son" or "foo-sonnet" to Sonnet. configOptionValue, which v1, the v2
bridge and the native v2 core share, then accepted the value. Words now
match whole, and the fuzzy tiers need every model word of the
preference; provider ids, dates, -fast and context hints are dropped
with normalizeModelId first, so aliases and provider spellings still
resolve.
## Summary
Fix workflow tool cards that remain pending indefinitely, and surface
workflow progress through standard ACP v2 updates.
### Prevent orphan preview cards
Claude Code invokes Edit/Write preview hooks for workflow agents without
streaming those tools' uses and results through the root query.
Publishing a card from the hook alone leaves a pending call with no
completion path.
Stage early preview patches until the stream or a permission request
publishes the actual tool call. Keep patches pinned against later input
refinements, bound unclaimed previews, and clear them on teardown. A
call's own content takes precedence over a staged preview.
### Show workflow progress in place
Forward the SDK's typed task-progress fields to the existing workflow
card: current activity, summary, last activity, token count, tool-call
count, and elapsed time. Preserve progress arriving before the launch
result, suppress duplicate display updates, and include the latest
progress on session resume. Progress does not change paused/running
state or reopen completed calls.
This reads no workflow transcripts, journals, or metadata files and
introduces no ACP extension. The CLI also emits an untyped
`workflow_progress` snapshot; consuming that richer phase/agent data is
deliberately left out of this change. Existing v1 AIR progress uses the
same field normalization as before.
## Validation
- Regression reproduced before the orphan-preview fix.
- Nine relevant Vitest suites: **1,972 passed, 10 skipped**, including
v1/v2 scenarios, preview ordering, progress-before-launch, idle and
paused updates, duplicate suppression, resume snapshots, and late
progress after completion.
- `npm run check`
- `npm run build`
- `git diff --check`
- Live Claude Code **2.1.319** probes: captured SDK workflow events and
ran a real workflow through the updated ACP v2 adapter. One card
received two progress updates and then reached `completed`. This
verified protocol updates, not the Delta UI.
Rebased onto current `main` and reran the automated checks before
opening the PR.
acp-scenarios-v2.test.ts runs again in the v2-native-core vitest project
with V2_CORE_UNDER_TEST=native, comparing every message of each run with
the bridge's golden files and never writing them. It supersedes
acp-scenarios-v2-native.test.ts, which compared only session updates.
The native core's async prompt handler added promise hops, so the turn's
running state_update went out before the session/prompt response. v2
allows either order; the bridge's golden files hold the response first.
- Restarts restore effort, Fast mode, ultracode, the picked agent and
prePlanMode as the bridge does (SessionConfig.restoreFrom), and start
without the setup's _meta effort (withoutEffort, moved to session-effort).
- A route restart waits for a running account restart; the old query ends
at its next turn boundary after the new one started; a close during a
restart forgets the session.
- Config changes of a session run one at a time.
- The subscription guard runs in the session's prompt chain: cancel and
close answer a prompt it judges with -32800, and /remote-control keeps
its place.
- systemPrompt is validated on every setup path before it acts (active
resume, fork before the copy).
- A session whose query ended stays active until close: its requests fail
with -32603 and what happened instead of -32002.
- A resume of the active session with other additional directories
restarts it with them at its next turn boundary.
- A replayed tool call without a result ends failed.
- The clear-context prompts get no user_message; the clear-context mode is
resolved at the answer, with no fallback notice.
- No "needs authentication" notice when the session runs MCP OAuth.
Adds a test that pins the runtime export names of `lib.js` and
`acp-agent.js`.
`acp-agent.ts` is about to be split into smaller modules in a series of
pure-move PRs. Each move keeps the old exports as re-exports, because
`"exports": { "./*": "./*" }` lets consumers deep-import
`dist/acp-agent.js`. tsc only catches a missing export that something in
the repo imports; this test catches the rest. The list should change
only on purpose.
## Problem
The Claude Code CLI gives Fable 5.1 a different option value depending
on how the session starts:
- **New session:** listed as `fable` (`resolvedModel:
"claude-fable-5-1"`).
- **Resumed session whose transcript last ran Fable 5.1:** the same row
is listed as `claude-fable-5-1`, and there is no `fable` row.
Reproduced with CLI 2.1.310. Other families don't do this: a session
resumed on `claude-opus-5-5` still lists `opus`.
Clients store the option value as the session's choice. A choice saved
in a new session (`fable`) is not among the options of a resumed one,
and the reverse. A client that checks its saved value against the
options then refuses to apply it, and the model choice keeps flipping
between the two ids.
## Fix
`aliasResumedModelRow` in `session-model.ts` gives the resumed model's
row its family alias back. It changes a row only when:
- the row's value is the model read from the resumed transcript, equals
its own `resolvedModel` and has no context hint,
- no row already has the alias, and
- no newer version of the family is listed, since the alias runs the
family's newest model.
`createSession` applies it before the allowlist and model selection, so
new, resumed and loaded sessions over ACP v1 and v2 all get the same
list.
This is a workaround for the CLI listing the row under a different
value. The CLI also lists rows this way when `ANTHROPIC_MODEL` or
`settings.model` pins `claude-fable-5-1`. Those rows keep the pinned id
on purpose: relabelling them would turn the user's pinned version into
the alias, which moves to a newer Fable when one ships.
## Tests
- `acp-agent-settings.test.ts`: a session resumed on `claude-fable-5-1`
offers `fable` as the current value and option, with no `setModel` call.
Fails without the fix.
- `model-resolution.test.ts`: unit cases for the relabel and for each
case that keeps the list as it is.
- Checked end to end with the real CLI: a Fable turn, then
`session/load`, reports `fable`.
Port the bridge's effort, Fast mode, ultracode and agent options and their set
paths, the refusal fallback notice and model swap, the context window seed
(getContextUsage and the cross-session cache), conversation_reset handling, and
ExitPlanMode's clear-context option to the native v2 core.
The protocol-neutral code moves out of acp-agent.ts into shared modules that
both cores use: session-config-options.ts, session-fast-mode.ts,
context-window.ts, the effort switch helpers in session-effort.ts,
withCurrentModelInfo, and modelRefusalFallback.
The native core continues an accepted clear-context plan with Claude Code's own
/clear on the same query instead of the bridge's fresh query; the client sees
the same updates.
- providers/set, providers/disable and an auth/logout that drops a route
restart each live session's query at its next turn boundary, resuming the
same Claude session, as the bridge does (src/v2-native/restarts.ts).
Prompts sent meanwhile wait and go to the new query.
- The --hide-claude-auth subscription guard holds on the native core, as the
bridge applies it to v2 sessions (src/v2-native/subscription-guard.ts).
- /remote-control is listed and run as a local command of its own turn, and
messages typed in another client show as user messages
(src/v2-native/remote-control.ts). Its helpers move out of acp-agent.ts
into src/remote-control.ts.
- Docs: the gateway login routes only new sessions on the bridge too;
steering is not served to v2 by the bridge either; file change reports are
an AIR extension; the active-resume MCP server and /remote-control
differences are listed as intended.
A child's configuration from its hooks (mode, effort, agent type,
PostModelSwitch) merged with its response models, SendMessage and
SubagentHandback calls as session messages live and in a replay, a
child's tool progress, the replay's notice for missing subagent history,
and the restore of an agent from before a restart from the session's
subagent history, as the bridge does. The hook options and their order
move to subagent-configuration.ts, shared with the v1 core.
- share recordStreamedDelta and unstreamedRemainder (streamed-text.ts) with
the v1 core: a consolidated message adds the tail of a cut-short text block
- after session/cancel, drop the stopped work's consolidated messages except
the results of tool calls the client holds, as the bridge does
- report zero usage and quota on the idle of a prompt's turn without a result
- run acp-v2.test.ts against the native core too, as a vitest project
- End a child's unfinished tool calls before its idle (cancelled, failed,
or dropped before it ran), as v2 asks of updates after a cancel.
- Skip the late result of a dead turn (cancelled after started), and keep
dropping an abandoned prompt's run when another one's cancelled frame comes.
- Send no request of a session after session/close answered.
- Resume of the active session: announce every working child, send each
listed item of a child before its state, and keep live children's states
after a replay.
- Report running again when a cancel's stop or interrupt fails.
- Keep requires_action for an accepted MCP URL elicitation until Claude Code
reports it complete, and only when every foreground subagent is blocked.
- Read the idle's stop reason with the v1 core's rules (shared resultEnd),
map assistant error kinds and the sign-in message like the bridge, and use
model_refusal_no_fallback's explanation.
- Serve SandboxNetworkAccess tool calls, permission_denied, the subject's
_meta (shared permissionToolCallMeta), prePlanMode, the Auto mode fallback,
PostModelSwitch, MCP OAuth after fork, and the stopped-work check for
AskUserQuestion.
- Read the settings file before the settings watchers open (shared
configuredSettings), and forget canUseTool waiters that timed out.