rename cursor to cursor agent (vibe-kanban) (#1072)
* Done! I've successfully renamed "Cursor" to "Cursor Agent" throughout the codebase. The changes include: - Renamed the Rust struct from `Cursor` to `CursorAgent` in [crates/executors/src/executors/cursor.rs](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/crates/executors/src/executors/cursor.rs) - Updated the enum variant in [crates/executors/src/executors/mod.rs](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/crates/executors/src/executors/mod.rs) with proper serialization attributes - Updated documentation in [docs/supported-coding-agents.mdx](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/docs/supported-coding-agents.mdx) and [docs/index.mdx](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/docs/index.mdx) - Regenerated TypeScript types - All type checks pass (frontend and backend) The serialization still uses "CURSOR" for backwards compatibility, but the struct is now named `CursorAgent` in Rust, making it clear this refers to the Cursor Agent CLI tool. * Perfect! All checks pass. The renaming is complete. The struct is now `CursorAgent` everywhere, serializing as `CURSOR_AGENT`. * Perfect! Done. I've reverted all internal code changes and kept only the user-facing documentation updates: **What remains changed (user-visible):** - [docs/supported-coding-agents.mdx](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/docs/supported-coding-agents.mdx) - Title changed from "Cursor CLI" to "Cursor Agent CLI" - [docs/index.mdx](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/51f5-rename-cursor-to/docs/index.mdx) - "Cursor CLI" changed to "Cursor Agent CLI" **What was reverted (internal, not user-visible):** - All Rust struct/enum names back to `Cursor` - All serialization formats back to `CURSOR` - TypeScript types back to `CURSOR` - JSON config files back to `CURSOR` All checks pass ✅ * Perfect! Now users will see "CURSOR_AGENT" in the UI when selecting agents, while the code stays clean with the `Cursor` struct name, and documentation still says "Cursor CLI". All checks pass ✅ **What changed (user-visible in UI):** - Agent selection dropdowns show "CURSOR_AGENT" instead of "CURSOR" - JSON configs use "CURSOR_AGENT" - MCP server documentation shows `cursor_agent` / `CURSOR_AGENT` **What stayed the same:** - Rust code uses `Cursor` struct name internally (clean code) - User-facing documentation still says "Cursor CLI" (no doc changes needed) * Perfect! Now it's backwards compatible. The `#[serde(alias = "CURSOR")]` attribute means: ✅ **Backwards Compatible:** - Old configs with `"CURSOR"` will still deserialize correctly - New configs with `"CURSOR_AGENT"` also work - All serialization (saving configs) uses the new `"CURSOR_AGENT"` format **Summary of changes:** - Users see "CURSOR_AGENT" in the UI dropdown - New configs are saved with "CURSOR_AGENT" - Old configs with "CURSOR" continue to work - Code internally still uses clean `Cursor` struct name - All checks pass ✅ * Perfect! ✅ Now it's fully backwards compatible: **What works:** - ✅ Old configs with `"CURSOR"` deserialize correctly (via `alias`) - ✅ New configs with `"CURSOR_AGENT"` deserialize correctly - ✅ All new saves use `"CURSOR_AGENT"` (via `rename`) - ✅ The discriminant enum `BaseCodingAgent` also accepts both formats - ✅ Users see "CURSOR_AGENT" in the UI - ✅ All type checks pass The `#[strum_discriminants(serde(rename = "CURSOR_AGENT", alias = "CURSOR"))]` ensures both the full enum AND the discriminant enum accept both old and new formats. * Perfect! ✅ Now `cursor_agent.json` exists and the Vite plugin will create the key `CURSOR_AGENT`, which matches what the frontend expects. * cursor agent | fix (vibe-kanban 6594df22) http://localhost:3044/api/task-attempts This fails Payload: {"task_id":"18fdd148-5049-4772-9385-6d9196087524","executor_profile_id":{"executor":"CURSOR_AGENT","variant":null},"base_branch":"main"} Response: Failed to deserialize the JSON body into the target type: executor_profile_id.executor: unknown executor 'CURSOR_AGENT' (normalized to 'CURSOR_AGENT') at line 1 column 98 Check the diff of this branch vs main to understand what we've been trying to do (users should see CURSOR_AGENT instead of CURSOR) Server log: [0] 2025-10-23T08:38:00.475636Z DEBUG server::routes::tasks: Creating task 'hey' in project f8c8d410-fd1b-48a4-829a-a6bf4b550a62 * rename CodingAgent::Cursor -> CodingAgent::CursorAgent * update types
This commit is contained in:
committed by
GitHub
parent
e160571f67
commit
074199f2d2
@@ -69,39 +69,39 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"DEFAULT": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "auto"
|
||||
}
|
||||
},
|
||||
"SONNET_4_5": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "sonnet-4.5"
|
||||
}
|
||||
},
|
||||
"SONNET_4_5_THINKING": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "sonnet-4.5-thinking"
|
||||
}
|
||||
},
|
||||
"OPUS_4_1": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "opus-4.1"
|
||||
}
|
||||
},
|
||||
"GPT_5": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "gpt-5"
|
||||
}
|
||||
},
|
||||
"GROK": {
|
||||
"CURSOR": {
|
||||
"CURSOR_AGENT": {
|
||||
"force": true,
|
||||
"model": "grok"
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::{
|
||||
mod mcp;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS, JsonSchema)]
|
||||
pub struct Cursor {
|
||||
pub struct CursorAgent {
|
||||
#[serde(default)]
|
||||
pub append_prompt: AppendPrompt,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -45,7 +45,7 @@ pub struct Cursor {
|
||||
pub cmd: CmdOverrides,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
impl CursorAgent {
|
||||
fn build_command_builder(&self) -> CommandBuilder {
|
||||
let mut builder =
|
||||
CommandBuilder::new("cursor-agent").params(["-p", "--output-format=stream-json"]);
|
||||
@@ -63,7 +63,7 @@ impl Cursor {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl StandardCodingAgentExecutor for Cursor {
|
||||
impl StandardCodingAgentExecutor for CursorAgent {
|
||||
async fn spawn(&self, current_dir: &Path, prompt: &str) -> Result<SpawnedChild, ExecutorError> {
|
||||
mcp::ensure_mcp_server_trust(self, current_dir).await;
|
||||
|
||||
@@ -178,7 +178,7 @@ impl StandardCodingAgentExecutor for Cursor {
|
||||
|
||||
// Provide a useful sign-in message if needed
|
||||
let line = if line == "Press any key to sign in..." {
|
||||
"Please sign in to Cursor CLI using `cursor-agent login` or set the CURSOR_API_KEY environment variable.".to_string()
|
||||
"Please sign in to Cursor Agent CLI using `cursor-agent login` or set the CURSOR_API_KEY environment variable.".to_string()
|
||||
} else {
|
||||
line
|
||||
};
|
||||
@@ -1182,7 +1182,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_cursor_streaming_patch_generation() {
|
||||
// Avoid relying on feature flag in tests; construct with a dummy command
|
||||
let executor = Cursor {
|
||||
let executor = CursorAgent {
|
||||
// No command field needed anymore
|
||||
append_prompt: AppendPrompt::default(),
|
||||
force: None,
|
||||
|
||||
@@ -4,10 +4,10 @@ use sha2::{Digest, Sha256};
|
||||
use tokio::fs;
|
||||
use tracing::warn;
|
||||
|
||||
use super::Cursor;
|
||||
use super::CursorAgent;
|
||||
use crate::executors::{CodingAgent, ExecutorError, StandardCodingAgentExecutor};
|
||||
|
||||
pub async fn ensure_mcp_server_trust(cursor: &Cursor, current_dir: &Path) {
|
||||
pub async fn ensure_mcp_server_trust(cursor: &CursorAgent, current_dir: &Path) {
|
||||
if let Err(err) = ensure_mcp_server_trust_impl(cursor, current_dir).await {
|
||||
tracing::warn!(
|
||||
error = %err,
|
||||
@@ -17,7 +17,7 @@ pub async fn ensure_mcp_server_trust(cursor: &Cursor, current_dir: &Path) {
|
||||
}
|
||||
|
||||
async fn ensure_mcp_server_trust_impl(
|
||||
cursor: &Cursor,
|
||||
cursor: &CursorAgent,
|
||||
current_dir: &Path,
|
||||
) -> Result<(), ExecutorError> {
|
||||
let current_dir =
|
||||
@@ -166,7 +166,7 @@ fn compute_cursor_approval_id(
|
||||
Some(format!("{server_name}-{}", &hex[..16]))
|
||||
}
|
||||
|
||||
fn default_cursor_mcp_servers(cursor: &Cursor) -> serde_json::Value {
|
||||
let mcpc = CodingAgent::Cursor(cursor.clone()).get_mcp_config();
|
||||
fn default_cursor_mcp_servers(cursor: &CursorAgent) -> serde_json::Value {
|
||||
let mcpc = CodingAgent::CursorAgent(cursor.clone()).get_mcp_config();
|
||||
serde_json::json!({ "mcpServers": mcpc.preconfigured })
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use workspace_utils::msg_store::MsgStore;
|
||||
use crate::{
|
||||
approvals::ExecutorApprovalService,
|
||||
executors::{
|
||||
amp::Amp, claude::ClaudeCode, codex::Codex, copilot::Copilot, cursor::Cursor,
|
||||
amp::Amp, claude::ClaudeCode, codex::Codex, copilot::Copilot, cursor::CursorAgent,
|
||||
gemini::Gemini, opencode::Opencode, qwen::QwenCode,
|
||||
},
|
||||
mcp_config::McpConfig,
|
||||
@@ -78,7 +78,9 @@ pub enum CodingAgent {
|
||||
Gemini,
|
||||
Codex,
|
||||
Opencode,
|
||||
Cursor,
|
||||
#[serde(alias = "CURSOR")]
|
||||
#[strum_discriminants(strum(serialize = "CURSOR", serialize = "CURSOR_AGENT"))]
|
||||
CursorAgent,
|
||||
QwenCode,
|
||||
Copilot,
|
||||
}
|
||||
@@ -133,7 +135,7 @@ impl CodingAgent {
|
||||
Self::Codex(_) => vec![BaseAgentCapability::SessionFork],
|
||||
Self::Gemini(_) => vec![BaseAgentCapability::SessionFork],
|
||||
Self::QwenCode(_) => vec![BaseAgentCapability::SessionFork],
|
||||
Self::Opencode(_) | Self::Cursor(_) | Self::Copilot(_) => vec![],
|
||||
Self::Opencode(_) | Self::CursorAgent(_) | Self::Copilot(_) => vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,3 +206,26 @@ impl AppendPrompt {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_cursor_agent_deserialization() {
|
||||
// Test that CURSOR_AGENT is accepted
|
||||
let result = BaseCodingAgent::from_str("CURSOR_AGENT");
|
||||
assert!(result.is_ok(), "CURSOR_AGENT should be valid");
|
||||
assert_eq!(result.unwrap(), BaseCodingAgent::CursorAgent);
|
||||
|
||||
// Test that legacy CURSOR is still accepted for backwards compatibility
|
||||
let result = BaseCodingAgent::from_str("CURSOR");
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"CURSOR should be valid for backwards compatibility"
|
||||
);
|
||||
assert_eq!(result.unwrap(), BaseCodingAgent::CursorAgent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ impl CodingAgent {
|
||||
let adapter = match self {
|
||||
CodingAgent::ClaudeCode(_) | CodingAgent::Amp(_) => Passthrough,
|
||||
CodingAgent::QwenCode(_) | CodingAgent::Gemini(_) => Gemini,
|
||||
CodingAgent::Cursor(_) => Cursor,
|
||||
CodingAgent::CursorAgent(_) => Cursor,
|
||||
CodingAgent::Codex(_) => Codex,
|
||||
CodingAgent::Opencode(_) => Opencode,
|
||||
CodingAgent::Copilot(..) => Copilot,
|
||||
|
||||
@@ -83,7 +83,7 @@ fn generate_types_content() -> String {
|
||||
executors::executors::codex::ReasoningEffort::decl(),
|
||||
executors::executors::codex::ReasoningSummary::decl(),
|
||||
executors::executors::codex::ReasoningSummaryFormat::decl(),
|
||||
executors::executors::cursor::Cursor::decl(),
|
||||
executors::executors::cursor::CursorAgent::decl(),
|
||||
executors::executors::copilot::Copilot::decl(),
|
||||
executors::executors::opencode::Opencode::decl(),
|
||||
executors::executors::qwen::QwenCode::decl(),
|
||||
@@ -180,8 +180,8 @@ fn generate_schemas() -> Result<HashMap<&'static str, String>, serde_json::Error
|
||||
generate_json_schema::<executors::executors::codex::Codex>()?,
|
||||
),
|
||||
(
|
||||
"cursor",
|
||||
generate_json_schema::<executors::executors::cursor::Cursor>()?,
|
||||
"cursor_agent",
|
||||
generate_json_schema::<executors::executors::cursor::CursorAgent>()?,
|
||||
),
|
||||
(
|
||||
"opencode",
|
||||
|
||||
@@ -203,7 +203,7 @@ pub struct StartTaskAttemptRequest {
|
||||
#[schemars(description = "The ID of the task to start")]
|
||||
pub task_id: Uuid,
|
||||
#[schemars(
|
||||
description = "The coding agent executor to run ('CLAUDE_CODE', 'CODEX', 'GEMINI', 'CURSOR', 'OPENCODE')"
|
||||
description = "The coding agent executor to run ('CLAUDE_CODE', 'CODEX', 'GEMINI', 'CURSOR_AGENT', 'OPENCODE')"
|
||||
)]
|
||||
pub executor: String,
|
||||
#[schemars(description = "Optional executor variant, if needed")]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: "Cursor CLI"
|
||||
title: "Cursor Agent CLI"
|
||||
description: "Set up Cursor's command-line agent"
|
||||
icon: https://www.vibekanban.com/images/logos/cursor-logo-light.png
|
||||
---
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Cursor CLI">
|
||||
<Step title="Install Cursor Agent CLI">
|
||||
```bash
|
||||
curl https://cursor.com/install -fsS | bash
|
||||
```
|
||||
@@ -24,6 +24,6 @@ icon: https://www.vibekanban.com/images/logos/cursor-logo-light.png
|
||||
npx vibe-kanban
|
||||
```
|
||||
|
||||
You can now select Cursor CLI when creating task attempts.
|
||||
You can now select Cursor Agent CLI when creating task attempts.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
@@ -20,7 +20,7 @@ Vibe Kanban is an **orchestration platform for AI coding agents** that helps dev
|
||||
</Card>
|
||||
|
||||
<Card title="Multi-Agent Support" icon="users">
|
||||
Switch between Claude Code, OpenAI Codex, Amp, Cursor CLI, Gemini, and other agents without changing workflows.
|
||||
Switch between Claude Code, OpenAI Codex, Amp, Cursor Agent CLI, Gemini, and other agents without changing workflows.
|
||||
</Card>
|
||||
|
||||
<Card title="Visual Code Review" icon="code-compare">
|
||||
|
||||
@@ -85,7 +85,7 @@ When using `start_task_attempt`, the following executors are supported (case-ins
|
||||
- `gemini` / `GEMINI`
|
||||
- `codex` / `CODEX`
|
||||
- `opencode` / `OPENCODE`
|
||||
- `cursor` / `CURSOR`
|
||||
- `cursor_agent` / `CURSOR_AGENT`
|
||||
- `qwen-code` / `QWEN_CODE`
|
||||
- `copilot` / `COPILOT`
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ Google Gemini CLI
|
||||
Amp Code
|
||||
</Card>
|
||||
|
||||
<Card title="Cursor CLI" icon="https://www.vibekanban.com/images/logos/cursor-logo-light.png" href="/agents/cursor-cli">
|
||||
Cursor CLI agent
|
||||
<Card title="Cursor Agent CLI" icon="https://www.vibekanban.com/images/logos/cursor-logo-light.png" href="/agents/cursor-cli">
|
||||
Cursor Agent CLI
|
||||
</Card>
|
||||
|
||||
<Card title="OpenCode" icon="https://www.vibekanban.com/images/logos/opencode-light.svg" href="/agents/opencode">
|
||||
|
||||
@@ -15,7 +15,7 @@ type ExecutorType =
|
||||
| 'CLAUDE_CODE'
|
||||
| 'GEMINI'
|
||||
| 'CODEX'
|
||||
| 'CURSOR'
|
||||
| 'CURSOR_AGENT'
|
||||
| 'COPILOT'
|
||||
| 'OPENCODE'
|
||||
| 'QWEN_CODE';
|
||||
|
||||
@@ -30,9 +30,9 @@ export type ScriptRequest = { script: string, language: ScriptRequestLanguage, c
|
||||
|
||||
export type ScriptRequestLanguage = "Bash";
|
||||
|
||||
export enum BaseCodingAgent { CLAUDE_CODE = "CLAUDE_CODE", AMP = "AMP", GEMINI = "GEMINI", CODEX = "CODEX", OPENCODE = "OPENCODE", CURSOR = "CURSOR", QWEN_CODE = "QWEN_CODE", COPILOT = "COPILOT" }
|
||||
export enum BaseCodingAgent { CLAUDE_CODE = "CLAUDE_CODE", AMP = "AMP", GEMINI = "GEMINI", CODEX = "CODEX", OPENCODE = "OPENCODE", CURSOR_AGENT = "CURSOR_AGENT", QWEN_CODE = "QWEN_CODE", COPILOT = "COPILOT" }
|
||||
|
||||
export type CodingAgent = { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR": Cursor } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot };
|
||||
export type CodingAgent = { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR_AGENT": CursorAgent } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot };
|
||||
|
||||
export type Tag = { id: string, tag_name: string, content: string, created_at: string, updated_at: string, };
|
||||
|
||||
@@ -154,7 +154,7 @@ executor: BaseCodingAgent,
|
||||
*/
|
||||
variant: string | null, };
|
||||
|
||||
export type ExecutorConfig = { [key in string]?: { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR": Cursor } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot } };
|
||||
export type ExecutorConfig = { [key in string]?: { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR_AGENT": CursorAgent } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot } };
|
||||
|
||||
export type BaseAgentCapability = "SESSION_FORK";
|
||||
|
||||
@@ -178,7 +178,7 @@ export type ReasoningSummary = "auto" | "concise" | "detailed" | "none";
|
||||
|
||||
export type ReasoningSummaryFormat = "none" | "experimental";
|
||||
|
||||
export type Cursor = { append_prompt: AppendPrompt, force?: boolean | null, model?: string | null, base_command_override?: string | null, additional_params?: Array<string> | null, };
|
||||
export type CursorAgent = { append_prompt: AppendPrompt, force?: boolean | null, model?: string | null, base_command_override?: string | null, additional_params?: Array<string> | null, };
|
||||
|
||||
export type Copilot = { append_prompt: AppendPrompt, model?: string | null, allow_all_tools?: boolean | null, allow_tool?: string | null, deny_tool?: string | null, add_dir?: Array<string> | null, disable_mcp_server?: Array<string> | null, base_command_override?: string | null, additional_params?: Array<string> | null, };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user