wip

Richard Feldman created

Change summary

crates/agent_servers/src/claude.rs | 18 ++++++++++++++++++
crates/agent_servers/src/custom.rs | 25 ++++++++++++++++++++++---
crates/agent_servers/src/gemini.rs | 22 ++++++++++++++++++----
3 files changed, 58 insertions(+), 7 deletions(-)

Detailed changes

crates/agent_servers/src/claude.rs 🔗

@@ -82,6 +82,13 @@ impl AgentServer for ClaudeCode {
             settings.get::<AllAgentServersSettings>(None).claude.clone()
         });
 
+        dbg!(&root_dir);
+
+        // Get the project environment variables for the root directory
+        let project_env = delegate.project().update(cx, |project, cx| {
+            project.directory_environment(root_dir.as_path().into(), cx)
+        });
+
         cx.spawn(async move |cx| {
             let mut command = if let Some(settings) = settings {
                 settings.command
@@ -99,6 +106,17 @@ impl AgentServer for ClaudeCode {
                 .await?
             };
 
+            // Merge project environment variables (from .env files, etc.)
+            if let Some(env) = dbg!(project_env.await) {
+                if let Some(command_env) = &mut command.env {
+                    command_env.extend(
+                        env.iter()
+                            .map(|(key, val)| dbg!((key.clone(), val.clone()))),
+                    );
+                }
+            }
+
+            // Add the API key if available (project-specific env may override this)
             if let Some(api_key) = cx
                 .update(AnthropicLanguageModelProvider::api_key)?
                 .await

crates/agent_servers/src/custom.rs 🔗

@@ -33,13 +33,32 @@ impl crate::AgentServer for CustomAgentServer {
     fn connect(
         &self,
         root_dir: &Path,
-        _delegate: AgentServerDelegate,
+        delegate: AgentServerDelegate,
         cx: &mut App,
     ) -> Task<Result<Rc<dyn AgentConnection>>> {
         let server_name = self.name();
-        let command = self.command.clone();
+        let mut command = self.command.clone();
         let root_dir = root_dir.to_path_buf();
-        cx.spawn(async move |cx| crate::acp::connect(server_name, command, &root_dir, cx).await)
+
+        // Get the project environment variables for the root directory
+        let project_env = delegate.project().update(cx, |project, cx| {
+            project.directory_environment(root_dir.as_path().into(), cx)
+        });
+
+        cx.spawn(async move |cx| {
+            // Start with project environment variables (from shell, .env files, etc.)
+            let mut env = project_env.await.unwrap_or_default();
+
+            // Merge with any existing command env (command env takes precedence)
+            if let Some(command_env) = &command.env {
+                env.extend(command_env.clone());
+            }
+
+            // Set the merged environment back on the command
+            command.env = Some(env);
+
+            crate::acp::connect(server_name, command, &root_dir, cx).await
+        })
     }
 
     fn into_any(self: Rc<Self>) -> Rc<dyn std::any::Any> {

crates/agent_servers/src/gemini.rs 🔗

@@ -42,6 +42,11 @@ impl AgentServer for Gemini {
             settings.get::<AllAgentServersSettings>(None).gemini.clone()
         });
 
+        // Get the project environment variables for the root directory
+        let project_env = delegate.project().update(cx, |project, cx| {
+            project.directory_environment(root_dir.as_path().into(), cx)
+        });
+
         cx.spawn(async move |cx| {
             let ignore_system_version = settings
                 .as_ref()
@@ -68,13 +73,22 @@ impl AgentServer for Gemini {
                 command.args.push(ACP_ARG.into());
             }
 
+            // Start with project environment variables (from shell, .env files, etc.)
+            let mut env = project_env.await.unwrap_or_default();
+
+            // Add the API key if available (this takes precedence over project env)
             if let Some(api_key) = cx.update(GoogleLanguageModelProvider::api_key)?.await.ok() {
-                command
-                    .env
-                    .get_or_insert_default()
-                    .insert("GEMINI_API_KEY".to_owned(), api_key.key);
+                env.insert("GEMINI_API_KEY".to_owned(), api_key.key);
             }
 
+            // Merge with any existing command env (command env takes precedence)
+            if let Some(command_env) = &command.env {
+                env.extend(command_env.clone());
+            }
+
+            // Set the merged environment back on the command
+            command.env = Some(env);
+
             let root_dir_exists = fs.is_dir(&root_dir).await;
             anyhow::ensure!(
                 root_dir_exists,