diff --git a/crates/agent_servers/src/acp.rs b/crates/agent_servers/src/acp.rs index 7991c1e3ccedafe8891ef80c57c4939bb19d2fb1..9386a9493df021e09a6e868536b9a9fb8db32391 100644 --- a/crates/agent_servers/src/acp.rs +++ b/crates/agent_servers/src/acp.rs @@ -9,6 +9,7 @@ use futures::AsyncBufReadExt as _; use futures::io::BufReader; use project::Project; use serde::Deserialize; +use util::ResultExt as _; use std::{any::Any, cell::RefCell}; use std::{path::Path, rc::Rc}; @@ -29,6 +30,11 @@ pub struct AcpConnection { sessions: Rc>>, auth_methods: Vec, agent_capabilities: acp::AgentCapabilities, + default_mode: Option, + root_dir: PathBuf, + // NB: Don't move this into the wait_task, since we need to ensure the process is + // killed on drop (setting kill_on_drop on the command seems to not always work). + child: smol::process::Child, _io_task: Task>, _wait_task: Task>, _stderr_task: Task>, @@ -64,9 +70,11 @@ impl AcpConnection { .current_dir(root_dir) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) - .stderr(std::process::Stdio::piped()) - .kill_on_drop(true) - .spawn()?; + .stderr(std::process::Stdio::piped()); + if !is_remote { + child.current_dir(root_dir); + } + let mut child = child.spawn()?; let stdout = child.stdout.take().context("Failed to take stdout")?; let stdin = child.stdin.take().context("Failed to take stdin")?; @@ -102,8 +110,9 @@ impl AcpConnection { let wait_task = cx.spawn({ let sessions = sessions.clone(); + let status_fut = child.status(); async move |cx| { - let status = child.status().await?; + let status = status_fut.await?; for session in sessions.borrow().values() { session @@ -152,6 +161,7 @@ impl AcpConnection { _io_task: io_task, _wait_task: wait_task, _stderr_task: stderr_task, + child, }) } @@ -160,6 +170,13 @@ impl AcpConnection { } } +impl Drop for AcpConnection { + fn drop(&mut self) { + // See the comment on the child field. + self.child.kill().log_err(); + } +} + impl AgentConnection for AcpConnection { fn new_thread( self: Rc,