From da0d02a7cd15c6924b85d631973bff95bf60395c Mon Sep 17 00:00:00 2001 From: Michael Atwood <70112949+doowta@users.noreply.github.com> Date: Thu, 22 Oct 2026 02:39:22 -0500 Subject: [PATCH] Agent: offer Open folder only for a project on this computer While the app was connected to a paired computer, that computer's project menu still offered Open folder. The folder is revealed by this computer's file manager, so it opened a local folder that happened to share the path, or failed when there was none. The menu now offers it only while the app is on this computer, whose projects are the only ones the local file manager can show. Rename, Trust and Remove go through the connected computer and are unchanged. Co-Authored-By: Claude Opus 5.5 --- apps/maple-agent/app/src/backend.rs | 8 +++++ apps/maple-agent/app/src/ui/chat/sidebar.rs | 18 ++++++----- apps/maple-agent/app/src/ui/chat/tests.rs | 34 +++++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/apps/maple-agent/app/src/backend.rs b/apps/maple-agent/app/src/backend.rs index 717407fa6..31a0e26c2 100644 --- a/apps/maple-agent/app/src/backend.rs +++ b/apps/maple-agent/app/src/backend.rs @@ -303,6 +303,14 @@ impl AgentBackend { } } + /// A UI test backend that reports itself as connected to `peer`. + #[cfg(test)] + pub fn remote_for_test(peer: &str) -> Result { + let mut backend = Self::for_test("http://127.0.0.1:9".into(), String::new())?; + backend.remote_host = Some(peer.to_string()); + Ok(backend) + } + pub fn new(api_url: String, _harness_instructions: String) -> Result { let api_url = maple_agent::maple_api::validate_api_url(&api_url)?; let runtime = Runtime::new().map_err(|e| format!("Could not start host client: {e}"))?; diff --git a/apps/maple-agent/app/src/ui/chat/sidebar.rs b/apps/maple-agent/app/src/ui/chat/sidebar.rs index c1c4b7da0..ca644749c 100644 --- a/apps/maple-agent/app/src/ui/chat/sidebar.rs +++ b/apps/maple-agent/app/src/ui/chat/sidebar.rs @@ -2023,14 +2023,18 @@ impl Sidebar { if target.computer.as_deref() != self.backend.remote_host() { return items; } - let open_root = root.clone(); let remove_root = root.clone(); - items.push(SidebarMenuItem { - id: target.element_id("open-project"), - icon: "folder-open", - label: "Open folder", - on_click: Box::new(move |this, cx| this.open_folder(&open_root, cx)), - }); + // The file manager runs on this computer, so a paired computer's + // folder cannot be revealed from here. + if self.backend.remote_host().is_none() { + let open_root = root.clone(); + items.push(SidebarMenuItem { + id: target.element_id("open-project"), + icon: "folder-open", + label: "Open folder", + on_click: Box::new(move |this, cx| this.open_folder(&open_root, cx)), + }); + } if let Some(status) = self .menu_trust .as_ref() diff --git a/apps/maple-agent/app/src/ui/chat/tests.rs b/apps/maple-agent/app/src/ui/chat/tests.rs index 1dd1eaf02..d8527de81 100644 --- a/apps/maple-agent/app/src/ui/chat/tests.rs +++ b/apps/maple-agent/app/src/ui/chat/tests.rs @@ -6333,6 +6333,40 @@ mod state_tests { ); }); } + /// The file manager runs on this computer: a project on a paired + /// computer never offers "Open folder", even while that computer is + /// the active one. + #[gpui::test] + fn only_a_local_project_offers_open_folder(cx: &mut TestAppContext) { + cx.executor().allow_parking(); + for (backend, computer) in [ + ( + crate::backend::AgentBackend::for_test("http://127.0.0.1:9".into(), String::new()), + None, + ), + ( + crate::backend::AgentBackend::remote_for_test("east"), + Some("east"), + ), + ] { + let backend = Arc::new(backend.expect("backend")); + let chat = cx.new(|cx| { + let _guard = SETTINGS_LOCK.lock(); + ChatScreen::new_without_start(backend, "user".to_string(), cx) + }); + chat.update(cx, |this, cx| { + let menu = this + .sidebar + .read(cx) + .project_menu_labels_for_test(&ProjectTarget { + computer: computer.map(str::to_string), + path: "/shared".into(), + }); + assert_eq!(menu.contains(&"Open folder"), computer.is_none()); + assert!(menu.contains(&"Remove project")); + }); + } + } #[gpui::test] fn inactive_project_rename_previews_and_failures_are_isolated_by_computer(