From e73b0253c870f95c2115283c813ceddfaf3a2255 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Fri, 19 Jun 2026 05:16:17 -0300 Subject: [PATCH] fix(release): reconcile v3.8.29 cycle gate/test drift surfaced at release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full quality gate (test:unit + test:vitest + check:docs-all) caught drift from cycle PRs that the PR→release fast-gates do not run. Each fix aligns to the already-merged code (no behavior change): - test(cloud-agent): expect 4 registered agents incl. cursor-cloud (#4250) - test(db-rules): add accessTokens to INTENTIONALLY_INTERNAL audited set (#4256) - test(glm): GLM/GLM-CN coding timeout 900000 -> 3000000 (50min) (#4255) - fix(i18n): add connect/tokens/configure CLI locale sections to pt-BR.json (#4256) - docs(env): document OMNIROUTE_CONTEXT in .env.example + ENVIRONMENT.md (#4256) - fix(ci): fabricated-docs checker now indexes arg-bearing .command("x ") forms (false-negative flagged a real `omniroute connect`); +2 regression tests --- .env.example | 5 +++ bin/cli/locales/pt-BR.json | 9 +++++ docs/reference/ENVIRONMENT.md | 33 ++++++++++--------- .../__tests__/glmCodingProviderConfig.test.ts | 4 +-- scripts/check/check-fabricated-docs.mjs | 6 ++-- .../check-db-rules-classification.test.ts | 3 +- tests/unit/check-fabricated-docs.test.ts | 33 +++++++++++++++++++ tests/unit/cloudAgent-types.test.ts | 3 +- 8 files changed, 74 insertions(+), 22 deletions(-) diff --git a/.env.example b/.env.example index 314c18fefb..3941efae2e 100644 --- a/.env.example +++ b/.env.example @@ -474,6 +474,11 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true # Legacy alias for OMNIROUTE_API_KEY. # ROUTER_API_KEY= +# CLI remote-mode context/profile for `omniroute` commands (overrides the active +# context in the local contexts store). Equivalent to the `--context ` flag. +# Used by: bin/cli/program.mjs, bin/cli/api.mjs (remote mode). +# OMNIROUTE_CONTEXT= + # Enforce scope-based access control on MCP tool calls. # Used by: open-sse/mcp-server/server.ts — rejects calls outside allowed scopes. # OMNIROUTE_MCP_ENFORCE_SCOPES=false diff --git a/bin/cli/locales/pt-BR.json b/bin/cli/locales/pt-BR.json index e79fc678c1..e907b7c28f 100644 --- a/bin/cli/locales/pt-BR.json +++ b/bin/cli/locales/pt-BR.json @@ -1261,5 +1261,14 @@ "token": "Chave de API que o cliente Claude deve enviar (ANTHROPIC_AUTH_TOKEN)", "notRunning": "OmniRoute não está rodando na porta {port}. Inicie com 'omniroute serve'.", "notFound": "O CLI 'claude' não foi encontrado no PATH." + }, + "connect": { + "description": "Conecta a um servidor OmniRoute remoto e entra no modo remoto" + }, + "tokens": { + "description": "Gerencia tokens de acesso CLI com escopo (modo remoto)" + }, + "configure": { + "description": "Escolhe um provedor+modelo do servidor ativo e grava uma configuração de CLI local" } } diff --git a/docs/reference/ENVIRONMENT.md b/docs/reference/ENVIRONMENT.md index 03c0685d79..b536aa6b5d 100644 --- a/docs/reference/ENVIRONMENT.md +++ b/docs/reference/ENVIRONMENT.md @@ -215,8 +215,8 @@ OmniRoute provides a two-layer defense: request-side injection scanning and resp ### VS Code Tokenized-Route Context Sanitizer -| Variable | Default | Source File | Description | -| ----------------------------------- | ------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Variable | Default | Source File | Description | +| ----------------------------------- | ------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_VSCODE_SANITIZE_CONTEXT` | `1` | `src/app/api/v1/vscode/contextSanitizer.ts` | Strips implicit active-editor context (`editorContext`, `activeEditor`, `currentFile`, `selection`, `openTabs`…) from `/v1/vscode/[token]/*` requests and redacts content of explicitly-attached sensitive files. Secure-by-default; set to `0` to disable. | ### Scenarios @@ -364,6 +364,7 @@ detection above). | `OMNIROUTE_API_KEY` | _(unset)_ | MCP/A2A modules | API key for internal MCP tool and A2A skill calls. | | `OMNIROUTE_API_KEY_ID` | _(unset)_ | `open-sse/mcp-server/audit.ts` | Key ID for MCP audit log attribution. | | `ROUTER_API_KEY` | _(unset)_ | Legacy | Legacy alias for `OMNIROUTE_API_KEY`. | +| `OMNIROUTE_CONTEXT` | _(active context)_ | `bin/cli/program.mjs`, `bin/cli/api.mjs` | CLI remote-mode context/profile for `omniroute` commands; overrides the active context in the local contexts store. Equivalent to `--context `. | | `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Enforce scope-based access control on MCP tool calls. | | `OMNIROUTE_MCP_SCOPES` | _(all)_ | `open-sse/mcp-server/server.ts` | Comma-separated scopes: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. | | `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS` | enabled | `open-sse/mcp-server/descriptionCompressor.ts` | Compress MCP tool descriptions before serializing the manifest. Disable values: `0`, `false`, `off`. | @@ -754,21 +755,21 @@ Anthropic-compatible provider instead. ## 21. Proxy Health -| Variable | Default | Source File | Description | -| ----------------------------------------------- | ---------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Fast-fail health check timeout. | -| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | Health check result cache TTL. | -| `OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Allow OAuth and provider validation flows to bypass a pinned proxy and connect directly when proxy reachability pre-checks fail. Effective precedence is Feature Flags DB override > env var > default. | -| `RATE_LIMIT_MAX_WAIT_MS` | `120000` (2 min) | `open-sse/services/rateLimitManager.ts` | Max time to wait on a 429 before failing the request. | -| `RATE_LIMIT_AUTO_ENABLE` | _(unset)_ | `open-sse/services/rateLimitManager.ts` | Force the auto-enable rate limit safety net on/off regardless of the persisted Dashboard setting. Accepts `true`/`1`/`on` to force on, `false`/`0`/`off` to force off. | -| `PROVIDER_COOLDOWN_ENABLED` | _(unset → off)_ | `open-sse/services/providerCooldownTracker.ts` | Opt-in global cross-request provider/connection cooldown tracking. OFF by default (overlaps Connection Cooldown / Provider Circuit Breaker). Accepts `true`/`1`/`on` to enable. | -| `PROVIDER_COOLDOWN_MIN_MS` | `5000` | `open-sse/services/providerCooldownTracker.ts` | Minimum cooldown (ms) before a failed provider/connection is retried. Scaled exponentially with consecutive failures. Only used when `PROVIDER_COOLDOWN_ENABLED`. | -| `PROVIDER_COOLDOWN_MAX_MS` | `300000` (5 min) | `open-sse/services/providerCooldownTracker.ts` | Maximum cooldown (ms) cap before a failed provider/connection is retried regardless. Only used when `PROVIDER_COOLDOWN_ENABLED`. | -| `STREAM_RECOVERY_ENABLED` | _(unset → off)_ | `open-sse/services/streamRecovery.ts` | Opt-in transparent recovery of truncated upstream streams (free-claude-code port). Holds the opening SSE window so an early cutoff is retried invisibly; OFF by default (adds time-to-first-token latency). Accepts `true`/`1`/`on` to enable. | +| Variable | Default | Source File | Description | +| ----------------------------------------------- | ---------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Fast-fail health check timeout. | +| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | Health check result cache TTL. | +| `OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Allow OAuth and provider validation flows to bypass a pinned proxy and connect directly when proxy reachability pre-checks fail. Effective precedence is Feature Flags DB override > env var > default. | +| `RATE_LIMIT_MAX_WAIT_MS` | `120000` (2 min) | `open-sse/services/rateLimitManager.ts` | Max time to wait on a 429 before failing the request. | +| `RATE_LIMIT_AUTO_ENABLE` | _(unset)_ | `open-sse/services/rateLimitManager.ts` | Force the auto-enable rate limit safety net on/off regardless of the persisted Dashboard setting. Accepts `true`/`1`/`on` to force on, `false`/`0`/`off` to force off. | +| `PROVIDER_COOLDOWN_ENABLED` | _(unset → off)_ | `open-sse/services/providerCooldownTracker.ts` | Opt-in global cross-request provider/connection cooldown tracking. OFF by default (overlaps Connection Cooldown / Provider Circuit Breaker). Accepts `true`/`1`/`on` to enable. | +| `PROVIDER_COOLDOWN_MIN_MS` | `5000` | `open-sse/services/providerCooldownTracker.ts` | Minimum cooldown (ms) before a failed provider/connection is retried. Scaled exponentially with consecutive failures. Only used when `PROVIDER_COOLDOWN_ENABLED`. | +| `PROVIDER_COOLDOWN_MAX_MS` | `300000` (5 min) | `open-sse/services/providerCooldownTracker.ts` | Maximum cooldown (ms) cap before a failed provider/connection is retried regardless. Only used when `PROVIDER_COOLDOWN_ENABLED`. | +| `STREAM_RECOVERY_ENABLED` | _(unset → off)_ | `open-sse/services/streamRecovery.ts` | Opt-in transparent recovery of truncated upstream streams (free-claude-code port). Holds the opening SSE window so an early cutoff is retried invisibly; OFF by default (adds time-to-first-token latency). Accepts `true`/`1`/`on` to enable. | | `STREAM_RECOVERY_MIDSTREAM_ENABLED` | _(unset → off)_ | `open-sse/services/streamRecovery.ts` | Opt-in mid-stream continuation (Fase 4.4): after a post-commit truncation, re-request with the partial text as an assistant prefill and stitch the missing suffix (plain-text OpenAI-compatible streams only, never with a tool call in flight). OFF by default — the recovered tail arrives as one burst. Independent of `STREAM_RECOVERY_ENABLED`. Accepts `true`/`1`/`on` to enable. | -| `HEALTHCHECK_STAGGER_MS` | `3000` | `src/lib/tokenHealthCheck.ts` | Stagger interval (ms) between provider token healthchecks at startup. | -| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Number of automatic retries on model-scoped cooldown responses before returning error to client. | -| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Max backoff interval (seconds) between cooldown retries. Capped by this value regardless of upstream `Retry-After`. | +| `HEALTHCHECK_STAGGER_MS` | `3000` | `src/lib/tokenHealthCheck.ts` | Stagger interval (ms) between provider token healthchecks at startup. | +| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Number of automatic retries on model-scoped cooldown responses before returning error to client. | +| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Max backoff interval (seconds) between cooldown retries. Capped by this value regardless of upstream `Retry-After`. | --- diff --git a/open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts b/open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts index b52874c6d5..52ce967e1f 100644 --- a/open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts +++ b/open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts @@ -23,7 +23,7 @@ describe("GLM Coding provider registry surfaces", () => { expect(entry?.authHeader).toBe("bearer"); expect(entry?.headers?.["Anthropic-Version"]).toBeUndefined(); expect(entry?.requestDefaults).toEqual({ maxTokens: 16384 }); - expect(entry?.timeoutMs).toBe(900000); + expect(entry?.timeoutMs).toBe(3000000); }); it("preserves custom GLM base URL query parameters while deriving transport endpoints", () => { @@ -74,7 +74,7 @@ describe("GLM Coding provider registry surfaces", () => { expect(entry?.executor).toBe("glm"); expect(entry?.baseUrl).toBe("https://open.bigmodel.cn/api/coding/paas/v4/chat/completions"); expect(entry?.requestDefaults).toEqual({ maxTokens: 16384 }); - expect(entry?.timeoutMs).toBe(900000); + expect(entry?.timeoutMs).toBe(3000000); expect(getProviderModels("glmcn").map((model) => model.id)).toEqual( getProviderModels("glm").map((model) => model.id) ); diff --git a/scripts/check/check-fabricated-docs.mjs b/scripts/check/check-fabricated-docs.mjs index b75b261dc5..27478cf316 100644 --- a/scripts/check/check-fabricated-docs.mjs +++ b/scripts/check/check-fabricated-docs.mjs @@ -570,8 +570,10 @@ export function buildCodebaseIndex(root = ROOT) { else if (/\.(mjs|js|ts)$/.test(name)) { try { const content = fs.readFileSync(child, "utf8"); - // Programmatic API: `command('foo', ...)`, `.command('bar')` - const m1 = content.matchAll(/\.command\(\s*['"`]([a-z][a-z0-9-]+)['"`]/g); + // Programmatic API: `command('foo', ...)`, `.command('bar')`, and + // arg-bearing forms `.command('connect ')` / `.command('chat [msg]')` + // — capture the leading subcommand token regardless of trailing args. + const m1 = content.matchAll(/\.command\(\s*['"`]([a-z][a-z0-9-]+)/g); for (const m of m1) cliCommands.add(m[1]); // Subcommand names: `${name}Cmd`, `name = "foo"`, etc. const m2 = content.matchAll(/name:\s*['"`]([a-z][a-z0-9-]+)['"`]/g); diff --git a/tests/unit/check-db-rules-classification.test.ts b/tests/unit/check-db-rules-classification.test.ts index 7c3d6a804c..d17c5ae6cc 100644 --- a/tests/unit/check-db-rules-classification.test.ts +++ b/tests/unit/check-db-rules-classification.test.ts @@ -122,9 +122,10 @@ test("INTENTIONALLY_INTERNAL is exported from check-db-rules.mjs", () => { assert.ok(INTENTIONALLY_INTERNAL.size > 0, "INTENTIONALLY_INTERNAL must not be empty"); }); -test("INTENTIONALLY_INTERNAL contains the expected 25 audited modules", () => { +test("INTENTIONALLY_INTERNAL contains the expected 26 audited modules", () => { const expected = [ "_rowTypes", + "accessTokens", "cleanup", "cliToolState", "comboForecast", diff --git a/tests/unit/check-fabricated-docs.test.ts b/tests/unit/check-fabricated-docs.test.ts index f2f133b834..8b37114a24 100644 --- a/tests/unit/check-fabricated-docs.test.ts +++ b/tests/unit/check-fabricated-docs.test.ts @@ -312,3 +312,36 @@ test("ANTI-OVER-SUPPRESSION: a fabricated env var on a normal (non-negated) line "a fabricated env var on a plain line must still be flagged" ); }); + +test("cli-cmd: an arg-bearing `.command('connect ')` registration is NOT flagged", () => { + // The old extraction regex required the subcommand name to be immediately followed + // by the closing quote, so commander's arg-bearing forms (`connect `, + // `chat [msg]`) were never indexed → a doc that referenced them was wrongly flagged. + const found = findingsFor({ + files: { + "bin/cli/commands/connect.mjs": + 'export function registerConnect(p) {\n p.command("connect ").action(() => {});\n}\n', + }, + docs: { "guides/remote.md": "You log in once with `omniroute connect `.\n" }, + }); + assert.ok( + !found.has("cli-cmd::omniroute connect"), + "a registered arg-bearing subcommand must be recognized and not flagged" + ); +}); + +test("ANTI-OVER-SUPPRESSION: an unregistered subcommand IS still flagged", () => { + // Broadening the regex must add precision, not blind detection: a doc that invokes + // a subcommand with no `.command()` registration anywhere in bin/ must remain flagged. + const found = findingsFor({ + files: { + "bin/cli/commands/connect.mjs": + 'export function registerConnect(p) {\n p.command("connect ").action(() => {});\n}\n', + }, + docs: { "guides/remote.md": "Then run `omniroute teleport ` to finish.\n" }, + }); + assert.ok( + found.has("cli-cmd::omniroute teleport"), + "an unregistered subcommand must remain flagged — precision must not blind detection" + ); +}); diff --git a/tests/unit/cloudAgent-types.test.ts b/tests/unit/cloudAgent-types.test.ts index 6bc9b74fed..dbff0ec2a4 100644 --- a/tests/unit/cloudAgent-types.test.ts +++ b/tests/unit/cloudAgent-types.test.ts @@ -131,7 +131,8 @@ test("getAvailableAgents returns all registered agents", () => { assert.strictEqual(agents.includes("jules"), true); assert.strictEqual(agents.includes("devin"), true); assert.strictEqual(agents.includes("codex-cloud"), true); - assert.strictEqual(agents.length, 3); + assert.strictEqual(agents.includes("cursor-cloud"), true); + assert.strictEqual(agents.length, 4); }); test("getAgent returns correct agent for valid providerId", () => {