Skip to content

feat(run,launch): add Cursor through cursor-agent, built-in fable@cursor - #74

Draft
runewright[bot] wants to merge 1 commit into
mainfrom
change/cursor-agent-surface
Draft

runewright[bot] wants to merge 1 commit into
mainfrom
change/cursor-agent-surface

Conversation

@runewright

@runewright runewright Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

rune run and rune launch get Cursor through its official cursor-agent CLI, and fable@cursor works without config.

Plan

Change cursor-agent-surface: proposal, design, two ADDED deltas (harness-run-command, harness-launch-command), tasks, and adr.md under docs/changes/cursor-agent-surface/. Proof under docs/proofs/cursor-agent-surface/. Reviewed by Fable, astra, and grok before the push. Their fixes are in, one rejected in tasks.md.

Changes

  • Add Surface::Cursor in src/cli/surface/cursor.rs. A surface is one coding tool that rune run can start. The run is cursor-agent -p --output-format json --workspace <repo> --trust, prompt on stdin with the system prompt in front. Read-only adds --mode ask, workspace-write --force --sandbox enabled. result is the text, usage.outputTokens the completion tokens, is_error fails the run.
  • Keep only -e and --endpoint from a Cursor profile. cursor-agent accepts flags its help does not list and reads a positional as a subcommand or the prompt, so everything else is dropped with a warning that never shows the value. CURSOR_API_KEY goes in the profile env.
  • Refuse a read-only run when the cli-config.json the tool reads sets approvalMode: unrestricted, as defense in depth behind ask mode.
  • --clean needs CURSOR_API_KEY (the browser login lives in the Keychain) and moves HOME and CURSOR_CONFIG_DIR into the clean root. A sandboxed Keychain failure gets a hint to run rune outside the sandbox.
  • rune launch cursor starts cursor-agent unless tools.cursor.binary says otherwise, and passes the profile route as --model.
  • Built-in fable@cursor profile and fable-cursor route (claude-fable-5-1-high). BUILT_IN_ROUTES holds every built-in route. Config of the same name wins.

Testing

  • cargo test, clippy, fmt, rune spec validate, rune docs check clean. 34 new tests.
  • Proof docs/proofs/cursor-agent-surface/proof.{cast,gif,txt}, one scene per scenario against a fake cursor-agent.
  • Live outside the sandbox: fable@cursor returned pong. A read-only run asked for a file wrote nothing, under auto-review and a copied unrestricted config. Workspace-write created it.

Proof: launch default and configured binary, profile model, built-in fable, read-only and workspace-write, error result, clean without and with a key, unrestricted approval refused, sandbox hint, widening flags dropped, unlisted flag dropped, subcommand dropped

Release Notes

  • rune run cursor and rune launch cursor start Cursor's cursor-agent. fable@cursor selects Claude Fable 5.1 on Cursor without config. Cursor labels its Fable models "NO ZDR". Run rune outside the harness sandbox.

Add Surface::Cursor and src/cli/surface/cursor.rs. rune run cursor starts
cursor-agent -p --output-format json --workspace <repo> --trust, sends the
prompt on stdin with the system prompt in front, and reads the one result
object: result is the text, usage.outputTokens the completion tokens,
is_error fails with the message or the subtype. Read-only adds --mode ask,
workspace-write adds --force --sandbox enabled.

A profile keeps only -e and --endpoint. cursor-agent accepts options its
help does not list (--data-dir, --allowed-tools) and reads a positional as
a subcommand or the prompt, so every other argument is dropped with a
warning that names the flag and never the value. --api-key is dropped too;
the key belongs in the profile env as CURSOR_API_KEY. A read-only run
refuses when the cli-config.json the tool reads (CURSOR_CONFIG_DIR,
$XDG_CONFIG_HOME/cursor, ~/.cursor) sets approvalMode unrestricted, as
defense in depth behind ask mode.

--clean needs a nonempty CURSOR_API_KEY in the child's environment, profile
env included, because the browser login lives in the Keychain; HOME and
CURSOR_CONFIG_DIR move into the clean root. A failure that shows the
Keychain signature of a sandboxed process gets a hint to run rune outside
the harness sandbox.

rune launch cursor starts cursor-agent unless tools.cursor.binary says
otherwise, because cursor on a Mac opens the editor. A Cursor launch passes
the profile route as --model, and rune run strips that generated pair.
BUILT_IN_PROFILES gives fable@cursor without config through the built-in
route fable-cursor (claude-fable-5-1-high); the built-in routes move into
one BUILT_IN_ROUTES table. A configured profile or route of the same name
replaces the built-in one.

Change cursor-agent-surface: proposal, design, ADR, two ADDED deltas,
tasks, pull-request. Proof under docs/proofs/cursor-agent-surface with
one scene per scenario. 34 new tests. Reviewed by Fable, astra, and grok;
each finding fixed or rejected in tasks.md.

Co-Authored-By: Martin Zeman <N4M3Z@users.noreply.github.com>
@github-actions github-actions Bot added size:xlarge auto: changed-lines bucket area:docs auto: documentation and markdown labels Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

review/correctness stood down on 47ad84d9: free lanes only: deterministic check quality is pending on this head. Apply review:runeseer to force a paid round.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

review/correctness stood down on 47ad84d9: free lanes only: deterministic check quality is not green on this head. Apply review:runeseer to force a paid round.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

review/correctness stood down on 47ad84d9: free lanes only: deterministic check quality is not green on this head. Apply review:runeseer to force a paid round.

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

Labels

area:docs auto: documentation and markdown size:xlarge auto: changed-lines bucket

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants