Skip to content

feat(cli): setup-cursor — print Cursor setup steps for OmniRoute - #4291

Merged
diegosouzapw merged 1 commit into
release/v3.8.30from
feat/cursor-cli
Jun 19, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.30from
feat/cursor-cli

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

What

CLI #7. omniroute setup-cursor guides Cursor to use OmniRoute.

Cursor stores its OpenAI key + "Override OpenAI Base URL" in an opaque SQLite DB (state.vscdb) with no stable schema — not safe to file-write. So this command prints the exact in-app steps and lists real model names from /v1/models.

  • Resolves apiBase WITH /v1 (Cursor appends /chat/completions) + key (--remote/--api-key → active context → localhost).
  • Prints Settings → Models → Override OpenAI Base URL + key + model-name steps.
  • Caveat surfaced: the custom base URL powers Cursor's chat panel only — Composer / inline-edit / autocomplete stay on Cursor's backend.

Validation

  • Remote (VPS v3.8.30): real output lists the VPS's glm models + correct /v1 base URL.
  • 4 unit tests; check:cli-i18n ✓.

Series: …Cline #4280 · Kilo #4284 · Continue #4289 · Cursor (this). Next: Roo, Crush, Goose, Qwen Code, Gemini CLI, Aider.

🤖 Generated with Claude Code

CLI #7 of the series. Cursor stores its OpenAI key + "Override OpenAI Base URL"
in an opaque SQLite DB (state.vscdb) with no stable schema — not safe to
file-write. So `omniroute setup-cursor` prints the exact in-app steps and lists
real model names from /v1/models.

- Resolves apiBase WITH /v1 (Cursor appends /chat/completions) + key from
  --remote/--api-key → active context → localhost.
- Prints Settings → Models → Override OpenAI Base URL + key + model-name steps,
  with a clear caveat that the custom base URL powers Cursor's CHAT panel only
  (Composer / inline-edit / autocomplete stay on Cursor's backend).

Researched against current Cursor behavior. Tests: resolveCursorTarget (/v1, key),
buildCursorInstructions (base URL + /v1 note + model samples + caveat). 4 unit
tests; check:cli-i18n green.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@diegosouzapw
diegosouzapw merged commit 9616b65 into release/v3.8.30 Jun 19, 2026
4 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the setup-cursor command to guide users through manually configuring Cursor to use OmniRoute, complete with unit tests and updated documentation. The feedback suggests simplifying a redundant URL string replacement when fetching models and using optional chaining to safely handle potential null responses from the models endpoint.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

try {
const headers = { "Content-Type": "application/json" };
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
const res = await fetch(`${apiBase.replace(/\/v1$/, "")}/v1/models`, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since apiBase is guaranteed to end with /v1 (and have no trailing slashes) due to ensureV1, the regex replacement apiBase.replace(/\/v1$/, "") followed by appending /v1/models is redundant. It can be simplified directly to ${apiBase}/models.

Suggested change
const res = await fetch(`${apiBase.replace(/\/v1$/, "")}/v1/models`, {
const res = await fetch(`${apiBase}/models`, {

});
if (!res.ok) return [];
const body = await res.json();
const list = Array.isArray(body) ? body : body.data ?? body.models ?? [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the server returns null as a valid JSON response, body will be null. Accessing body.data directly will throw a TypeError. While this is caught by the try-catch block, using optional chaining (body?.data ?? body?.models ?? []) is safer and prevents unnecessary exceptions.

Suggested change
const list = Array.isArray(body) ? body : body.data ?? body.models ?? [];
const list = Array.isArray(body) ? body : (body?.data ?? body?.models ?? []);

@diegosouzapw
diegosouzapw deleted the feat/cursor-cli branch June 19, 2026 16:22
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…aper-inference#4291)

CLI cheaper-inference#7 of the series. Cursor stores its OpenAI key + "Override OpenAI Base URL"
in an opaque SQLite DB (state.vscdb) with no stable schema — not safe to
file-write. So `omniroute setup-cursor` prints the exact in-app steps and lists
real model names from /v1/models.

- Resolves apiBase WITH /v1 (Cursor appends /chat/completions) + key from
  --remote/--api-key → active context → localhost.
- Prints Settings → Models → Override OpenAI Base URL + key + model-name steps,
  with a clear caveat that the custom base URL powers Cursor's CHAT panel only
  (Composer / inline-edit / autocomplete stay on Cursor's backend).

Researched against current Cursor behavior. Tests: resolveCursorTarget (/v1, key),
buildCursorInstructions (base URL + /v1 note + model samples + caveat). 4 unit
tests; check:cli-i18n green.
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.

1 participant