Skip to content

feat(agents): add cursor CLI agent backend#107

Open
valvesss wants to merge 1 commit into
vercel-labs:mainfrom
cold-code-labs:feat/cursor-cli-agent
Open

feat(agents): add cursor CLI agent backend#107
valvesss wants to merge 1 commit into
vercel-labs:mainfrom
cold-code-labs:feat/cursor-cli-agent

Conversation

@valvesss

Copy link
Copy Markdown

What changed

Adds a fourth agent backend, --agent cursor, that drives the Cursor CLI
(cursor-agent) headless instead of talking to a model endpoint over HTTP.
Cursor runs its own agent loop — the CLI does the Read/Glob/Shell tool calls
against the checkout and streams newline-delimited JSON events, which the new
CursorCliPlugin parses into deepsec's AgentProgress stream and turns into
findings JSON.

Why

The Cursor "seat" is reachable over an OpenAI/Anthropic-compatible message
API, but that path does not relay agentic tool_use — driving it through
the existing claude / codex / pi backends produced 1 turn, 0 tool calls,
and 0 findings on obviously-vulnerable code (the agent never reads a file).
The Cursor CLI carries the tool-use loop natively, so a CLI-spawning backend
(like the codex path, but for cursor-agent) is what makes the Cursor seat
usable as a deepsec engine.

Verified end-to-end against an intentionally-vulnerable fixture: --agent cursor ran 9 tool calls over 3 turns and returned 3 correct findings
(critical SQL injection, critical command injection, hardcoded secret) —
matching what the claude backend finds on the same input.

Verification

  • pnpm test:unit passes (2138 tests, incl. a new hermetic plugin test)
  • pnpm -r build (typecheck) passes
  • pnpm lint passes (the one remaining warning is pre-existing in
    sandbox/setup.ts, untouched here)
  • pnpm knip passes
  • pnpm test full run — the e2e project is gated on Vercel Sandbox
    credentials (DEEPSEC_E2E_LIVE_SANDBOX) and this change doesn't touch
    the sandbox path, so it wasn't run

Notes for reviewer

  • Auth is out-of-band. The plugin injects no credential — cursor-agent
    uses its own login session (~/.cursor) or CURSOR_API_KEY. cursor is
    therefore intentionally not added to preflight's KNOWN_BACKENDS, so
    assertAgentCredential no-ops for it (the AI-gateway env is irrelevant to
    this backend). Binary path overridable via CURSOR_AGENT_BIN.
  • Sandboxing. The CLI is spawned with --force (no interactive approvals)
    so it can read + run shell inside the checkout; the prompt instructs it to
    read only. Unlike the codex backend, this does not yet apply an
    env-allowlist or a read-only CLI mode — noted as a follow-up. It fits the
    same trust model as running codex/claude locally against a repo.
  • Cost. The Cursor CLI doesn't report a per-call cost, so the batch
    readout shows tokens but omits the $ figure (same handling as a missing
    price entry on the codex backend).
  • New backend is additive: default agent, existing backends, and all data
    formats are unchanged.

@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

@valvesss is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@valvesss
valvesss force-pushed the feat/cursor-cli-agent branch from 204a0a8 to 5f03ce8 Compare July 15, 2026 15:38
Adds a fourth agent backend, `--agent cursor`, that drives the Cursor
CLI (`cursor-agent`) headless instead of talking to a model endpoint
over HTTP. Cursor runs its own agent loop — the CLI does the Read /
Glob / Shell tool calls against the checkout, streams newline-delimited
JSON events, and the plugin parses those into deepsec's AgentProgress
stream and pulls the findings JSON out of the final message.

Why a CLI backend: the Cursor "seat" is reachable over an
OpenAI/Anthropic-compatible *message* API, but that path does not relay
agentic `tool_use` — driving it via the claude/codex/pi backends
produced 0 tool calls and 0 findings. The CLI carries the tool-use loop
natively.

- New `CursorCliPlugin` (`packages/processor/src/agents/cursor-cli.ts`),
  registered in `createDefaultAgentRegistry`; implements `investigate`
  and `revalidate` with a one-shot JSON-repair fallback, reusing the
  shared prompt/parse helpers.
- Default model `auto` (`agent-defaults.ts`); `--agent cursor` resolves
  as-is. Auth is the user's `cursor-agent` login or `CURSOR_API_KEY`;
  `cursor` is intentionally left out of preflight's KNOWN_BACKENDS so
  the gateway credential check is skipped. Binary overridable via
  `CURSOR_AGENT_BIN`.
- Tests: hermetic plugin test driving a fake `cursor-agent` that emits a
  canned stream-json transcript; registry / default-model /
  resolve-agent-type coverage.
- Docs: models.md (backend table, CLI examples, a "Cursor CLI backend"
  section) and configuration.md (defaultAgent values + CURSOR_* env).

Co-authored-by: Vitor Alves <vitoralvesinfo@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@valvesss
valvesss force-pushed the feat/cursor-cli-agent branch from 5f03ce8 to bb1b541 Compare July 15, 2026 15:52
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