fix: Cursor catalog gather isolation and canonical dual-mode OAuth - #23
Merged
cursor[bot] merged 1 commit intoAug 27, 2026
Merged
Conversation
A Cursor dashboard-key exchange or GetUsableModels throw no longer rejects Promise.all catalog gather; Cursor degrades to cached/static models so unrelated providers still appear. Restrict the dual-mode OAuth surface to canonical providers.cursor. Custom adapter:cursor rows can still use keys, but they no longer show OAuth controls the backend cannot honor. Co-authored-by: pavelhov <pavelhov@users.noreply.github.com>
pavelhov
marked this pull request as ready for review
August 27, 2026 20:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Findings
This PR addresses two Codex review findings from the Cursor dual-mode work (
160b574). It does not rework packaging, test runners, or unrelated providers.P1 — Cursor exchange/discovery throw rejected the whole catalog
src/codex/catalog/provider-fetch.tsmaterializes a Cursor dashboard key (materializeCursorRunBearer) then callsGetUsableModels. A transient exchange 500 throws before the existing{ ok: false }degradation path. Providers are gathered withPromise.all, so one Cursor failure rejected the entire model catalog, including unrelated providers.Fix: catch exchange/discovery throws (and keep the existing non-ok degradation path). Cursor falls back to stale cache, else the configured/static seed. Other providers continue to appear.
Contract: a Cursor-only exchange or discovery error must not fail catalog gather. Cursor degrades; siblings stay.
P2 — Dual-mode OAuth UI on non-canonical
adapter: "cursor"rowsgui/src/provider-workspace/auth.tstreated everyadapter: "cursor"row as dual-mode. Backend OAuth endpoints only accept canonical provider idcursor. A provider namedcustom-cursortherefore showed OAuth controls that always fail.Fix:
isCursorKeyAuthOverrideis canonicalproviders.cursoronly (name === "cursor"andadapter === "cursor"). OAuth account-pool fetches use that helper. Key-only custom cursor adapters still get the key surface; they do not get OAuth UI that cannot succeed.Contract: canonical
providers.cursorstill shows accounts + API-key pool. A custom id withadapter: "cursor"does not get the dual-mode OAuth surface.ToS warning copy is unchanged. No new Cursor private RPCs.
Tests
tests/cursor-hardening.test.ts: exchange throw andGetUsableModelsthrow/500 must not rejectPromise.all; sibling providers still appear; Cursor degrades to static seed or stale cache.tests/cursor-apikey-dual-mode.test.ts:custom-cursoris not dual-mode; canonicalcursorstill is.gui/tests/cursor-apikey-dual-mode.test.tsx: custom cursor Settings shows keys only, not OAuth login.Verified
Local (Bun 1.3.14):
bun test tests/cursor-hardening.test.ts tests/cursor-apikey-dual-mode.test.tscd gui && bun test tests/cursor-apikey-dual-mode.test.tsxbun run typecheckbun run privacy:scancd gui && bun run lint && bun run lint:i18n && bun run test && bun run buildbun run test:parallel(607 files passed)cd docs-site && bun run buildGUI dual-mode restriction verified via
ProviderAuthPanelhappy-dom tests, not a live dashboard session. Canonical Cursor still renders accounts + API-key pool;custom-cursorrenders keys only.Merge target is
development. Do not push tomain.