Skip to content

feat(cli): Codex CLI launcher + setup commands - #4270

Merged
diegosouzapw merged 2 commits into
release/v3.8.30from
feat/codex-cli-commands
Jun 19, 2026
Merged

diegosouzapw merged 2 commits into
release/v3.8.30from
feat/codex-cli-commands

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Consolidates work-in-progress that was sitting uncommitted on the shared checkout into a tracked PR (per operator request during the v3.8.29 release wrap-up). Reconstructed cleanly on release/v3.8.30.

What

  • omniroute launch-codex — boots OmniRoute (if needed) and launches the OpenAI Codex CLI pointed at it (local or remote VPS), no manual env/config editing.
  • omniroute setup-codex — generates ~/.codex profile files from OmniRoute's live model catalog.
  • Registered in the command registry; en.json + pt-BR.json locale sections added (keeps the cli-i18n-catalog top-level parity gate green); CODEX-CLI-CONFIGURATION.md refreshed.
  • Separate commit: .vscode/settings.json — disables git auto-repo-detection for the nested worktrees (perf; editor-only).

Validation

  • both Codex command modules load + export their register fns; registry registerCommands intact
  • cli-i18n-catalog test 7/7 (en keys complete + pt-BR parity)
  • lint: 0 errors (bin/cli is eslint-ignored)

Note: drop the chore(vscode) commit in review if the editor settings aren't wanted repo-wide.

Two new CLI subcommands mirroring the `launch`/`configure` pattern, for driving the
OpenAI Codex CLI against OmniRoute:

- `omniroute launch-codex` — boots OmniRoute (if needed) and launches Codex CLI
  pointed at it (local or remote VPS), with no manual env/config editing.
- `omniroute setup-codex` — generates ~/.codex profile files from OmniRoute's live
  model catalog.

Registered in the command registry; en.json + pt-BR.json locale sections added
(keeps the cli-i18n-catalog top-level parity gate green). CODEX-CLI-CONFIGURATION.md
refreshed. Consolidated from work-in-progress that was uncommitted on the shared
checkout; reconstructed on release/v3.8.30.
Disable VS Code's git auto-repository-detection / submodule scan / autofetch so the
Source Control view stops indexing the ~44 nested repos (worktrees + _references/*
+ _mono_repo/*), which caused constant "validating" churn. Only the root repo is
tracked. Editor-only settings; no runtime impact.
@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 two new CLI commands, launch-codex and setup-codex, along with localized descriptions, documentation updates, and VS Code settings to optimize Git performance. The feedback highlights several areas for improvement: making URL parsing more robust against trailing slashes in both commands, aligning the model categorization logic in setup-codex.mjs with the updated documentation, and adding safer error handling and response parsing to prevent potential runtime crashes. Additionally, the reviewer notes that corresponding tests should be added for these new production commands to comply with the repository's style guide.

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.

*/
async function healthCheck(baseUrl, timeoutMs = 3000) {
try {
const res = await fetch(`${baseUrl.replace(/\/v1$/, "")}/api/monitoring/health`, {

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 baseUrl has a trailing slash (e.g., http://localhost:20128/v1/), the regex \/\/v1$/ will not match, leaving the trailing slash and resulting in a malformed URL like http://localhost:20128/v1//api/monitoring/health.

We can make this more robust by handling optional trailing slashes.

Suggested change
const res = await fetch(`${baseUrl.replace(/\/v1$/, "")}/api/monitoring/health`, {
const cleanBase = baseUrl.replace(/\/v1\/?$/, "").replace(/\/$/, "");
const res = await fetch(`${cleanBase}/api/monitoring/health`, {

*/
export async function runSetupCodexCommand(opts = {}) {
const port = Number(opts.port ?? process.env.PORT ?? 20128) || 20128;
const baseUrl = (opts.remote ?? `http://localhost:${port}`).replace(/\/v1$/, "");

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

Similar to the health check, if opts.remote contains a trailing slash (e.g., http://100.67.86.91:20128/v1/), the regex \/\/v1$/ will fail to strip the /v1/ path correctly. Let's make this robust against trailing slashes.

Suggested change
const baseUrl = (opts.remote ?? `http://localhost:${port}`).replace(/\/v1$/, "");
const baseUrl = (opts.remote ?? `http://localhost:${port}`).replace(/\/v1\/?$/, "").replace(/\/$/, "");

Comment on lines +34 to +62
const thinkingPatterns = [
{ re: /kmc\/kimi-k2\.7/, name: "kimi-k27", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /kmc\/kimi-k2\.6/, name: "kimi-k26", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /glm\/glm-5\.2-max/, name: "glm52max", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /glm\/glm-5\.2$/, name: "glm52", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /opencode-go\/mimo-v2\.5-pro/, name: "mimo-pro", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /opencode-go\/qwen3\.7-plus/, name: "qwen37plus", ctx: 32768, compact: 28000, toolLimit: 16384 },
];

// ── Good models (high effort) ─────────────────────────────────────────────
const goodPatterns = [
{ re: /ollamacloud\/deepseek-v4-pro/, name: "deepseek-pro", ctx: 131072, compact: 112000, toolLimit: 32768 },
{ re: /opencode-go\/mimo-v2\.5$/, name: "mimo", ctx: 131072, compact: 112000, toolLimit: 32768 },
];

// ── Simple models (no effort) ─────────────────────────────────────────────
const simplePatterns = [
{ re: /ollamacloud\/gemma4:31b/, name: "gemma4", ctx: 32768, compact: 28000, toolLimit: 16384 },
{ re: /ollamacloud\/nemotron-3-super/, name: "nemotron", ctx: 32768, compact: 28000, toolLimit: 16384 },
{ re: /ollamacloud\/gpt-oss:20b/, name: "gptoss", ctx: 32768, compact: 28000, toolLimit: 16384 },
];

// ── Fast models (low effort) ──────────────────────────────────────────────
const fastPatterns = [
{ re: /ollamacloud\/deepseek-v4-flash/, name: "deepseek-flash", ctx: 65536, compact: 56000, toolLimit: 16384 },
{ re: /ollamacloud\/gemini-3-flash/, name: "gemini-flash", ctx: 1000000, compact: 850000, toolLimit: 32768 },
{ re: /glm\/glm-5-turbo/, name: "glm5turbo", ctx: 131072, compact: 112000, toolLimit: 16384 },
{ re: /glm\/glm-4\.7-flash/, name: "glm47flash", ctx: 131072, compact: 112000, toolLimit: 16384 },
];

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

There are a few discrepancies between the model categorization patterns defined here and the documentation in CODEX-CLI-CONFIGURATION.md:

  1. kimi-k2.6: Listed under thinkingPatterns in the code (which assigns effort: "xhigh" and summary: true), but documented under ### Good models (bons) — high effort in the markdown. It should be moved to goodPatterns.
  2. ds/deepseek-v4-pro: Documented under ### Good models (bons) — high effort with a 1M context window, but completely missing from the code patterns.
  3. mistral/mistral-large-latest: Documented under ### Fast models (rápidos) — low effort with a 256k context window, but completely missing from the code patterns.

Let's update the patterns to align with the documentation.

  const thinkingPatterns = [
    { re: /kmc\/kimi-k2\.7/, name: "kimi-k27", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /glm\/glm-5\.2-max/, name: "glm52max", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /glm\/glm-5\.2$/, name: "glm52", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /opencode-go\/mimo-v2\.5-pro/, name: "mimo-pro", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /opencode-go\/qwen3\.7-plus/, name: "qwen37plus", ctx: 32768, compact: 28000, toolLimit: 16384 },
  ];

  // ── Good models (high effort) ─────────────────────────────────────────────
  const goodPatterns = [
    { re: /kmc\/kimi-k2\.6/, name: "kimi-k26", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /ollamacloud\/deepseek-v4-pro/, name: "deepseek-pro", ctx: 131072, compact: 112000, toolLimit: 32768 },
    { re: /ds\/deepseek-v4-pro/, name: "deepseek", ctx: 1000000, compact: 900000, toolLimit: 65536 },
    { re: /opencode-go\/mimo-v2\.5/, name: "mimo", ctx: 131072, compact: 112000, toolLimit: 32768 },
  ];

  // ── Simple models (no effort) ─────────────────────────────────────────────
  const simplePatterns = [
    { re: /ollamacloud\/gemma4:31b/, name: "gemma4", ctx: 32768, compact: 28000, toolLimit: 16384 },
    { re: /ollamacloud\/nemotron-3-super/, name: "nemotron", ctx: 32768, compact: 28000, toolLimit: 16384 },
    { re: /ollamacloud\/gpt-oss:20b/, name: "gptoss", ctx: 32768, compact: 28000, toolLimit: 16384 },
  ];

  // ── Fast models (low effort) ──────────────────────────────────────────────
  const fastPatterns = [
    { re: /ollamacloud\/deepseek-v4-flash/, name: "deepseek-flash", ctx: 65536, compact: 56000, toolLimit: 16384 },
    { re: /ollamacloud\/gemini-3-flash/, name: "gemini-flash", ctx: 1000000, compact: 850000, toolLimit: 32768 },
    { re: /glm\/glm-5-turbo/, name: "glm5turbo", ctx: 131072, compact: 112000, toolLimit: 16384 },
    { re: /glm\/glm-4\.7-flash/, name: "glm47flash", ctx: 131072, compact: 112000, toolLimit: 16384 },
    { re: /mistral\/mistral-large-latest/, name: "mistral", ctx: 262144, compact: 220000, toolLimit: 16384 },
  ];

});
if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}`);
const body = await res.json();
models = 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

To make this more robust against different server response formats (e.g., if the server returns a direct JSON array instead of an object, or if body is nullish), we should perform a safer check.

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

const body = await res.json();
models = body.data ?? body.models ?? [];
} catch (err) {
printError(`Failed to fetch models: ${err.message}`);

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 err is not an object or is null/undefined, accessing err.message will throw a TypeError and crash the process. Let's safely access the message or fall back to the string representation of the error.

Suggested change
printError(`Failed to fetch models: ${err.message}`);
printError(`Failed to fetch models: ${err?.message || String(err)}`);

Comment on lines +59 to +60
import { registerLaunchCodex } from "./launch-codex.mjs";
import { registerSetupCodex } from "./setup-codex.mjs";

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

According to the Repository Style Guide (Rule 9 under 2. Hard Rules):

Always include tests when changing production code (src/, open-sse/, electron/, bin/).

Since this PR introduces new production CLI commands in bin/cli/commands/, please ensure that corresponding unit or integration tests are added within the tests/ directory to maintain coverage.

References
  1. Always include tests when changing production code (src/, open-sse/, electron/, bin/). (link)

@diegosouzapw
diegosouzapw merged commit c34d37a into release/v3.8.30 Jun 19, 2026
4 checks passed
@diegosouzapw
diegosouzapw deleted the feat/codex-cli-commands branch June 19, 2026 12:36
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
* feat(cli): Codex CLI launcher + setup commands

Two new CLI subcommands mirroring the `launch`/`configure` pattern, for driving the
OpenAI Codex CLI against OmniRoute:

- `omniroute launch-codex` — boots OmniRoute (if needed) and launches Codex CLI
  pointed at it (local or remote VPS), with no manual env/config editing.
- `omniroute setup-codex` — generates ~/.codex profile files from OmniRoute's live
  model catalog.

Registered in the command registry; en.json + pt-BR.json locale sections added
(keeps the cli-i18n-catalog top-level parity gate green). CODEX-CLI-CONFIGURATION.md
refreshed. Consolidated from work-in-progress that was uncommitted on the shared
checkout; reconstructed on release/v3.8.30.

* chore(vscode): reduce git repo-detection overhead for nested worktrees

Disable VS Code's git auto-repository-detection / submodule scan / autofetch so the
Source Control view stops indexing the ~44 nested repos (worktrees + _references/*
+ _mono_repo/*), which caused constant "validating" churn. Only the root repo is
tracked. Editor-only settings; no runtime impact.
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