remote_server: Fix panic due to invalid settings access (#41904)

Lukas Wirth created

Closes https://github.com/zed-industries/zed/issues/41860

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/project/src/agent_server_store.rs     | 5 +++--
crates/project/src/environment.rs            | 9 +++++++++
crates/project/src/project.rs                | 8 +++++---
crates/remote_server/src/headless_project.rs | 2 +-
4 files changed, 18 insertions(+), 6 deletions(-)

Detailed changes

crates/project/src/agent_server_store.rs 🔗

@@ -1821,8 +1821,9 @@ mod extension_agent_tests {
         let fs = fs::FakeFs::new(cx.background_executor.clone());
         let http_client = http_client::FakeHttpClient::with_404_response();
         let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
-        let project_environment =
-            cx.new(|cx| crate::ProjectEnvironment::new(None, worktree_store.downgrade(), None, cx));
+        let project_environment = cx.new(|cx| {
+            crate::ProjectEnvironment::new(None, worktree_store.downgrade(), None, false, cx)
+        });
 
         let agent = LocalExtensionArchiveAgent {
             fs,

crates/project/src/environment.rs 🔗

@@ -26,6 +26,7 @@ pub struct ProjectEnvironment {
     environment_error_messages_tx: mpsc::UnboundedSender<String>,
     worktree_store: WeakEntity<WorktreeStore>,
     remote_client: Option<WeakEntity<RemoteClient>>,
+    is_remote_project: bool,
     _tasks: Vec<Task<()>>,
 }
 
@@ -40,6 +41,7 @@ impl ProjectEnvironment {
         cli_environment: Option<HashMap<String, String>>,
         worktree_store: WeakEntity<WorktreeStore>,
         remote_client: Option<WeakEntity<RemoteClient>>,
+        is_remote_project: bool,
         cx: &mut Context<Self>,
     ) -> Self {
         let (tx, mut rx) = mpsc::unbounded();
@@ -60,6 +62,7 @@ impl ProjectEnvironment {
             environment_error_messages_tx: tx,
             worktree_store,
             remote_client,
+            is_remote_project,
             _tasks: vec![task],
         }
     }
@@ -128,6 +131,9 @@ impl ProjectEnvironment {
                     cx,
                 )
             }),
+            None if self.is_remote_project => {
+                Some(self.local_directory_environment(&Shell::System, abs_path, cx))
+            }
             None => Some({
                 let shell = TerminalSettings::get(
                     Some(settings::SettingsLocation {
@@ -160,6 +166,9 @@ impl ProjectEnvironment {
                     cx,
                 )
             }),
+            None if self.is_remote_project => {
+                Some(self.local_directory_environment(&Shell::System, abs_path, cx))
+            }
             None => self
                 .worktree_store
                 .read_with(cx, |worktree_store, cx| {

crates/project/src/project.rs 🔗

@@ -1072,8 +1072,9 @@ impl Project {
             let context_server_store =
                 cx.new(|cx| ContextServerStore::new(worktree_store.clone(), weak_self.clone(), cx));
 
-            let environment =
-                cx.new(|cx| ProjectEnvironment::new(env, worktree_store.downgrade(), None, cx));
+            let environment = cx.new(|cx| {
+                ProjectEnvironment::new(env, worktree_store.downgrade(), None, false, cx)
+            });
             let manifest_tree = ManifestTree::new(worktree_store.clone(), cx);
             let toolchain_store = cx.new(|cx| {
                 ToolchainStore::local(
@@ -1313,6 +1314,7 @@ impl Project {
                     None,
                     worktree_store.downgrade(),
                     Some(remote.downgrade()),
+                    false,
                     cx,
                 )
             });
@@ -1529,7 +1531,7 @@ impl Project {
         })?;
 
         let environment =
-            cx.new(|cx| ProjectEnvironment::new(None, worktree_store.downgrade(), None, cx))?;
+            cx.new(|cx| ProjectEnvironment::new(None, worktree_store.downgrade(), None, true, cx))?;
         let breakpoint_store =
             cx.new(|_| BreakpointStore::remote(remote_id, client.clone().into()))?;
         let dap_store = cx.new(|cx| {

crates/remote_server/src/headless_project.rs 🔗

@@ -95,7 +95,7 @@ impl HeadlessProject {
         });
 
         let environment =
-            cx.new(|cx| ProjectEnvironment::new(None, worktree_store.downgrade(), None, cx));
+            cx.new(|cx| ProjectEnvironment::new(None, worktree_store.downgrade(), None, true, cx));
         let manifest_tree = ManifestTree::new(worktree_store.clone(), cx);
         let toolchain_store = cx.new(|cx| {
             ToolchainStore::local(