Skip to content

feat(sse): Cursor plan images via Agent CLI (IMAGE_PROVIDERS.cursor) - #10842

Merged
diegosouzapw merged 5 commits into
release/v3.8.50from
feat/8338-cursor-agent-image-provider
Aug 20, 2026
Merged

diegosouzapw merged 5 commits into
release/v3.8.50from
feat/8338-cursor-agent-image-provider

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Summary

Carries forward #8338 (@valvesss) — Cursor plan image generation via the Agent CLI's native generateImage tool, reusing the existing Cursor OAuth/API-key chat connection. Opened as a new PR because the fork (cold-code-labs/OmniRoute-1, an organization fork) does not support "allow edits from maintainers" — GitHub only grants that for personal-account forks — so the pending review fixes below could not be pushed to the original branch, and #8338 had also drifted into merge conflicts against the current release tip.

All 3 of the original commits are preserved with @valvesss's authorship intact:

  1. feat(sse): Cursor plan images via Agent CLI — the original feature.
  2. fix(cursor-image): allowlist CLI model + clamp request timeout — @valvesss's own response to the first review round (model argv allowlist against IMAGE_PROVIDERS.cursor.models, timeout_ms server-side clamp).
  3. fix(sse): loopback/LAN-gate the cursor-agent-image spawn path (Hard Rules #15/#17) — @valvesss's response to the second review round (this is the first image-provider handler that spawns a local process; it's now gated on the trusted AUTHZ_HEADER_PEER_LOCALITY verdict so a leaked API key via a tunnel can't trigger a spawn from a remote caller — mirrors every other spawn-capable route in the codebase).

Plus 2 small commits from me reconciling the rebase:

  • A test fix: the allowlist test and the security-guard test were written against diverging histories of [v3.8.50] feat(sse): Cursor plan images via Agent CLI (IMAGE_PROVIDERS.cursor) #8338 and didn't know about each other; cherry-picking both exposed one test that needed peerLocality threaded through.
  • A file-size baseline bump for imageRegistry.ts (+14 lines, the new cursor registry entry — same "provider catalog, no split" rationale as prior registry rebaselines).

Validation (TDD, Hard Rule #18)

  • tests/unit/cursor-agent-image.test.ts: 14/14 pass (includes the argv-injection defense, the timeout clamp, and both loopback-gate tests — non-local caller rejected before spawn, and fail-closed when peerLocality is missing).
  • tests/unit/image-generation-route.test.ts + tests/unit/image-generation-handler.test.ts: 79/79 pass combined, no regression in the other ~40 image providers sharing this route.
  • npm run typecheck:core — clean.
  • check:file-size, check:complexity, check:cognitive-complexity, check:changelog-integrity — all green (file-size baseline bump documented above).

Related

🙏 Full credit to @valvesss for the design (seat-bridge via Agent CLI, locked prompt, per-request workspace) and for responding to both review rounds — this PR only carries the work across the org-fork gap.

valvesss and others added 5 commits August 20, 2026 08:57
Add cursor-agent-image format that reuses the chat Cursor OAuth connection and
drives the Agent CLI native generateImage tool with a locked prompt and
per-request workspace. Chat AgentService rejects built-ins; CLI is the seat path.
 review)

Two mechanical hardening fixes requested in review:

- Model: the request's `model=cursor/<…>` flowed unfiltered into the Agent CLI
  `--model` argv. Add resolveCursorImageModel() — an allowlist derived from
  IMAGE_PROVIDERS.cursor.models (auto | composer-2 | composer-2.5), mirroring the
  auggie executor. Unknown or flag-shaped values fall back to "auto" and never
  reach argv. Operator overrides (connection psd / CURSOR_IMG_MODEL) stay trusted.

- Timeout: request `timeout_ms` had no upper bound while the shared Cursor seat
  has only CURSOR_IMG_MAX_CONCURRENT (default 2) slots. Add
  resolveCursorImageTimeoutMs() clamping the caller value to MAX_TIMEOUT_MS
  (300000ms); the operator default (CURSOR_IMG_TIMEOUT_MS) stays uncapped.

Tests: +3 (12/12) — allowlist unit test, end-to-end proof a flag-shaped model
resolves to "auto" in argv, and the timeout clamp.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ules #15/#17)

handleCursorAgentImageGeneration spawns the Cursor `agent` CLI, but
POST /v1/images/generations is shared by ~40 non-spawning image providers
that remote callers legitimately use, so the whole route can't be
classified LOCAL_ONLY without breaking them. Instead the handler now
rejects before any credential lookup or spawn unless the trusted
AUTHZ_HEADER_PEER_LOCALITY verdict (stamped by the authz pipeline from
the real TCP peer, never the spoofable Host header) is "loopback" or
"lan" — mirroring the policy every other LOCAL_ONLY route already gets.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
… test

The model-allowlist test (from the allowlist/timeout-clamp commit) and the
loopback/LAN guard (from the security-guard commit) were written independently
against diverging histories of this PR and didn't know about each other —
cherry-picking both here exposed the gap: this one test still called
handleCursorAgentImageGeneration without peerLocality, so the guard's
fail-closed default rejected it with 403 before reaching the argv-sanitization
logic the test actually exercises.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw
diegosouzapw merged commit bbcfb73 into release/v3.8.50 Aug 20, 2026
11 checks passed
diegosouzapw added a commit that referenced this pull request Aug 20, 2026
#10737)

Merged — locally validated (fusion-vision-panel-3378 test green, file-size/changelog gates green) after resolving base-drift against #10842/#10838 (both landed just before).
@diegosouzapw
diegosouzapw deleted the feat/8338-cursor-agent-image-provider branch August 21, 2026 15:32
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…heaper-inference#10842)

Merged — locally validated (60/60 combined image-generation tests, typecheck:core clean, complexity/cognitive/file-size/changelog gates green, small rebaseline for the combined imageRegistry.ts growth).
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
cheaper-inference#10737)

Merged — locally validated (fusion-vision-panel-3378 test green, file-size/changelog gates green) after resolving base-drift against cheaper-inference#10842/cheaper-inference#10838 (both landed just before).
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.

3 participants