diff --git a/packages/cli/src/lib/detect-agent.ts b/packages/cli/src/lib/detect-agent.ts index b8c15bd53..87684eb9c 100644 --- a/packages/cli/src/lib/detect-agent.ts +++ b/packages/cli/src/lib/detect-agent.ts @@ -18,6 +18,7 @@ const AGENT_PLUGINS: Array<{ name: string; pkg: string }> = [ { name: "claude-code", pkg: "@composio/ao-plugin-agent-claude-code" }, { name: "aider", pkg: "@composio/ao-plugin-agent-aider" }, { name: "codex", pkg: "@composio/ao-plugin-agent-codex" }, + { name: "cursor", pkg: "@composio/ao-plugin-agent-cursor" }, { name: "opencode", pkg: "@composio/ao-plugin-agent-opencode" }, ]; diff --git a/packages/cli/src/lib/plugins.ts b/packages/cli/src/lib/plugins.ts index 215cd006c..32a8e6eec 100644 --- a/packages/cli/src/lib/plugins.ts +++ b/packages/cli/src/lib/plugins.ts @@ -2,6 +2,7 @@ import type { Agent, OrchestratorConfig, PluginRegistry, SCM } from "@composio/a import claudeCodePlugin from "@composio/ao-plugin-agent-claude-code"; import codexPlugin from "@composio/ao-plugin-agent-codex"; import aiderPlugin from "@composio/ao-plugin-agent-aider"; +import cursorPlugin from "@composio/ao-plugin-agent-cursor"; import opencodePlugin from "@composio/ao-plugin-agent-opencode"; import githubSCMPlugin from "@composio/ao-plugin-scm-github"; @@ -9,6 +10,7 @@ const agentPlugins: Record = { "claude-code": claudeCodePlugin, codex: codexPlugin, aider: aiderPlugin, + cursor: cursorPlugin, opencode: opencodePlugin, }; diff --git a/packages/core/src/plugin-registry.ts b/packages/core/src/plugin-registry.ts index 224d8a456..4d1dd7d22 100644 --- a/packages/core/src/plugin-registry.ts +++ b/packages/core/src/plugin-registry.ts @@ -38,6 +38,7 @@ const BUILTIN_PLUGINS: Array<{ slot: PluginSlot; name: string; pkg: string }> = { slot: "agent", name: "claude-code", pkg: "@composio/ao-plugin-agent-claude-code" }, { slot: "agent", name: "codex", pkg: "@composio/ao-plugin-agent-codex" }, { slot: "agent", name: "aider", pkg: "@composio/ao-plugin-agent-aider" }, + { slot: "agent", name: "cursor", pkg: "@composio/ao-plugin-agent-cursor" }, { slot: "agent", name: "opencode", pkg: "@composio/ao-plugin-agent-opencode" }, // Workspaces { slot: "workspace", name: "worktree", pkg: "@composio/ao-plugin-workspace-worktree" }, diff --git a/packages/plugins/agent-cursor/src/index.test.ts b/packages/plugins/agent-cursor/src/index.test.ts index 69fc335c0..865f75a1f 100644 --- a/packages/plugins/agent-cursor/src/index.test.ts +++ b/packages/plugins/agent-cursor/src/index.test.ts @@ -322,11 +322,6 @@ describe("detectActivity", () => { expect(agent.detectActivity("Press Enter to continue")).toBe("waiting_input"); }); - it("returns blocked for error messages", () => { - expect(agent.detectActivity("error: failed to connect")).toBe("blocked"); - expect(agent.detectActivity("failed: timeout exceeded")).toBe("blocked"); - }); - it("returns active for non-empty terminal output", () => { expect(agent.detectActivity("cursor is processing files\n")).toBe("active"); }); diff --git a/packages/plugins/agent-cursor/src/index.ts b/packages/plugins/agent-cursor/src/index.ts index 478b7cf2f..e46fa5574 100644 --- a/packages/plugins/agent-cursor/src/index.ts +++ b/packages/plugins/agent-cursor/src/index.ts @@ -178,9 +178,12 @@ function createCursorAgent(): Agent { if (/proceed\?/i.test(tail)) return "waiting_input"; if (/Press Enter to continue/i.test(tail)) return "waiting_input"; - // Check for error indicators - if (/error:/i.test(tail)) return "blocked"; - if (/failed:/i.test(tail)) return "blocked"; + // Note: "blocked" detection removed — compiler errors, test failures, and linter + // messages are extremely common in normal tool output. Unlike Claude Code (which + // has native JSONL with rich "error" types), terminal-based detection can't + // distinguish between actionable agent errors and normal tool output. + // If Cursor CLI provides native JSONL in the future, blocked detection can be + // added to getActivityState() based on JSONL entry types. return "active"; }, diff --git a/packages/web/package.json b/packages/web/package.json index 38d7d4515..64e17bfdd 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -29,6 +29,7 @@ "dependencies": { "@composio/ao-core": "workspace:*", "@composio/ao-plugin-agent-claude-code": "workspace:*", + "@composio/ao-plugin-agent-cursor": "workspace:*", "@composio/ao-plugin-agent-opencode": "workspace:*", "@composio/ao-plugin-runtime-tmux": "workspace:*", "@composio/ao-plugin-scm-github": "workspace:*", diff --git a/packages/web/src/lib/services.ts b/packages/web/src/lib/services.ts index 7715136f8..b9c947a69 100644 --- a/packages/web/src/lib/services.ts +++ b/packages/web/src/lib/services.ts @@ -39,6 +39,7 @@ import { // Static plugin imports — webpack needs these to be string literals import pluginRuntimeTmux from "@composio/ao-plugin-runtime-tmux"; import pluginAgentClaudeCode from "@composio/ao-plugin-agent-claude-code"; +import pluginAgentCursor from "@composio/ao-plugin-agent-cursor"; import pluginAgentOpencode from "@composio/ao-plugin-agent-opencode"; import pluginWorkspaceWorktree from "@composio/ao-plugin-workspace-worktree"; import pluginScmGithub from "@composio/ao-plugin-scm-github"; @@ -81,6 +82,7 @@ async function initServices(): Promise { // Register plugins explicitly (webpack can't handle dynamic import() in core) registry.register(pluginRuntimeTmux); registry.register(pluginAgentClaudeCode); + registry.register(pluginAgentCursor); registry.register(pluginAgentOpencode); registry.register(pluginWorkspaceWorktree); registry.register(pluginScmGithub); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc09d9189..060c25446 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -600,6 +600,9 @@ importers: '@composio/ao-plugin-agent-claude-code': specifier: workspace:* version: link:../plugins/agent-claude-code + '@composio/ao-plugin-agent-cursor': + specifier: workspace:* + version: link:../plugins/agent-cursor '@composio/ao-plugin-agent-opencode': specifier: workspace:* version: link:../plugins/agent-opencode