From bbaf7045995a0dba994580d958e89a0029f047dd 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 d82d176c381bb1e6cbb9bc25c16cec9da21a1a64..589633ae250580f6eb66a513534c79a898fdc0d6 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -432,11 +432,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));