From 7324acbe17ced52281a3bae0cedc469aa1b3ce33 Mon Sep 17 00:00:00 2001 From: Prashanth Ramasamy <101465633+p-prash@users.noreply.github.com> Date: Fri, 11 Sep 2026 09:35:30 +0800 Subject: [PATCH] fix(desktop): discover current Cursor Agent CLI Signed-off-by: Prashanth Ramasamy <101465633+p-prash@users.noreply.github.com> --- .../src-tauri/src/managed_agents/discovery.rs | 13 +++++++++-- .../src/managed_agents/discovery/presets.rs | 4 ++-- .../src/managed_agents/discovery/tests.rs | 22 +++++++++++++++++++ .../e2e/harness-catalog-screenshots.spec.ts | 6 ++--- desktop/tests/e2e/harness-management.spec.ts | 6 ++--- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/desktop/src-tauri/src/managed_agents/discovery.rs b/desktop/src-tauri/src/managed_agents/discovery.rs index e4b87e7557a..a73cc287f9d 100644 --- a/desktop/src-tauri/src/managed_agents/discovery.rs +++ b/desktop/src-tauri/src/managed_agents/discovery.rs @@ -563,13 +563,22 @@ pub(crate) fn availability_drift( /// On Windows also includes `.cmd` and `.bat` variants so npm-generated shims /// (e.g. `codex-acp.cmd` in `%APPDATA%\npm`) are discoverable. fn command_basenames(command: &str) -> Vec { - let candidates = vec![executable_basename(command)]; + let mut candidates = vec![executable_basename(command)]; + // Cursor renamed its native CLI from `cursor-agent` to `agent`. Keep the + // old command as a compatibility alias for persisted harness records and + // older custom configurations while preferring the current binary. + if command.eq_ignore_ascii_case("cursor-agent") { + candidates.push(executable_basename("agent")); + } #[cfg(windows)] { - let mut candidates = candidates; if !command.contains('.') { candidates.push(format!("{command}.cmd")); candidates.push(format!("{command}.bat")); + if command.eq_ignore_ascii_case("cursor-agent") { + candidates.push("agent.cmd".to_string()); + candidates.push("agent.bat".to_string()); + } } return candidates; } diff --git a/desktop/src-tauri/src/managed_agents/discovery/presets.rs b/desktop/src-tauri/src/managed_agents/discovery/presets.rs index b184559c157..e3d23a5de5a 100644 --- a/desktop/src-tauri/src/managed_agents/discovery/presets.rs +++ b/desktop/src-tauri/src/managed_agents/discovery/presets.rs @@ -133,10 +133,10 @@ pub(super) const PRESET_HARNESSES: &[PresetHarness] = &[ PresetHarness { id: "cursor", label: "Cursor", - command: "cursor-agent", + command: "agent", args: &["acp"], install_instructions_url: "https://cursor.com/downloads", - install_hint: "Buzz talks to Cursor through the cursor-agent CLI's ACP mode.", + install_hint: "Buzz talks to Cursor through the Cursor Agent CLI's ACP mode.", underlying_cli: None, underlying_cli_install_hint: None, underlying_cli_install_instructions_url: None, diff --git a/desktop/src-tauri/src/managed_agents/discovery/tests.rs b/desktop/src-tauri/src/managed_agents/discovery/tests.rs index f13a2d20bdf..c7639f5812a 100644 --- a/desktop/src-tauri/src/managed_agents/discovery/tests.rs +++ b/desktop/src-tauri/src/managed_agents/discovery/tests.rs @@ -12,6 +12,28 @@ use super::{ }; use crate::managed_agents::AcpAvailabilityStatus; +#[test] +fn cursor_preset_uses_renamed_cli_and_keeps_legacy_alias() { + let candidates = super::command_basenames("cursor-agent"); + let cursor = super::preset_harness_definitions() + .into_iter() + .find(|harness| harness.id == "cursor") + .unwrap(); + + assert_eq!(candidates.first().map(String::as_str), Some("cursor-agent")); + assert!( + candidates.iter().any(|candidate| { + candidate == "agent" + || candidate == "agent.exe" + || candidate == "agent.cmd" + || candidate == "agent.bat" + }), + "Cursor's current agent binary must be discoverable as a compatibility alias" + ); + assert_eq!(cursor.command, "agent"); + assert_eq!(cursor.args, vec!["acp".to_string()]); +} + #[test] fn resolves_known_avatar_for_bare_command() { let avatar_url = managed_agent_avatar_url("goose").expect("goose avatar should resolve"); diff --git a/desktop/tests/e2e/harness-catalog-screenshots.spec.ts b/desktop/tests/e2e/harness-catalog-screenshots.spec.ts index c5613f41f2a..9afaf1feda3 100644 --- a/desktop/tests/e2e/harness-catalog-screenshots.spec.ts +++ b/desktop/tests/e2e/harness-catalog-screenshots.spec.ts @@ -66,12 +66,12 @@ const CATALOG = [ label: "Cursor", avatar_url: "", availability: "available", - command: "cursor-agent", - binary_path: "/usr/local/bin/cursor-agent", + command: "agent", + binary_path: "/usr/local/bin/agent", default_args: ["acp"], mcp_command: null, install_hint: - "Buzz talks to Cursor through the cursor-agent CLI's ACP mode.", + "Buzz talks to Cursor through the Cursor Agent CLI's ACP mode.", install_instructions_url: "https://cursor.com/downloads", can_auto_install: false, underlying_cli_path: null, diff --git a/desktop/tests/e2e/harness-management.spec.ts b/desktop/tests/e2e/harness-management.spec.ts index c5b441ad21d..dcbdfca4366 100644 --- a/desktop/tests/e2e/harness-management.spec.ts +++ b/desktop/tests/e2e/harness-management.spec.ts @@ -74,11 +74,11 @@ const CURSOR_AVAILABLE = { label: "Cursor", avatar_url: "", availability: "available", - command: "cursor-agent", - binary_path: "/usr/local/bin/cursor-agent", + command: "agent", + binary_path: "/usr/local/bin/agent", default_args: [], mcp_command: null, - install_hint: "Buzz talks to Cursor through the cursor-agent CLI's ACP mode.", + install_hint: "Buzz talks to Cursor through the Cursor Agent CLI's ACP mode.", install_instructions_url: "https://cursor.com/cli", can_auto_install: false, requires_external_cli: true,