You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GSD users on a Cursor plan today have no first-class way to delegate slice execution to that subscription. The only "delegate to a vendor CLI" provider shipped today is claude-code-cli (#2382 + #2523), which only serves the Anthropic-subscription audience.
ToolId in src/resources/extensions/universal-config/types.ts already includes "cursor" at the config-discovery level — but no execution provider exists.
What's missing
A cursor-agent provider that:
Spawns the user's locally authenticated cursor-agent binary in headless streaming mode (-p --output-format stream-json) and parses NDJSON events into GSD's AssistantMessageEvent stream.
Surfaces every model the user's Cursor subscription exposes through /model.
Never touches Cursor credentials — auth state is owned entirely by cursor-agent login and/or CURSOR_API_KEY.
ADR #2509 documents the boundary that kept claude-code-cli compliant with Anthropic's third-party policy: delegate to the local CLI, never handle vendor credentials, never offer a vendor-login flow, never publish benchmarks. We adopt the same posture for Cursor:
Never read/store Cursor OAuth tokens — only check agent status or CURSOR_API_KEY env var.
Never re-implement cursor login; shell out if a /cursor login helper is added later.
No GSD-side metering or routing across vendors.
Cursor ToS §1.5(v)/(vii) — GSD is an orchestrator that delegates to Cursor, not a competing service; legal review before any benchmarking content.
3. Decision
Add a self-contained extension src/resources/extensions/cursor-cli/ mirroring the claude-code-cli/ layout 1:1, plus the minimal core plumbing needed for the new provider id.
Phase 1 — CLI provider (GA path)
Register cursor-agent via pi.registerProvider("cursor-agent", { authMode: "externalCli", api: "cursor-stream-json", ... }). Spawn cursor-agent -p --output-format stream-json with --model, --workspace, --trust, optional --resume; parse the NDJSON event union (system | assistant | tool_call | tool_result | result | stream_event | error); translate to AssistantMessageEvent. result.usage displayed only — no dollar estimation (matches the Ollama-style "billed against your plan" semantics).
Models seeded statically (composer-2.5, claude-sonnet-4-6, claude-opus-4-7, gpt-5.5, gemini-2.5-pro, grok-4), refreshed via cursor-agent --list-models at startup and on /cursor models.
Behind GSD_CURSOR_USE_SDK=1. Dynamic import("@cursor/sdk"); on resolution failure fall back to CLI path with a one-line warning. Justified by lower-latency event handoff and Cloud Agents access (Agent.create({ cloud: {...} })). Gated until SDK declares GA — @cursor/sdk is still public beta as of April 2026.
Phase 3 — /cursor slash commands
QoL on top of Phase 1: /cursor, /cursor login, /cursor logout, /cursor models, /cursor resume <session>. Pure shell-outs to cursor-agent.
Add "cursor-agent" to the provider picker, labeled "Cursor (via your subscription)".
src/wizard.ts
Add cursor-agent entry (no key required).
<extension loader manifest>
Register cursor-cli extension. Exact path to confirm during plan refinement.
Everything else lives under src/resources/extensions/cursor-cli/.
5. Known coupling — externalCli tool-lifecycle bridging (#5630 / #6311)
Issue #5630 and the open PR #6311 document that claude-code-cli never bridges tool lifecycle into the pi extension event bus, leaving write-gate verification as dead code under externalCli. Any new externalCli provider — including cursor-cli — inherits this gap.
Anyone already working on this? Happy to claim the issue and start once assigned.
I'm a first-time contributor to this repo; per CONTRIBUTING.md I will wait for assignment before any code lands. Lesson noted from #4101 (codex-cli was closed for missing issue link).
ADR: Cursor as Model Provider via cursor-agent CLI / @cursor/sdk
Status: Proposed
Date: 2026-05-19
Author: @pfurini
Related: #2509 (precedent ADR), #2382, #2523, #2532, #3246, #5630, #6311, #2555, #3485
1. Context and Problem Statement
The opportunity
Cursor (Anysphere) ships a paid subscription (Pro / Pro+ / Ultra / Teams) that bundles:
GSD users on a Cursor plan today have no first-class way to delegate slice execution to that subscription. The only "delegate to a vendor CLI" provider shipped today is
claude-code-cli(#2382 + #2523), which only serves the Anthropic-subscription audience.What GSD already has
authMode: 'externalCli'pattern for subscription-backed CLIs that ship a local agent harness.authMode: 'externalCli'framework inpackages/pi-ai.claude-code-cliextension undersrc/resources/extensions/claude-code-cli/(reference implementation).externalToolExecutionevent protocol so Agent Core does not redispatch tool calls the external CLI already executed.ToolIdinsrc/resources/extensions/universal-config/types.tsalready includes"cursor"at the config-discovery level — but no execution provider exists.What's missing
A
cursor-agentprovider that:cursor-agentbinary in headless streaming mode (-p --output-format stream-json) and parses NDJSON events into GSD'sAssistantMessageEventstream./model.cursor-agent loginand/orCURSOR_API_KEY.2. Compliance posture (lesson from #2509)
ADR #2509 documents the boundary that kept
claude-code-clicompliant with Anthropic's third-party policy: delegate to the local CLI, never handle vendor credentials, never offer a vendor-login flow, never publish benchmarks. We adopt the same posture for Cursor:agent statusorCURSOR_API_KEYenv var.cursor login; shell out if a/cursor loginhelper is added later.3. Decision
Add a self-contained extension
src/resources/extensions/cursor-cli/mirroring theclaude-code-cli/layout 1:1, plus the minimal core plumbing needed for the new provider id.Phase 1 — CLI provider (GA path)
Register
cursor-agentviapi.registerProvider("cursor-agent", { authMode: "externalCli", api: "cursor-stream-json", ... }). Spawncursor-agent -p --output-format stream-jsonwith--model,--workspace,--trust, optional--resume; parse the NDJSON event union (system | assistant | tool_call | tool_result | result | stream_event | error); translate toAssistantMessageEvent.result.usagedisplayed only — no dollar estimation (matches the Ollama-style "billed against your plan" semantics).Models seeded statically (
composer-2.5,claude-sonnet-4-6,claude-opus-4-7,gpt-5.5,gemini-2.5-pro,grok-4), refreshed viacursor-agent --list-modelsat startup and on/cursor models.Kill-switch:
GSD_CURSOR_DISABLE=1. Debug:GSD_CURSOR_DEBUG=1.Phase 2 —
@cursor/sdkadapter (opt-in)Behind
GSD_CURSOR_USE_SDK=1. Dynamicimport("@cursor/sdk"); on resolution failure fall back to CLI path with a one-line warning. Justified by lower-latency event handoff and Cloud Agents access (Agent.create({ cloud: {...} })). Gated until SDK declares GA —@cursor/sdkis still public beta as of April 2026.Phase 3 —
/cursorslash commandsQoL on top of Phase 1:
/cursor,/cursor login,/cursor logout,/cursor models,/cursor resume <session>. Pure shell-outs tocursor-agent.4. Minimal core changes (mirrors
claude-code-cliprecedent)packages/pi-ai/src/types.ts"cursor-agent"toKnownProvider;"cursor-stream-json"(Phase 1) and"cursor-sdk"(Phase 2) toKnownApi.packages/pi-ai/src/env-api-keys.ts"cursor-agent"→process.env.CURSOR_API_KEY ?? "cursor-agent"placeholder.src/onboarding.ts"cursor-agent"to the provider picker, labeled "Cursor (via your subscription)".src/wizard.tscursor-agententry (no key required).<extension loader manifest>cursor-cliextension. Exact path to confirm during plan refinement.Everything else lives under
src/resources/extensions/cursor-cli/.5. Known coupling — externalCli tool-lifecycle bridging (#5630 / #6311)
Issue #5630 and the open PR #6311 document that
claude-code-clinever bridges tool lifecycle into the pi extension event bus, leaving write-gate verification as dead code underexternalCli. Any newexternalCliprovider — includingcursor-cli— inherits this gap.Two options, maintainer steer requested:
6. Risks
cursor-agentvsagent,.cmd/.exeon Windows)claude.exe;CURSOR_AGENT_BINoverride env.thinkingevents suppressed in-pmode → no reasoning visibility in TUItool_progress.result.usagein TUI footer (mirrors Claude Code token display); document quota in onboarding.--trust/--forceautonomous-edit semantics--trustalways (slice cwd already trusted);--forceonly when the slice declares write intent — same gating asclaude-code-cli.clearReadinessCache()on/cursor logincompletion and onCURSOR_API_KEYchange at session start.unregisterProvider("cursor-agent").7. Open questions
--forcepolicy? Recommendation: opt-in per slice via existing write-intent flag; TUI badge when--forceis on.session_idfromsystem/init; opt-in/cursor resume; fresh session per slice by default./cursor models+ 24h background timer; static seed wins for capabilities, dynamic adds new ids.--sandboxunset (CLI default); documentCURSOR_SANDBOX=enabledenv override.8. Acceptance criteria (Phase 1)
cursor-agentinstalled and authenticated sees Cursor models in/modelwithin 30 s of GSD startup./model cursor-agent/composer-2.5switches the active model; next slice streams text/tool events into the TUI.externalToolExecutionso Agent Core does not redispatch.result.usageis captured and displayed in the slice footer.GSD_CURSOR_DISABLE=1keeps the extension dormant at startup.claude-code-cliprovider behaviour — both coexist viaKnownProviderdiscrimination.9. Out of scope
Agent.create({ cloud: {...} })) — Phase-2+ once a concrete use case lands.10. Request to maintainers
I'm a first-time contributor to this repo; per
CONTRIBUTING.mdI will wait for assignment before any code lands. Lesson noted from #4101 (codex-cli was closed for missing issue link).