From e9b4f59e0f2b732424d830b3c49119fd3c233b59 Mon Sep 17 00:00:00 2001 From: Hakan Ensari Date: Mon, 15 Sep 2025 12:20:27 +0200 Subject: [PATCH] Fix external agent authentication with spaces in paths (#38175) This fixes terminal-based authentication for external ACP agents (Claude Code, Gemini CLI) when file paths contain spaces, like "Application Support" on macOS and "Program Files" on Windows. When users click authentication buttons or type `/login`, they get errors like `Cannot find module '/Users/username/Library/Application'` because the path gets split at the space. The fix removes redundant `shlex::try_quote` calls from `spawn_external_agent_login`. These were causing double-quoting since the terminal spawning code already handles proper shell escaping. Added a test to verify paths with spaces aren't pre-quoted. Release Notes: - Fixed external agent authentication failures when file paths contain spaces --------- Co-authored-by: Hakan Ensari Co-authored-by: Claude --- Cargo.lock | 1 - crates/agent_ui/Cargo.toml | 1 - crates/agent_ui/src/acp/thread_view.rs | 32 +++++++++++++++----------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14ec0e21db..2b01b45f63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,7 +416,6 @@ dependencies = [ "serde_json", "serde_json_lenient", "settings", - "shlex", "smol", "streaming_diff", "task", diff --git a/crates/agent_ui/Cargo.toml b/crates/agent_ui/Cargo.toml index 028db95c10..47d9f6d6a2 100644 --- a/crates/agent_ui/Cargo.toml +++ b/crates/agent_ui/Cargo.toml @@ -80,7 +80,6 @@ serde.workspace = true serde_json.workspace = true serde_json_lenient.workspace = true settings.workspace = true -shlex.workspace = true smol.workspace = true streaming_diff.workspace = true task.workspace = true diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index d3986155d7..ceed3f8f98 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -9,7 +9,7 @@ use agent_client_protocol::{self as acp, PromptCapabilities}; use agent_servers::{AgentServer, AgentServerDelegate}; use agent_settings::{AgentProfileId, AgentSettings, CompletionMode, NotifyWhenAgentWaiting}; use agent2::{DbThreadMetadata, HistoryEntry, HistoryEntryId, HistoryStore, NativeAgentServer}; -use anyhow::{Context as _, Result, anyhow, bail}; +use anyhow::{Result, anyhow, bail}; use arrayvec::ArrayVec; use audio::{Audio, Sound}; use buffer_diff::BufferDiff; @@ -1584,19 +1584,6 @@ impl AcpThreadView { window.spawn(cx, async move |cx| { let mut task = login.clone(); - task.command = task - .command - .map(|command| anyhow::Ok(shlex::try_quote(&command)?.to_string())) - .transpose()?; - task.args = task - .args - .iter() - .map(|arg| { - Ok(shlex::try_quote(arg) - .context("Failed to quote argument")? - .to_string()) - }) - .collect::>>()?; task.full_label = task.label.clone(); task.id = task::TaskId(format!("external-agent-{}-login", task.label)); task.command_label = task.label.clone(); @@ -5680,6 +5667,23 @@ pub(crate) mod tests { }); } + #[gpui::test] + async fn test_spawn_external_agent_login_handles_spaces(cx: &mut TestAppContext) { + init_test(cx); + + // Verify paths with spaces aren't pre-quoted + let path_with_spaces = "/Users/test/Library/Application Support/Zed/cli.js"; + let login_task = task::SpawnInTerminal { + command: Some("node".to_string()), + args: vec![path_with_spaces.to_string(), "/login".to_string()], + ..Default::default() + }; + + // Args should be passed as-is, not pre-quoted + assert!(!login_task.args[0].starts_with('"')); + assert!(!login_task.args[0].starts_with('\'')); + } + #[gpui::test] async fn test_notification_for_tool_authorization(cx: &mut TestAppContext) { init_test(cx);