Skip to content

feat(harness): add cursor (Cursor CLI) as a verified adapter#491

Open
cybercat-yanik wants to merge 1 commit into
kunchenguid:mainfrom
cybercat-yanik:feat/cursor-adapter
Open

feat(harness): add cursor (Cursor CLI) as a verified adapter#491
cybercat-yanik wants to merge 1 commit into
kunchenguid:mainfrom
cybercat-yanik:feat/cursor-adapter

Conversation

@cybercat-yanik

Copy link
Copy Markdown

What

Adds cursor (the Cursor CLI, binary cursor-agent) as a sixth verified harness adapter. This opens the Cursor subscription model catalog (Grok 4.5, Codex/GPT tiers, Sonnet, Gemini; enumerable via cursor-agent --list-models) as crewmate/secondmate dispatch targets, which is especially useful for captains who reach some of these models only through Cursor.

Adapter facts (all verified empirically on cursor-agent 2026.07.09-a3815c0, per CONTRIBUTING)

  • Launch: cursor-agent --force --model <id> "$(cat <brief>)"; --force auto-approves execution and a crewmate ran fully unattended (file edits + shell commands).
  • Busy signature: ctrl+c to stop, shown iff a turn is running. The spinner word varies (Working/Running), so the cancel hint is the signature. It is end-anchored in the busy regexes because unlike the other tokens it is generic English a transcript could contain mid-line; verified live both ways (decoy phrase mid-line reads idle, real turn reads busy).
  • Exit/interrupt: /exit or /quit (slash popup, the usual too-fast-Enter hazard; fm-send's retried Enter lands it); single Ctrl+C cancels a turn.
  • Detection: CURSOR_AGENT=1 env marker; ancestry matches the full binary name *cursor-agent* (a bare *cursor* would match the Cursor IDE's own processes from its integrated terminal) and is ordered before *claude* because cursor's runtime is claude-code-derived (AI_AGENT=claude-code_*, but no CLAUDECODE).
  • Effort axis: none; Cursor model ids bake reasoning effort into the name (grok-4.5-xhigh). The bootstrap validator rejects an effort axis on cursor profiles like it does for opencode, and fm-spawn records but never passes it. The SKILL documents Cursor's shifted display names (id grok-4.5-xhigh displays as plain "Cursor Grok 4.5").
  • Turn-end: no hook. A Claude-style .claude/settings.local.json Stop hook verifiably does not fire despite the claude-code-derived runtime, so cursor crewmates ride busy-regex stale-pane supervision; the launch template is identical for ship/scout/secondmate.
  • Composer: placeholder ghost text is dim (SGR 2, verified via raw styled capture), so the generic ghost-stripper handles it with no FM_COMPOSER_IDLE_RE override; fm_tmux_composer_state and fm_pane_is_busy were exercised live against idle and mid-turn panes. One quirk recorded: an Enter in the same keystroke burst as the text can be swallowed; fm-send's settle+retry covers it.
  • Trust dialog: "Workspace Trust Required" on first launch per directory; accept with Enter; persists.
  • Resume: --continue verified headlessly to restore the prior chat.

Tests

  • New test_cursor_threads_model_and_ignores_effort_axis in tests/fm-spawn-dispatch-profile.test.sh.
  • New invalid-effort row (cursor:high) in tests/fm-bootstrap.test.sh.
  • fm-spawn-dispatch-profile, fm-bootstrap, fm-composer-ghost, fm-grok-harness, fm-secondmate-harness, and fm-backend suites all pass on this branch.

🤖 Generated with Claude Code

@kunchenguid

Copy link
Copy Markdown
Owner

Thanks for the PR! This branch currently has a merge conflict with the base branch.

When you get a chance, please rebase onto (or merge) the latest base branch, resolve the conflict, and push. After that, checks will re-run and the PR will get looked at again.

Noted for firstmate#491 at 8d5af6f7.

Adds cursor (binary cursor-agent) to the verified adapter set, giving
firstmate access to the Cursor subscription model catalog (Grok 4.5,
Codex/GPT tiers, and more) as dispatch targets.

Every adapter fact was verified empirically against cursor-agent
2026.07.09 per CONTRIBUTING: launch autonomy via --force, busy signature
(end-anchored "ctrl+c to stop" because it is generic English a
transcript could contain mid-line), /exit and /quit with the slash
popup, single Ctrl+C interrupt, CURSOR_AGENT=1 env marker, workspace
trust dialog, dim (SGR 2) composer ghost text, --continue resume, and a
swallowed-Enter composer quirk. Detection matches the full binary name
cursor-agent, ordered before claude, so the Cursor IDE's own processes
and cursor's claude-code-derived runtime cannot misresolve. No turn-end
hook is wired: a Claude-style Stop hook verifiably does not fire, so
cursor crewmates ride busy-regex stale-pane supervision.

Cursor model ids bake reasoning effort into the name, so cursor has no
effort axis; the bootstrap validator rejects effort on cursor profiles
like it does for opencode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cybercat-yanik

Copy link
Copy Markdown
Author

Rebased onto latest main (b708731) and resolved the conflicts. Notes from the rebase:

  • AGENTS.md: kept your new pointer to the harness-adapters skill instead of restoring the inline profile-axes list; the cursor axis row lives only in the skill's launch-profile table now.
  • Extended the two adapter lists added on main since I branched: the secondmate-liveness trusted-harness case in bin/fm-bootstrap.sh, and kept the cursor test row alongside the new array-use/select validation rows in tests/fm-bootstrap.test.sh.
  • Scoping note added to the skill: cursor is verified as a crewmate/secondmate adapter only. It has no tracked primary turn-end guard, PreToolUse seatbelt, or watcher wake adapter, so a cursor PRIMARY intentionally falls back to the unknown-harness supervision snippet (docs/supervision-protocols/unknown.md) rather than getting a named snippet.

fm-spawn-dispatch-profile, fm-bootstrap, fm-composer-ghost, fm-grok-harness, and fm-secondmate-harness suites all pass on the rebased branch.

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