Skip to content

feat(team): add cursor-agent as 4th tmux worker type (executor-only) - #2734

Closed
aryateja2106 wants to merge 1 commit into
Yeachan-Heo:mainfrom
aryateja2106:feat/cursor-worker-support
Closed

aryateja2106 wants to merge 1 commit into
Yeachan-Heo:mainfrom
aryateja2106:feat/cursor-worker-support

Conversation

@aryateja2106

Copy link
Copy Markdown
Contributor

Adds cursor-agent (Cursor's Composer 2 REPL) as a first-class `omc team` worker provider alongside claude/codex/gemini.

Why

cursor-agent is a very capable interactive coding agent that many users (including myself) already keep a running Cursor Pro/Max plan for. Making it a native OMC worker lets those users burn Cursor credits for throughput work while the Claude orchestrator retains the plan/verify role — without leaving the `omc team` mental model.

The user also gets the full cmux-pane visibility: they can watch the cursor-agent REPL live, interrupt by typing directly into the split, and the orchestrator continues to coordinate via the standard filesystem A2A at `.omc/state/team//`.

Changes

File Change
`src/team/model-contract.ts` Extend `CliAgentType` with `'cursor'`; add `CONTRACTS.cursor` (binary `cursor-agent`, `supportsPromptMode: false`, minimal launch args)
`src/team/types.ts` Extend `WorkerBackend` with `'tmux-cursor'`; widen `WorkerInfo.worker_cli` to include `'cursor'`
`src/team/capabilities.ts` Map `tmux-cursor` to `['code-edit', 'refactoring', 'general']`
`src/team/cli-detection.ts` Detect `cursor-agent` in `detectAllClis()`
`src/team/worker-bootstrap.ts` Add `case 'cursor':` to `agentTypeGuidance` with REPL-aware instructions (stay in session, claim/transition tasks via team-api, do not auto-exit)
`src/team/cli-worker-contract.ts` Skip `shouldInjectContract` for cursor, matching the claude carve-out
`src/cli/team.ts` Add `'cursor'` to `VALID_CLI_AGENT_TYPES`; update help text

Executor-only: why

Codex and Gemini use `supportsPromptMode: true` because they're one-shot CLIs (run a prompt → exit). The CLI-worker output contract (`CONTRACT_ROLES` = critic/code-reviewer/security-reviewer/test-engineer) depends on exit-on-complete so the verdict JSON can be read by the leader's worker-completion handler.

cursor-agent is an interactive REPL — it does not exit after answering. Routing a reviewer role to a cursor worker would hang the team because the verdict file would never be written. This patch:

  1. Sets `supportsPromptMode: false` on the cursor contract.
  2. Extends `shouldInjectContract` to skip cursor (alongside claude).
  3. Documents the constraint in the in-prompt `agentTypeGuidance`.

Mailbox / inbox / sentinel / heartbeat flow is unchanged — cursor workers participate in the standard filesystem A2A the same way claude workers do.

Verification

```
$ npx tsc --noEmit

all production sources pass

$ cursor-agent --version # confirms binary detection

→ version output

```

End-to-end test (pending once this PR lands):

```
$ omc team 1:cursor:executor "implement hello.py and ack on leader-fixed"

cursor pane spawns in cmux split, receives trigger message,

claims task, edits file, transitions task status, waits.

```

Known follow-up (flagged honestly)

One residual TS error remains in `src/tests/runtime-guidance-plan-ralph.test.ts` at line 87 — it uses a hard-coded literal-union helper signature `(agentType: "claude" | "codex" | "gemini") => agentType is "claude"` that should be widened to `(agentType: CliAgentType) => agentType is "claude"` to accept the new provider. My local agent harness currently guards `*.test.ts` edits (it's a generic "don't silence tests" hook that mis-fires on type-widening), so rather than bypass it I'm surfacing this for a one-line amendment in-PR. Happy to paste the exact diff in a comment — it's simply replacing the literal union with the existing `CliAgentType` import.

Compatibility

  • Existing claude/codex/gemini worker types and behaviors are unchanged.
  • No bridge/MCP changes — cursor uses the existing tmux-pane path.
  • The `BridgeConfig.provider` literal `'codex' | 'gemini'` is intentionally NOT widened: cursor does not go through the bridge runtime, so that narrower type correctly excludes it.

Relationship to cmux

This PR pairs well with two upstream cmux fixes I just opened to make `omc team` work inside cmux at all:

Once all three land, `cmux omc team 1:cursor,1:codex,1:gemini "..."` works end-to-end with each agent in its own cmux split, driveable both by the user (direct keyboard input) and the orchestrator (via the filesystem mailbox).

Adds cursor-agent (Cursor's Composer 2 REPL) as a first-class
\`omc team\` worker provider alongside claude/codex/gemini. Spawned
via the existing tmux-pane path (no bridge changes); cursor workers
appear as cmux/tmux split panes that the user can both observe and
type into directly.

## Changes

- \`src/team/model-contract.ts\`
  - Extend \`CliAgentType\` union with \`'cursor'\`.
  - Add \`cursor\` entry to \`CONTRACTS\` with binary \`cursor-agent\`,
    minimal launch args (no model flag — cursor-agent owns its own
    model selection inside the REPL), and \`supportsPromptMode: false\`.
- \`src/team/types.ts\`
  - Extend \`WorkerBackend\` with \`'tmux-cursor'\`.
  - Widen \`WorkerInfo.worker_cli\` to include \`'cursor'\`.
- \`src/team/capabilities.ts\`
  - Map \`tmux-cursor\` to \`['code-edit', 'refactoring', 'general']\`
    so the fitness scorer routes appropriate executor work to cursor.
- \`src/team/cli-detection.ts\`
  - Detect \`cursor-agent\` in \`detectAllClis()\`.
- \`src/team/worker-bootstrap.ts\`
  - Add \`case 'cursor':\` to \`agentTypeGuidance\` with REPL-aware
    instructions: stay in session, claim/transition tasks via
    team-api, do not auto-exit, take only executor-style work.
- \`src/team/cli-worker-contract.ts\`
  - Skip verdict-file injection for cursor in \`shouldInjectContract\`,
    matching the existing claude carve-out. Cursor REPL cannot perform
    write-verdict-and-exit.
- \`src/cli/team.ts\`
  - Add \`'cursor'\` to \`VALID_CLI_AGENT_TYPES\` and update help text.

## Why executor-only

Codex and Gemini set \`supportsPromptMode: true\` because they are
one-shot CLIs that run a single prompt and exit. The CLI-worker output
contract (CONTRACT_ROLES = critic, code-reviewer, security-reviewer,
test-engineer) depends on this exit-on-complete behavior to surface
structured verdict JSON back to the leader.

cursor-agent is an interactive REPL: it does not exit after answering a
prompt. Routing a reviewer role to a cursor worker would hang the team
because the verdict file is never written and the worker never exits.
This patch:

1. Marks \`supportsPromptMode: false\` on the cursor contract.
2. Updates \`shouldInjectContract\` to skip cursor (alongside claude).
3. Documents the constraint inline in the agentTypeGuidance.

Mailbox/inbox/sentinel/heartbeat behavior is unchanged — cursor workers
participate in the standard \`.omc/state/team/<team>/\` filesystem A2A
the same way claude workers do.

## Verification

- \`npx tsc --noEmit\` passes for all production sources.
- One residual error in \`src/__tests__/runtime-guidance-plan-ralph.test.ts\`
  (line 87) requires widening a hard-coded test helper signature
  \`(agentType: "claude" | "codex" | "gemini") => agentType is "claude"\`
  to \`(agentType: CliAgentType) => agentType is "claude"\` — a one-line
  type-only update. My local agent harness currently guards \`*.test.ts\`
  edits, so I'm flagging this as a follow-up for a maintainer or
  in-PR amendment rather than ship a stale-typed test.

## Usage

Once cmux PR Yeachan-Heo#3031 (tmux-compat short-form expansion) lands, this
enables:

\`\`\`
omc team 1:cursor:executor "implement the X feature"
omc team 1:cursor,1:codex:critic "implement and review the Y change"
\`\`\`

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a02a5f834

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cli/team.ts

const JOB_ID_PATTERN = /^omc-[a-z0-9]{1,16}$/;
const VALID_CLI_AGENT_TYPES = new Set(['claude', 'codex', 'gemini']);
const VALID_CLI_AGENT_TYPES = new Set(['claude', 'codex', 'gemini', 'cursor']);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add cursor to the active omc team parser

Adding cursor in src/cli/team.ts does not make the shipped omc team command accept it, because the real entrypoint wires teamCommand from src/cli/commands/team.ts (see src/cli/index.ts) and that parser still uses VALID_TEAM_CLI_AGENT_TYPES = ['claude','codex','gemini']. In that code path, 1:cursor is treated as a role token rather than an agent type, so users cannot actually launch cursor workers via the primary CLI surface.

Useful? React with 👍 / 👎.

import { isExternalLLMDisabled } from '../lib/security-config.js';

export type CliAgentType = 'claude' | 'codex' | 'gemini';
export type CliAgentType = 'claude' | 'codex' | 'gemini' | 'cursor';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include cursor in v1 CLI-worker shutdown detection

Widening CliAgentType to include cursor allows v1 teams to persist cursor agent types, but shutdownTeam() in src/team/runtime.ts still classifies CLI-worker teams using only claude|codex|gemini. When OMC_RUNTIME_V2 is disabled, cursor teams are misclassified as bridge teams and the shutdown path waits for shutdown-ack.json files that tmux CLI workers never write, causing avoidable timeout delays (30s by default).

Useful? React with 👍 / 👎.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Thanks for the contribution. We're closing this PR because it targets main; this repo takes contribution PRs against dev.

Please retarget the change onto dev and reopen as a fresh PR if you want us to review it there.

—
[repo owner's gaebal-gajae (clawdbot) 🦞]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants