diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 9d23eeb8cde071e20e5d3e4d7f873b1f668501b2..fe65a53aa70522ff48728d3eaded16ac3312f2e0 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -313,7 +313,7 @@ "use_key_equivalents": true, "bindings": { "cmd-n": "agent::NewTextThread", - "cmd-alt-t": "agent::NewThread" + "cmd-alt-n": "agent::NewExternalAgentThread" } }, { diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index d4138aa5bdf8f3731df7508ab8d6476455aca11b..dfc4d27e1153c61dc07c00a807c958f69db77b5a 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -1892,6 +1892,9 @@ impl AgentPanel { .anchor(Corner::TopRight) .with_handle(self.new_thread_menu_handle.clone()) .menu({ + let selected_agent = self.selected_agent.clone(); + let is_agent_selected = move |agent_type: AgentType| selected_agent == agent_type; + let workspace = self.workspace.clone(); let is_via_collab = workspace .update(cx, |workspace, cx| { @@ -1929,7 +1932,9 @@ impl AgentPanel { }) .item( ContextMenuEntry::new("Zed Agent") - .action(NewThread.boxed_clone()) + .when(is_agent_selected(AgentType::NativeAgent) | is_agent_selected(AgentType::TextThread) , |this| { + this.action(Box::new(NewExternalAgentThread { agent: None })) + }) .icon(IconName::ZedAgent) .icon_color(Color::Muted) .handler({ @@ -1955,9 +1960,9 @@ impl AgentPanel { ) .item( ContextMenuEntry::new("Text Thread") + .action(NewTextThread.boxed_clone()) .icon(IconName::TextThread) .icon_color(Color::Muted) - .action(NewTextThread.boxed_clone()) .handler({ let workspace = workspace.clone(); move |window, cx| { @@ -1983,6 +1988,9 @@ impl AgentPanel { .header("External Agents") .item( ContextMenuEntry::new("Claude Code") + .when(is_agent_selected(AgentType::ClaudeCode), |this| { + this.action(Box::new(NewExternalAgentThread { agent: None })) + }) .icon(IconName::AiClaude) .disabled(is_via_collab) .icon_color(Color::Muted) @@ -2009,6 +2017,9 @@ impl AgentPanel { ) .item( ContextMenuEntry::new("Codex CLI") + .when(is_agent_selected(AgentType::Codex), |this| { + this.action(Box::new(NewExternalAgentThread { agent: None })) + }) .icon(IconName::AiOpenAi) .disabled(is_via_collab) .icon_color(Color::Muted) @@ -2035,6 +2046,9 @@ impl AgentPanel { ) .item( ContextMenuEntry::new("Gemini CLI") + .when(is_agent_selected(AgentType::Gemini), |this| { + this.action(Box::new(NewExternalAgentThread { agent: None })) + }) .icon(IconName::AiGemini) .icon_color(Color::Muted) .disabled(is_via_collab) @@ -2060,8 +2074,8 @@ impl AgentPanel { }), ) .map(|mut menu| { - let agent_server_store_read = agent_server_store.read(cx); - let agent_names = agent_server_store_read + let agent_server_store = agent_server_store.read(cx); + let agent_names = agent_server_store .external_agents() .filter(|name| { name.0 != GEMINI_NAME @@ -2070,21 +2084,38 @@ impl AgentPanel { }) .cloned() .collect::>(); + let custom_settings = cx .global::() .get::(None) .custom .clone(); + for agent_name in agent_names { - let icon_path = agent_server_store_read.agent_icon(&agent_name); - let mut entry = - ContextMenuEntry::new(format!("{}", agent_name)); + let icon_path = agent_server_store.agent_icon(&agent_name); + + let mut entry = ContextMenuEntry::new(agent_name.clone()); + + let command = custom_settings + .get(&agent_name.0) + .map(|settings| settings.command.clone()) + .unwrap_or(placeholder_command()); + if let Some(icon_path) = icon_path { entry = entry.custom_icon_svg(icon_path); } else { entry = entry.icon(IconName::Terminal); } entry = entry + .when( + is_agent_selected(AgentType::Custom { + name: agent_name.0.clone(), + command: command.clone(), + }), + |this| { + this.action(Box::new(NewExternalAgentThread { agent: None })) + }, + ) .icon_color(Color::Muted) .disabled(is_via_collab) .handler({ @@ -2124,6 +2155,7 @@ impl AgentPanel { } } }); + menu = menu.item(entry); } @@ -2156,7 +2188,7 @@ impl AgentPanel { .id("selected_agent_icon") .when_some(selected_agent_custom_icon, |this, icon_path| { let label = selected_agent_label.clone(); - this.px(DynamicSpacing::Base02.rems(cx)) + this.px_1() .child(Icon::from_external_svg(icon_path).color(Color::Muted)) .tooltip(move |_window, cx| { Tooltip::with_meta(label.clone(), None, "Selected Agent", cx) @@ -2165,7 +2197,7 @@ impl AgentPanel { .when(!has_custom_icon, |this| { this.when_some(self.selected_agent.icon(), |this, icon| { let label = selected_agent_label.clone(); - this.px(DynamicSpacing::Base02.rems(cx)) + this.px_1() .child(Icon::new(icon).color(Color::Muted)) .tooltip(move |_window, cx| { Tooltip::with_meta(label.clone(), None, "Selected Agent", cx)