From ae840c6ef39007bd00ef8f63161825bd18cdcc50 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Wed, 3 Sep 2025 03:40:14 -0400 Subject: [PATCH] acp: Fix handling of single-file worktrees (#37412) When the first visible worktree is a single-file worktree, we would previously try to use the absolute path of that file as the root directory for external agents, causing an error. This PR changes how we handle this situation: we'll use the root of the first non-single-file visible worktree if there are any, and if there are none, the parent directory of the first single-file visible worktree. Related to #37213 Release Notes: - acp: Fixed being unable to run external agents when a single file (not part of a project) was opened in Zed. --- crates/agent_ui/src/acp/thread_view.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 60b3166a57aebc02fba82d4b350de0e48b84ef94..bf981d10f7685c64f8c3e8c03895dda8c5d839eb 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -427,11 +427,24 @@ impl AcpThreadView { "External agents are not yet supported for remote projects.".into(), )); } - let root_dir = project - .read(cx) - .visible_worktrees(cx) + let mut worktrees = project.read(cx).visible_worktrees(cx).collect::>(); + // Pick the first non-single-file worktree for the root directory if there are any, + // and otherwise the parent of a single-file worktree, falling back to $HOME if there are no visible worktrees. + worktrees.sort_by(|l, r| { + l.read(cx) + .is_single_file() + .cmp(&r.read(cx).is_single_file()) + }); + let root_dir = worktrees + .into_iter() + .filter_map(|worktree| { + if worktree.read(cx).is_single_file() { + Some(worktree.read(cx).abs_path().parent()?.into()) + } else { + Some(worktree.read(cx).abs_path()) + } + }) .next() - .map(|worktree| worktree.read(cx).abs_path()) .unwrap_or_else(|| paths::home_dir().as_path().into()); let (tx, mut rx) = watch::channel("Loading…".into()); let delegate = AgentServerDelegate::new(project.clone(), Some(tx));