Skip to content

feat(cli): setup-cline — configure Cline for OmniRoute (CLI files + VS Code hints) - #4280

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

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

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

What

CLI #4 of the series. omniroute setup-cline configures the Cline AI agent to use OmniRoute.

Cline is special: its VS Code extension keeps config in VS Code's opaque globalStorage (not file-writable), while its CLI/standalone mode reads ~/.cline/data/. So this command does both (per owner decision):

  • Writes ~/.cline/data/globalState.json (act/planModeApiProvider=openai, openAiBaseUrl = ROOT url without /v1 — Cline appends /v1/chat/completions — openAiModelId + planModeOpenAiModelId) and ~/.cline/data/secrets.json (openAiApiKey), merged to preserve existing state. Matches the dashboard cli-tools/cline-settings schema.
  • Prints the exact VS Code extension settings (Base URL / key / model) to paste.
  • Remote-aware (--remote/--api-key → active context → localhost); model via --model or interactive pick from /v1/models (no auto-discovery in Cline).

Researched against current Cline docs (saoudrizwan.claude-dev): confirmed the OpenAI-compatible keys, the Plan/Act split, and that openAiBaseUrl must be the root (no /v1).

Validation

  • Remote (VPS v3.8.30): setup-cline --remote --dry-run --model glm/glm-5-turbo → correct globalState + secrets + UI hints.
  • Cline's wire (/v1/chat/completions) already validated end-to-end → "OK".
  • 6 unit tests; check:cli-i18n ✓.

Establishes the strategy for the remaining VS Code extensions (Kilo, Continue, Roo).

🤖 Generated with Claude Code

…S Code hints)

CLI #4 of the series. Cline's VS Code extension keeps config in opaque VS Code
globalStorage (not file-writable); its CLI/standalone mode reads ~/.cline/data/.

`omniroute setup-cline`:
- writes ~/.cline/data/globalState.json (act/planModeApiProvider=openai,
  openAiBaseUrl = ROOT url WITHOUT /v1 — Cline appends /v1/chat/completions —
  openAiModelId + planModeOpenAiModelId) and ~/.cline/data/secrets.json
  (openAiApiKey), both merged to preserve existing state. Matches the dashboard
  cli-tools/cline-settings schema.
- remote-aware (--remote/--api-key → active context → localhost).
- model resolved via --model or an interactive pick from /v1/models (Cline has
  no model auto-discovery).
- prints the exact VS Code extension settings (Base URL/key/model) to paste,
  since the extension's storage can't be written directly.

Researched against the current Cline docs (saoudrizwan.claude-dev): confirmed
the openai-compatible keys, the Plan/Act split, and that openAiBaseUrl must be
the ROOT (no /v1). Cline's wire (/v1/chat/completions) already validated → "OK".

Tests: buildClineGlobalState (provider+root+model, merge-preserve),
buildClineSecrets (key + placeholder), resolveClineTarget (/v1 strip, key win).
6 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.

@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-cline CLI command to configure the Cline AI coding agent for OmniRoute, along with associated unit tests and documentation updates. The review feedback identifies a few key improvements: preserving existing API keys in secrets.json instead of overwriting them with a fallback placeholder when no new key is provided, registering the missing --context option in the CLI command definition, and adding a unit test to verify key preservation.

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.

Comment on lines +64 to +66
export function buildClineSecrets(existing, { apiKey }) {
return { ...(existing || {}), openAiApiKey: apiKey || "sk_omniroute" };
}

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.

high

If apiKey is not provided (e.g., when running the command without an active context or environment variable), buildClineSecrets will overwrite any existing openAiApiKey in secrets.json with the fallback placeholder 'sk_omniroute'. To prevent losing an already configured key, we should fall back to the existing key if present before using the placeholder.

Suggested change
export function buildClineSecrets(existing, { apiKey }) {
return { ...(existing || {}), openAiApiKey: apiKey || "sk_omniroute" };
}
export function buildClineSecrets(existing, { apiKey }) {
return { ...(existing || {}), openAiApiKey: apiKey || existing?.openAiApiKey || "sk_omniroute" };
}

Comment on lines +149 to +155
.option("--port <port>", "Local OmniRoute port (ignored when --remote is set)", "20128")
.option("--remote <url>", "Remote OmniRoute URL, e.g. http://192.168.0.15:20128")
.option("--api-key <key>", "OmniRoute API key (defaults to OMNIROUTE_API_KEY env var)")
.option("--model <id>", "Model id for Cline (required unless picked interactively)")
.option("--cline-dir <dir>", "Cline data dir (default: ~/.cline/data)")
.option("--yes", "Non-interactive: do not prompt (requires --model)")
.option("--dry-run", "Print what would be written without touching the filesystem")

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

The resolveClineTarget function attempts to read opts.context to resolve the active context, but the --context option is not registered in the CLI command definition. Adding the --context <name> option allows users to specify a context directly from the command line.

    .option("--port <port>", "Local OmniRoute port (ignored when --remote is set)", "20128")
    .option("--remote <url>", "Remote OmniRoute URL, e.g. http://192.168.0.15:20128")
    .option("--context <name>", "OmniRoute context name")
    .option("--api-key <key>", "OmniRoute API key (defaults to OMNIROUTE_API_KEY env var)")
    .option("--model <id>", "Model id for Cline (required unless picked interactively)")
    .option("--cline-dir <dir>", "Cline data dir (default: ~/.cline/data)")
    .option("--yes", "Non-interactive: do not prompt (requires --model)")
    .option("--dry-run", "Print what would be written without touching the filesystem")

Comment on lines +34 to +36
test("buildClineSecrets falls back to a placeholder when no key", () => {
assert.equal(buildClineSecrets({}, { apiKey: "" }).openAiApiKey, "sk_omniroute");
});

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

Add a unit test to verify that buildClineSecrets preserves the existing key when no new key is provided.

Suggested change
test("buildClineSecrets falls back to a placeholder when no key", () => {
assert.equal(buildClineSecrets({}, { apiKey: "" }).openAiApiKey, "sk_omniroute");
});
test("buildClineSecrets falls back to a placeholder when no key", () => {
assert.equal(buildClineSecrets({}, { apiKey: "" }).openAiApiKey, "sk_omniroute");
});
test("buildClineSecrets preserves existing key if no new key is provided", () => {
const sec = buildClineSecrets({ openAiApiKey: "existing-key" }, { apiKey: "" });
assert.equal(sec.openAiApiKey, "existing-key");
});

@diegosouzapw
diegosouzapw merged commit 158a224 into release/v3.8.30 Jun 19, 2026
4 checks passed
@diegosouzapw
diegosouzapw deleted the feat/cline-cli branch June 19, 2026 15:31
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…S Code hints) (diegosouzapw#4280)

CLI diegosouzapw#4 of the series. Cline's VS Code extension keeps config in opaque VS Code
globalStorage (not file-writable); its CLI/standalone mode reads ~/.cline/data/.

`omniroute setup-cline`:
- writes ~/.cline/data/globalState.json (act/planModeApiProvider=openai,
  openAiBaseUrl = ROOT url WITHOUT /v1 — Cline appends /v1/chat/completions —
  openAiModelId + planModeOpenAiModelId) and ~/.cline/data/secrets.json
  (openAiApiKey), both merged to preserve existing state. Matches the dashboard
  cli-tools/cline-settings schema.
- remote-aware (--remote/--api-key → active context → localhost).
- model resolved via --model or an interactive pick from /v1/models (Cline has
  no model auto-discovery).
- prints the exact VS Code extension settings (Base URL/key/model) to paste,
  since the extension's storage can't be written directly.

Researched against the current Cline docs (saoudrizwan.claude-dev): confirmed
the openai-compatible keys, the Plan/Act split, and that openAiBaseUrl must be
the ROOT (no /v1). Cline's wire (/v1/chat/completions) already validated → "OK".

Tests: buildClineGlobalState (provider+root+model, merge-preserve),
buildClineSecrets (key + placeholder), resolveClineTarget (/v1 strip, key win).
6 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