Fixes #1167. ## Problem In plan mode the model often runs Explore agents in the background. The user turn's result then comes back while those agents are still running, so `session/prompt` is held open (#864/#866). When an agent finishes, the model writes the plan and calls `ExitPlanMode` in the **task-notification followup**. The user accepts it with a clear-context option. The interrupted cycle's `[ede_diagnostic] … stop_reason=tool_use` result carries that cycle's `task-notification` origin. That sends it into the autonomous-result branch, which: 1. sends the `usage_update` with `_claude/origin: task-notification`. This is the "background task finished at the same time" update from the report; it's actually the same cycle. 2. settles the held turn with `end_turn` and returns early, before the ExitPlanMode restart check runs. The plan is never continued, the mode stays `plan`, and nothing tells the client. ## Fix - The diagnostic match now lives in one shared function, `isExitPlanInterruptionResult()` in `exit-plan.ts`. Both the user-result path and the new check call it; the user path behaves as before. - In the autonomous branch, when the active turn is held and the result is the recorded ExitPlanMode interruption: - **Clear-context option:** drop the held turn's stored outcome, then run the usual fresh-context restart. The fresh query doesn't have the old background tasks, so the stale hold would otherwise settle the moved turn with `end_turn` before the plan runs. The continuation's own result settles the turn. - **"No, keep planning":** settle `cancelled` with the user turn's own usage, through `settleOrDefer`, so the turn stays open while other spawned subagents are still running. ## Tests There are two new tests in the deferred-settlement block. Each runs a held turn whose task-notification followup calls `ExitPlanMode`: one for the clear-context restart, one for keep-planning. The restart test also fails if the held outcome isn't dropped. ## Known limitations (unchanged by this PR) - **Background agents are killed by the restart.** Upstream `/clear` keeps background agent tasks running (`hasAgentTaskSurvivingClear`). The adapter's restart closes the old query, so any other running subagents are killed, just as on the existing user-turn restart path. - **Plans approved after the turn has ended are still dropped.** If `ExitPlanMode` runs after the turn has already settled, there's no open turn to continue, and the plan is dropped as before. A client-visible notice for that case would be a follow-up. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ACP adapter for the Claude Agent SDK
Use Claude Agent SDK from ACP-compatible clients!
This tool implements an ACP agent by using the official Claude Agent SDK, supporting:
- Context @-mentions
- Images
- Tool calls (with permission requests)
- Following
- Edit review
- TODO lists
- Nested subagent transcripts
- Interactive (and background) terminals
- Custom Slash commands
- Client MCP servers
- Session-scoped long-running goals through the provider-neutral goal extension
- Structured errors, recovery, and warnings through the opt-in session failure extension
- Concrete model and effort defaults through the opt-in recommended config value extension
- Tool permission presentation, editable choices, and durable effects through the permission extension
Learn more about the Agent Client Protocol.
To try changes that have landed on main but are not released yet, install from the
preview channel — every push to main publishes one. See
docs/RELEASES.md.
npm install @agentclientprotocol/claude-agent-acp@preview
Subagent sessions
Subagents are exposed only after bilateral capability negotiation. Until the released ACP SDKs
preserve the draft clientCapabilities.subagents field, a supporting client may advertise
nativeSubagentSessions in _meta.jetbrains.air.capabilities; the adapter mirrors the capability
in its initialize response. The canonical field remains supported and takes precedence once it is
available. Without either client signal, Agent/Task lifecycle keeps its legacy ordinary ACP
tool-call representation and child interactions stay on the root session. Clients that use the
historical _meta["subagent-transcript"] capability or forwardSubagentText session option retain
the flattened child transcript behavior.
Contribution Policy
This project does not require a Contributor License Agreement (CLA). Instead, contributions are accepted under the following terms:
By contributing to this project, you agree that your contributions will be licensed under the Apache License, Version 2.0. You affirm that you have the legal right to submit your work, that you are not including code you do not have rights to, and that you understand contributions are made without requiring a Contributor License Agreement (CLA).