Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nori-rs/acp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ diffy = { workspace = true }
chrono = { workspace = true }
uuid = { workspace = true, features = ["v4"] }
sha2 = { workspace = true }
which = { workspace = true }

[target.'cfg(unix)'.dependencies]
libc = { workspace = true }
Expand Down
10 changes: 5 additions & 5 deletions nori-rs/acp/src/config/types/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ name = "Claude Code"
slug = "claude-code"

[agents.distribution.npx]
package = "@zed-industries/claude-agent-acp"
package = "@agentclientprotocol/claude-agent-acp"
"#,
)
.unwrap();
Expand All @@ -1033,7 +1033,7 @@ package = "@zed-industries/claude-agent-acp"
assert!(config.agents[0].distribution.npx.is_some());
assert_eq!(
config.agents[0].distribution.npx.as_ref().unwrap().package,
"@zed-industries/claude-agent-acp"
"@agentclientprotocol/claude-agent-acp"
);
}

Expand Down Expand Up @@ -1130,7 +1130,7 @@ name = "Claude Code"
slug = "claude-code"

[agents.distribution.npx]
package = "@zed-industries/claude-agent-acp"
package = "@agentclientprotocol/claude-agent-acp"

[[agents]]
name = "Kimi"
Expand Down Expand Up @@ -1217,15 +1217,15 @@ fn test_agent_distribution_resolve_rejects_multiple() {
fn test_agent_distribution_resolve_npx() {
let dist = AgentDistributionToml {
npx: Some(PackageDistribution {
package: "@zed-industries/claude-agent-acp".to_string(),
package: "@agentclientprotocol/claude-agent-acp".to_string(),
args: vec![],
}),
..Default::default()
};
let resolved = dist.resolve().unwrap();
assert!(matches!(resolved, ResolvedDistribution::Npx { .. }));
if let ResolvedDistribution::Npx { package, args } = resolved {
assert_eq!(package, "@zed-industries/claude-agent-acp");
assert_eq!(package, "@agentclientprotocol/claude-agent-acp");
assert!(args.is_empty());
}
}
Expand Down
29 changes: 23 additions & 6 deletions nori-rs/acp/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ impl AgentKind {
/// Get the ACP adapter package name for launching this agent
pub fn acp_package(&self) -> &'static str {
match self {
// Claude and Codex use Zed's ACP adapters
AgentKind::ClaudeCode => "@zed-industries/claude-agent-acp",
// @latest forces bunx to resolve the new scope instead of a stale
// @zed-industries cache entry with the same unscoped package name.
AgentKind::ClaudeCode => "@agentclientprotocol/claude-agent-acp@latest",
// Codex uses Zed's ACP adapter
AgentKind::Codex => "@zed-industries/codex-acp",
// Gemini has native ACP support
AgentKind::Gemini => "@google/gemini-cli",
Expand Down Expand Up @@ -703,7 +705,7 @@ pub fn get_agent_config(agent_name: &str) -> Result<AcpAgentConfig> {
let package_manager = detect_preferred_package_manager();

let (command, args) = match agent {
// Claude and Codex use Zed's ACP adapters
// Claude and Codex use external ACP adapters
AgentKind::ClaudeCode | AgentKind::Codex => (
package_manager.command().to_string(),
vec![agent.acp_package().to_string()],
Expand All @@ -718,12 +720,28 @@ pub fn get_agent_config(agent_name: &str) -> Result<AcpAgentConfig> {
),
};

// Workaround: the v0.30.0+ Claude ACP adapter resolves its native
// binary via require.resolve() on platform-specific optional deps.
// On glibc Linux, bunx installs both musl and glibc variants; the
// adapter tries musl first, require.resolve succeeds (file exists),
// but execution fails (no musl loader). Point CLAUDE_CODE_EXECUTABLE
// at the system binary to bypass the broken resolution.
let mut env = HashMap::new();
if agent == AgentKind::ClaudeCode
&& let Ok(path) = which::which("claude")
{
env.insert(
"CLAUDE_CODE_EXECUTABLE".to_string(),
path.to_string_lossy().to_string(),
);
}

return Ok(AcpAgentConfig {
agent,
provider_slug: agent.slug().to_string(),
command,
args,
env: HashMap::new(),
env,
provider_info: AcpProviderInfo {
name: format!("{} ACP", agent.display_name()),
..Default::default()
Expand Down Expand Up @@ -999,11 +1017,10 @@ mod tests {
"Command should be npx or bunx, got: {}",
config.command
);
// Uses Zed's ACP adapter
assert!(
config
.args
.contains(&"@zed-industries/claude-agent-acp".to_string())
.contains(&"@agentclientprotocol/claude-agent-acp@latest".to_string())
);
assert_eq!(config.provider_info.name, "Claude Code ACP");
}
Expand Down
Loading