zed: Add support for `zed://agent` links (#34862)

Marshall Bowers created

This PR adds support for `zed://agent` links for opening the Agent
Panel.

Release Notes:

- N/A

Change summary

crates/zed/src/main.rs              | 15 ++++++++++++++-
crates/zed/src/zed/open_listener.rs |  3 +++
2 files changed, 17 insertions(+), 1 deletion(-)

Detailed changes

crates/zed/src/main.rs 🔗

@@ -1,6 +1,7 @@
 mod reliability;
 mod zed;
 
+use agent_ui::AgentPanel;
 use anyhow::{Context as _, Result};
 use clap::{Parser, command};
 use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
@@ -14,7 +15,7 @@ use extension_host::ExtensionStore;
 use fs::{Fs, RealFs};
 use futures::{StreamExt, channel::oneshot, future};
 use git::GitHostingProviderRegistry;
-use gpui::{App, AppContext as _, Application, AsyncApp, UpdateGlobal as _};
+use gpui::{App, AppContext as _, Application, AsyncApp, Focusable as _, UpdateGlobal as _};
 
 use gpui_tokio::Tokio;
 use http_client::{Url, read_proxy_from_env};
@@ -771,6 +772,18 @@ fn handle_open_request(request: OpenRequest, app_state: Arc<AppState>, cx: &mut
                 })
                 .detach_and_log_err(cx);
             }
+            OpenRequestKind::AgentPanel => {
+                cx.spawn(async move |cx| {
+                    let workspace =
+                        workspace::get_any_active_workspace(app_state, cx.clone()).await?;
+                    workspace.update(cx, |workspace, window, cx| {
+                        if let Some(panel) = workspace.panel::<AgentPanel>(cx) {
+                            panel.focus_handle(cx).focus(window);
+                        }
+                    })
+                })
+                .detach_and_log_err(cx);
+            }
             OpenRequestKind::DockMenuAction { index } => {
                 cx.perform_dock_menu_action(index);
             }

crates/zed/src/zed/open_listener.rs 🔗

@@ -42,6 +42,7 @@ pub struct OpenRequest {
 pub enum OpenRequestKind {
     CliConnection((mpsc::Receiver<CliRequest>, IpcSender<CliResponse>)),
     Extension { extension_id: String },
+    AgentPanel,
     DockMenuAction { index: usize },
 }
 
@@ -66,6 +67,8 @@ impl OpenRequest {
                 this.kind = Some(OpenRequestKind::Extension {
                     extension_id: extension_id.to_string(),
                 });
+            } else if url == "zed://agent" {
+                this.kind = Some(OpenRequestKind::AgentPanel);
             } else if url.starts_with("ssh://") {
                 this.parse_ssh_file_path(&url, cx)?
             } else if let Some(request_path) = parse_zed_link(&url, cx) {