agent_servers: Expand `~` in path from settings (#41602)

Bennet Bo Fenner created

Closes #40796


Release Notes:

- Fixed an issue where `~` would not be expanded when specifiying the
path of an ACP server

Change summary

crates/project/src/agent_server_store.rs | 42 ++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 2 deletions(-)

Detailed changes

crates/project/src/agent_server_store.rs 🔗

@@ -1638,7 +1638,9 @@ impl BuiltinAgentServerSettings {
 impl From<settings::BuiltinAgentServerSettings> for BuiltinAgentServerSettings {
     fn from(value: settings::BuiltinAgentServerSettings) -> Self {
         BuiltinAgentServerSettings {
-            path: value.path,
+            path: value
+                .path
+                .map(|p| PathBuf::from(shellexpand::tilde(&p.to_string_lossy()).as_ref())),
             args: value.args,
             env: value.env,
             ignore_system_version: value.ignore_system_version,
@@ -1673,7 +1675,7 @@ impl From<settings::CustomAgentServerSettings> for CustomAgentServerSettings {
     fn from(value: settings::CustomAgentServerSettings) -> Self {
         CustomAgentServerSettings {
             command: AgentServerCommand {
-                path: value.path,
+                path: PathBuf::from(shellexpand::tilde(&value.path.to_string_lossy()).as_ref()),
                 args: value.args,
                 env: value.env,
             },
@@ -1893,4 +1895,40 @@ mod extension_agent_tests {
         let target = manifest_entry.targets.get("linux-x86_64").unwrap();
         assert_eq!(target.cmd, "./release-agent");
     }
+
+    #[test]
+    fn test_tilde_expansion_in_settings() {
+        let settings = settings::BuiltinAgentServerSettings {
+            path: Some(PathBuf::from("~/bin/agent")),
+            args: Some(vec!["--flag".into()]),
+            env: None,
+            ignore_system_version: None,
+            default_mode: None,
+        };
+
+        let BuiltinAgentServerSettings { path, .. } = settings.into();
+
+        let path = path.unwrap();
+        assert!(
+            !path.to_string_lossy().starts_with("~"),
+            "Tilde should be expanded for builtin agent path"
+        );
+
+        let settings = settings::CustomAgentServerSettings {
+            path: PathBuf::from("~/custom/agent"),
+            args: vec!["serve".into()],
+            env: None,
+            default_mode: None,
+        };
+
+        let CustomAgentServerSettings {
+            command: AgentServerCommand { path, .. },
+            ..
+        } = settings.into();
+
+        assert!(
+            !path.to_string_lossy().starts_with("~"),
+            "Tilde should be expanded for custom agent path"
+        );
+    }
 }