v2's foreground work reported `requires_action` whenever any permission request or question in the session was open, including a background subagent's. The draft keeps `requires_action` for foreground work that is blocked on user action, and a background subagent asks without blocking the main conversation. So a v2 client saw a running turn as waiting on the user while it kept working. ## What changes A request blocks the foreground work when it is: - the main conversation's own request, or - the request of a subagent that runs in the foreground of the main conversation, so the tool call that spawned it waits on it. This applies up a chain of such subagents. A request from a subagent in the background, or from one nested inside it, no longer counts. - **Where each task runs.** The adapter records this per task: - from `task_started.is_backgrounded` and `parent_task_id`; - from a later `task_updated` patch that moves the task to the background; - Claude Code always resumes a subagent in the background. - **Unknown subagents.** A subagent without a record still counts, because its request can arrive before its `task_started`. Registering a task, or moving one to the background, checks the open requests again. - **Requests that name no agent** still count: MCP elicitations and dialogs. - **Steering is unchanged.** It still treats any open request as blocking. `Session.pendingUserInputCount` becomes `Session.openUserInputs`: the open requests, each with the subagent that asked. - **v1 is unchanged.** ## Evidence - **Live, CLI 2.1.293 via the SDK with a logging `canUseTool`:** - `task_started` carries `is_backgrounded: true` for a background subagent and `false` for a foreground one. - A subagent's `canUseTool` call carries `agentID` equal to its `task_started.task_id`. - `task_started` arrived before the subagent's request in both cases. - `parent_task_id` for nested subagents was not checked live; it's documented in the SDK types and covered by a test. - **6 new v2 tests:** - a background subagent's permission request leaves the turn `running`, and so does its question; - a foreground subagent's request reports `requires_action`; - a foreground subagent launched by a background one doesn't block; - a request that arrives before its subagent's `task_started` stops blocking once the subagent turns out to run in the background; - a request stops blocking once Claude Code moves its subagent to the background. - **Mutation checks.** Removing each rule in turn fails at least one test. That includes passing the subagent through for permission requests and for questions, the recheck at registration and at `task_updated`, and the walk up the chain. - `npm run check`, build and the full suite pass, with no golden file changes. Two resume tests now expect the resumed task to be recorded as backgrounded.
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)
- Compact file changes through the negotiated AIR diff patch extension
- Following
- Edit review
- TODO lists
- Nested subagent transcripts
- Interactive (and background) terminals
- Custom Slash commands
- Client MCP servers
/mcpin the chat: the MCP server status as a list. The adapter runs/mcp reconnect,/mcp enable, and/mcp disablethrough the SDK control API, because Claude Code refuses them in SDK mode. A reconnect of an ACP server that needs authentication starts MCP OAuth through URL elicitation- Session-scoped long-running goals for AIR through the goal extension under
_meta.jetbrains.air.goal - 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
- One fact per field in every tool call report, as the ACP tool call contract defines
- All AIR extensions, capabilities, and
_metakeys: AIR extensions
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. See AIR extensions.
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).