From 9a14ca8c5df7187aa8f499399773b252513da681 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 efde6c65e5ffa653c1515230fd863a3bacb7e6f7..952f046bdc3ee8a53c00160831fe6f57b014ee9c 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));