## Motivation ACP clients currently have two gaps when rendering Claude Code activity: 1. Bash tool calls expose the shell command as the standard ACP title, but the concise human-readable `description` produced by Claude Code is lost. 2. ACP 1.2 has no standard subagent tool kind or nested-message relationship, so subagent prose and child tools are either flattened into the main conversation or filtered out entirely. This PR adds namespaced metadata and an explicit client capability so richer clients can render both cases without changing the standard ACP schema or regressing legacy clients. ## What changed ### Bash descriptions - Keeps the shell command in the standard ACP `title`, preserving command-oriented clients. - Exposes the optional Claude Code Bash `description` as `_meta.claudeCode.title`. - Applies the metadata consistently to eager permission tool calls, normal tool calls, and streamed input refinements. - Falls back to the command title when no description is available. ### Nested subagent transcripts - Adds the opt-in client capability `clientCapabilities._meta["subagent-transcript"] = true`. - Enables the Claude Agent SDK `forwardSubagentText` option when the client advertises support. - Preserves the pre-existing caller-provided `forwardSubagentText: true` option for compatibility. - Marks Agent and legacy Task launches with `_meta.claudeCode.subagent = true`. - Relates nested text, thinking, and child tool calls to the launching Agent/Task call through `_meta.claudeCode.parentToolUseId`. - Preserves parent attribution during session-history replay, not only during live streaming. - Handles nested Agent-to-Agent launches without inferring subagents from the generic ACP `think` kind. ## Compatibility Clients that do not advertise `subagent-transcript` retain the previous behavior: subagent text and thinking remain filtered from the top-level feed. The normal Agent/Task tool result is still emitted in every mode as the protocol-compatible fallback. No existing result or standard ACP field is removed or redefined. ## Validation - `npm run build` - `npm run check` - `npm run test:run` - 623 tests passed, 20 skipped Coverage includes live and replayed nested text/thinking, child tool attribution, Agent/Task launch markers, nested Agent launches, legacy filtering, and SDK-option compatibility.
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
Learn more about the Agent Client Protocol.
Nested subagent transcripts
ACP 1.2 has no standard subagent tool kind or nested-message relationship. Clients that can render
nested transcripts can opt in with clientCapabilities._meta["subagent-transcript"] = true.
The agent then forwards subagent text, thinking, and tool calls, relating nested updates to the
launching Agent/Task call through _meta.claudeCode.parentToolUseId. Agent/Task calls are marked
with _meta.claudeCode.subagent = true.
Clients that do not advertise the capability retain the legacy flattened behavior. In both modes, the normal Agent/Task tool result is preserved as the protocol-compatible fallback.
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).