Commit Graph

20 Commits

Author SHA1 Message Date
Sulistyo Fajar Pratama
246b87f739 fix(mitm): gate Agent Bridge DNS and Trust Cert on sudo password (#7938) (#7939)
* fix(mitm): gate Agent Bridge DNS and Trust Cert on sudo password (#7938)

Extend the #7865 sudo gate to setup wizard DNS, Start DNS, and Trust Cert.
Start server still runs without a password but skips privileged cert/DNS
steps instead of spawning sudo -S with an empty string. Add a shared sudo
password modal on the Agent Bridge page for DNS and trust-cert actions.

Fixes #7938

* fix(mitm): use .tsx extension for MitmSudoPasswordModal hook

JSX in a .ts file broke dashboard typecheck and ESLint on CI.

* fix(mitm): skip DNS teardown on stop when sudo password missing (#7938)

stopMitm() no longer invokes removeDNSEntry with an empty password when
the server was started in skip mode. The MITM process is still killed.

* refactor(mitm): extract privileged step helpers to satisfy file-size cap

manager.ts exceeded the 800-line cap after #7938 gates. Move DNS teardown
and the shared sudo skip runner into dedicated modules; behavior unchanged.
2026-07-21 11:50:09 -03:00
Sulistyo Fajar Pratama
21fcb19f96 fix(mitm): gate Agent Bridge Repair on sudo password (#7836) (#7865)
Reject repair and Remove CA when no sudo password is supplied or cached,
instead of spawning sudo -S with an empty string. Add a password modal to
AgentBridgeMaintenanceCard and regression tests for the 400 gate.

Address PR review feedback: reject whitespace-only sudoPassword values,
avoid caching unusable passwords, extract closePasswordModal helper, and
replace the route test that invoked real sudo with pure gate assertions.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-20 15:57:22 -03:00
Ronaldo Davi
0730eee9f2 fix(api): await params in Agent Bridge DNS route (Next.js 16) (#7271) (#7492) 2026-07-18 11:35:26 -03:00
Hamsa_M
aba98fd227 fix(cli): per-agent DNS, startup guards, and batched Windows hosts writes (#6338)
DNS toggle in AgentBridge was broken for 8 of 9 agents: addDNSEntry/
removeDNSEntry always resolved the legacy Antigravity default hosts
regardless of which agent's dns_enabled flag was flipped. Both now
accept an optional agentId and resolve hosts via ALL_TARGETS; the
[id]/dns route passes id through and returns 404 for an unknown agent
instead of silently falling back to the defaults.

startMitmInternal() now wraps generateCert(), the provisionDnsEntries()
call, and the PID-file write in try/catch so a mid-startup failure
can't orphan the already-spawned MITM child process.

On Windows, addDNSEntries/removeDNSEntries batch every missing/present
entry into a single elevated PowerShell invocation instead of one UAC
prompt per host line.

Scope note: this PR originally bundled an unrelated SkillOpt feature
(DB migration, 6 API routes, dashboard UI) and a checks-free CI build
workflow alongside this DNS/startup fix. Both were dropped here as
out-of-scope per review-group-prs analysis (2-implementing plan);
only the DNS/startup-guard delta (dnsConfig.ts, manager.ts, the [id]/dns
route, and their tests) is applied.

Co-authored-by: hamsa0x7 <hamsa0x7@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-09 16:44:50 -03:00
Diego Rodrigues de Sa e Souza
78f05fc639 fix(startup): resolve AgentBridge MITM router key from existing OmniRoute key (#6403) (#6619)
AgentBridge's start/restart actions only ever checked an explicit apiKey
request field (never sent by the UI) and the ROUTER_API_KEY process env
var (unset unless manually exported), so startMitm() always spawned
server.cjs with an empty ROUTER_API_KEY and it hard-exited with
"no API key was provided". resolveRouterApiKey() now falls back to
pickApiKeyForInternalUse(), the same DB-backed selector already used by
the combo-health-check / cloud-sync-verify internal probes.
2026-07-07 23:27:34 -03:00
Milan Soni
49795c24ef fix(api): dynamic import for MITM + fix Turbopack over-bundling warnings (#6366)
Dynamic MITM manager import on the agent-bridge route + Turbopack static-analyzer anchor in the skills generator (#6329). Integrated into release/v3.8.46.
2026-07-06 17:34:33 -03:00
Diego Rodrigues de Sa e Souza
dc40911583 Release v3.8.39 (#5164)
* chore(release): open v3.8.39 development cycle

* docs(changelog): backfill 5 v3.8.38 bullets merged after release finalize

These PRs squash-merged into release/v3.8.38 between the CHANGELOG finalize
(ff57be32f) and the merge-to-main (ae6e2342d), so they shipped in the v3.8.38
tag but had no bullet:

- feat(compression): Ionizer engine (lossy JSON-array sampling + CCR) (#5148)
- fix(sse): preserve non-stream reasoning fields (#5155, @rdself)
- fix(i18n): add missing English UI labels (#5153, @rdself)
- test(combo): gated live smoke (#5151) + release-expectations refresh (#5150, @KooshaPari)

(#5129 exact-host Anthropic baseUrl is already covered by the #5130 bullet — same CodeQL #674.)
Synced 41 i18n CHANGELOG mirrors.

* feat(compression): TOON best-of-N candidate encoder + encoder A/B table (#5163)

Integrated into release/v3.8.39. TOON best-of-N candidate encoder (GCF default, fail-open). 17/17 unit tests pass on merge result; CI reds were base-stale + Quality Ratchet DRIFT.

* fix(zenmux): normalize vendor-prefixed GLM system roles (#5158)

Integrated into release/v3.8.39. ZenMux vendor-prefixed GLM system-role normalization; 12/12 role-normalizer tests pass on merge result. CI reds base-stale.

* [codex] fix xAI OAuth test and reasoning effort (#5157)

Integrated into release/v3.8.39. xAI reasoning-effort normalization (max/xhigh→high) + OAuth test config; 46/46 xai-translator tests pass on merge result. CI reds base-stale.

* docs(i18n): add Traditional Chinese (zh-TW) README and update zh-CN to latest (#5162)

Integrated into release/v3.8.39. Traditional Chinese (zh-TW) README + zh-CN refresh; docs-only.

* test(security): guard PII redaction stays opt-in (default off) + Hard Rule #20 (#5159)

Integrated into release/v3.8.39. PII opt-in regression guard + Hard Rule #20; rebased to strip base-drift (+81/-1). 5/5 guard tests pass; flip-proof verified.

* test(combo): deterministic context-relay universal-handoff coverage (closes phase-2 TODO) (#5168)

Integrated into release/v3.8.39. Deterministic context-relay universal-handoff coverage (3 tests); 3/3 pass on merge result.

* docs(i18n): full sync zh-TW and zh-CN README with canonical English v3.8.39 (#5171)

Integrated into release/v3.8.39. Full zh-TW docs tree + zh-CN sync with canonical English v3.8.39; docs-only.

* fix(serve): honour HOSTNAME from .env instead of hardcoding 0.0.0.0 (#5134) (#5170)

Integrated into release/v3.8.39. HOSTNAME env override in serve (#5134) + regression test (4/4, TDD flip-proof verified).

* fix(sse): resolve nameless deepseek-web tool blocks via parameter-schema match (#5154) (#5173)

Integrated into release/v3.8.39. Schema-based nameless deepseek-web tool-block resolution (#5154); 6/6 tests pass on merge result (incl. ambiguous/no-match negatives + named-tag no-regression).

* fix(sse): normalize array user content for Command Code to avoid upstream 400 (#5166) (#5174)

Integrated into release/v3.8.39. Normalize array user content for Command Code (#5166, user-array/400 symptom); 4/4 tests pass on merge result.

* fix(sse): defer </think> close so it never leaks before tool_calls (#5123) (#5175)

Integrated into release/v3.8.39. Defer </think> close so it never leaks before tool_calls (#5123); 4/4 tests pass (incl. #4633 no-regression). CHANGELOG synced to keep all 3 v3.8.39 fixes.

* fix(dashboard): use amber for home update-step warning icon (#5176)

Integrated into release/v3.8.39. Amber for home update-step warning icon; 1/1 UI test.

* fix(api): LAN/Tailscale dashboard — host-aware CSP + GET-exempt version route + combo field errors (#5083) (#5177)

Integrated into release/v3.8.39. Host-aware CSP (ReDoS/injection-safe host validation) + GET-exempt /api/system/version (POST/spawn stays LOCAL_ONLY, exact-match safe-methods-only) + COMBO_002 firstField. 44/44 tests + route-guard membership gate green. CHANGELOG synced to keep all 4 v3.8.39 fixes.

* fix(api): replace #5083 global middleware CSP with declarative ws: scheme (#5083)

Follow-up to PR #5177 (merged): that version implemented the LAN-CSP fix (Bug 1)
with a new global `src/middleware.ts` + `src/server/csp.ts`, which contradicts the
project's documented architecture — 'No global Next.js middleware — interception is
route-specific' (CLAUDE.md / AGENTS.md) — and was merged unverified (middleware vs
next.config header precedence was never confirmed in a real build).

This replaces that approach with the minimal, declarative equivalent:
  • next.config.mjs: connect-src now permits the bare `ws:` scheme (symmetric with the
    bare `wss:` already allowed) so the dashboard can reach its own Live WS server from
    a LAN/Tailscale host. No middleware.
  • Removes src/middleware.ts, src/server/csp.ts, and tests/unit/csp-host-aware.test.ts.
  • Adds tests/unit/csp-lan-ws-5083.test.ts (incl. a guard asserting src/middleware.ts
    does NOT exist, so the global-middleware approach cannot silently return).

Bugs 2 (GET-exempt /api/system/version) and 3 (COMBO_002 field surfacing) from #5177
are unaffected and remain in place.

Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>

* test(combo): end-to-end quota-share DRR routing-decision coverage (matrix parity) (#5179)

Integrated into release/v3.8.39. Quota-share DRR routing-decision coverage (matrix parity); 2/2 pass on merge result.

* feat(agent-bridge): graceful cert-install fallback with manual guide for containers (#4546) (#5178)

Integrated into release/v3.8.39. Agent-bridge graceful cert-install fallback + manual guide (#4546); 6/6 tests pass on merge result.

* fix(antigravity): family-scoped quota lockout (gemini/claude buckets) (#5180)

Integrated into release/v3.8.39 — family-scoped antigravity quota lockout. Rebased from v3.8.37 + validated (vitest 5/5, typecheck clean, full combo-matrix green, model-lockout 99/0). Same-model cross-account retry (chat.ts) deferred pending live antigravity VPS validation.

* fix(cli): force NODE_ENV to match dev/start run mode in custom Next server (#5189)

Integrated into release/v3.8.39. Force NODE_ENV to match dev/start run mode in custom Next server; 2/2 source-scan+ordering tests pass on merge result.

* feat(compression): CCR ranged/grep/stats retrieval (ReDoS-safe, backward-compat) (#5187)

Integrated into release/v3.8.39. CCR ranged/grep/stats retrieval (safe-regex ReDoS guard + length/match caps); 17/17 tests pass on merge result.

* docs(combo): sync all combo/routing-strategy docs to current state + document test coverage (#5185)

Integrated into release/v3.8.39. Combo/routing-strategy docs sync; docs-only.

* fix(mcp): return 404 (not 400) for unknown Streamable HTTP session id (#5169) (#5191)

* fix(api): respect blocked Auto (Zero-Config) provider in /v1/models catalog (#5192) (#5194)

* test(combo): deterministic context-relay codex quota-handoff coverage (closes last gap) (#5195)

* test(ci): wire antigravity-quota-family under test:vitest (fix test-discovery orphan) (#5196)

* fix(oauth): antigravity login no longer hangs — fire-and-forget onboarding + bounded post-exchange (#5193)

Antigravity OAuth hang fix (no-PKCE/no-openid + bounded post-exchange + exchange-500 fix). Includes #5200 (Koosha) revert + owner rebaseline to keep documented comments. Integrated into release/v3.8.39.

* feat(oauth): remote Antigravity login via local helper + paste-credentials (#5203)

Remote Antigravity login: local helper (omniroute login antigravity) + paste-credentials. Integrated into release/v3.8.39.

* fix(translator): accept Claude Messages shape in non-stream malformed-200 guard (#5156)

Integrated into release/v3.8.39

* fix(cli): default dev bundler to Turbopack (16.2.x panic no longer reproduces) (#5206)

Integrated into release/v3.8.39

* fix(cli): auto-calibrate server V8 heap from physical RAM (#5172) (#5213)

The server was spawned with a fixed --max-old-space-size=512 (omniroute serve)
or no heap flag at all (Electron), so RAM-rich boxes still OOM-crashed under
load (Ineffective mark-compacts near heap limit ~500MB) with many providers/
accounts and large model catalogs. New calibrateHeapFallbackMb(os.totalmem())
defaults the heap to ~35% of RAM clamped [512,4096], wired into serve.mjs and
electron/main.js. Explicit OMNIROUTE_MEMORY_MB still wins (#2939 unchanged).

Also addresses #5160 (same OOM root); #5152 (docker) benefits via the same knob.

Closes #5172

* fix(proxy): coalesce fast-fail health probes (#5208)

Integrated into release/v3.8.39

* fix(proxy): close dispatchers when clearing cache (#5202)

Integrated into release/v3.8.39

* fix(cli): raise dev server Node heap limit to 8GB to prevent OOM (#5198)

Integrated into release/v3.8.39

* fix(auth): allow synthetic no-auth fallback for mimocode (#5205)

Integrated into release/v3.8.39

* fix(oauth): preserve Antigravity refresh_token on empty/omitted upstream response (#3850) (#5214)

Google's OAuth refresh tokens are non-rotating: the refresh response usually
omits refresh_token and occasionally returns it as an empty string. The
Antigravity executor used `typeof tokens.refresh_token === "string" ? ... `
which accepts "" (typeof "" === "string") and overwrote the stored token with
empty, nulling it on first refresh. Now treats non-string OR empty as absent and
preserves credentials.refreshToken, matching refreshGoogleToken semantics.

Closes #3850

* fix(responses): normalize non-array input (#5204)

Integrated into release/v3.8.39

* fix(stream): normalize safety finish reasons via shared helper (#5197)

Integrated into release/v3.8.39

* fix(request-logger): never render negative '(-100%)' compression badge (#5201)

Integrated into release/v3.8.39

* fix(combo): reject empty responses api output (#5207)

Integrated into release/v3.8.39 — combo failover now rejects empty Responses API output (validateQuality). Baseline rebaseline dropped (main-measured drift; maintainer rebaselines at release).

* fix(pwa): prefer cached navigation before offline page (#5209)

Integrated into release/v3.8.39 — PWA service worker prefers cached navigation before offline page (#5165).

* chore(release): v3.8.39 — 2026-06-28

* chore(release): rebaseline openapi+i18n coverage ratchet drift for v3.8.39

---------

Co-authored-by: Arthur Bodera <abodera@gmail.com>
Co-authored-by: Nguyen Minh <lop123thcs@gmail.com>
Co-authored-by: lunkerchen <labanchen@gmail.com>
Co-authored-by: Ankit <177378174+anki1kr@users.noreply.github.com>
Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
Co-authored-by: Ardem2025 <ardemb22@gmail.com>
Co-authored-by: backryun <bakryun0718@proton.me>
Co-authored-by: Anton <39598727+NomenAK@users.noreply.github.com>
Co-authored-by: KooshaPari <42529354+KooshaPari@users.noreply.github.com>
Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
2026-06-28 06:58:29 -03:00
Diego Rodrigues de Sa e Souza
db362b0126 Release v3.8.30 (#4267)
Release v3.8.30 — see CHANGELOG.md [3.8.30] for the full release notes.
2026-06-20 07:09:43 -03:00
Diego Rodrigues de Sa e Souza
3c9883bb73 Release v3.8.29 (#4126)
OmniRoute v3.8.29 — 115 commits since v3.8.28. Full CHANGELOG + 41 i18n mirrors. All content quality gates green (build, unit 8/8, vitest 188/188, PR test policy, quality gates extended, docs sync, quality ratchet). Remaining red CI checks are pre-existing release flakes (coverage-shard/integration/node-compat teardown), a new transitive undici advisory in electron devDeps, and a workflow-level CodeQL fail (0 open alerts). VPS-validated by the operator.
2026-06-19 06:49:01 -03:00
Diego Rodrigues de Sa e Souza
f165efcd0b Release v3.8.28 (#4053)
* chore(release): open v3.8.28 development cycle

* fix(ws): warm SSE auth import on LiveWS startup; relocate boot test to integration (#4063)

The live dashboard WebSocket sidecar lazily import()-ed the SSE auth module
inside the connection handler, only on the API-key path. That cold import pulls
in hundreds of transitive modules and takes ~7s under tsx, blocking the
single-threaded event loop. The first API-key WebSocket connection therefore
stalled the loop long enough that any connection arriving in that window — e.g.
a same-origin cookie client — could not complete its handshake and timed out.

This was deterministic, not an "env flake": the boot test fires an API-key
connection immediately followed by a cookie connection, so the cookie connection
always raced the cold import and timed out (reproduced 3/3 locally and red on
every CI run; proven via instrumented probes — reversing the order or warming
the module first makes both connections open in ~20ms).

Fix:
- Memoize the auth-module import and warm it once at startup (before listen), so
  connection handling never pays the cold-import cost. Real improvement: the
  first API-key client no longer stalls the event loop for concurrent clients.
- Relocate the boot test from tests/unit/cli to tests/integration. It spawns a
  real subprocess + WS server + SQLite (~9-11s); under the unit suite's
  --test-concurrency=20 it contended for CPU and destabilized the shard. The
  serial integration runner is its correct home; it still guards #4004's
  cookie-parse fix on every PR via the integration CI job.
- Bump the test's startup/overall timeouts to absorb the eager auth warm.

Makes `npm run test:unit` deterministically green (the only remaining unit red).

Validated: relocated test 3/3 green via the integration runner (was 3/3 red);
typecheck:core + eslint clean; confirmed it no longer matches the test:unit glob
and does match tests/integration/*.test.ts.

* fix(ws): start LiveWS sidecar with cwd at package root (#4055) (#4064)

* chore(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.3 (#4045)

Integrado em release/v3.8.28. Patch de SHA do ossf/scorecard-action (2.4.0→2.4.3), mantém SHA-pin. Reds de CI são exclusivamente os shards flaky pré-existentes branch-wide (Unit 7/8, Integration, Coverage 7/8, Node 1/2) — não relacionados ao bump (PR deps-only).

* deps: bump electron from 42.4.0 to 42.4.1 in /electron (#4049)

Integrado em release/v3.8.28. Patch do electron (42.4.0→42.4.1). Reds de CI: shards flaky pré-existentes + PR Test Policy = falso-positivo (mudança deps-only sob electron/ não comporta teste de código) + Node 26(2/2) sem step (flake/infra). Precedente #3913/#3914 (electron dependabot mergeado nessas condições).

* fix(auto): resolve built-in auto catalog combos (#4058)

Integrado em release/v3.8.28. Resolve os IDs de catálogo `auto/*` built-in (combos virtuais) — corrige o 400 "No auto combos configured" em auto/best-coding etc. Ajuste de review: os mapas AUTO_TEMPLATE_VARIANTS/VALID_AUTO_VARIANTS duplicados em chat.ts e chatHelpers.ts foram extraídos para open-sse/services/autoCombo/builtinCatalog.ts (DRY), devolvendo chatHelpers.ts <800 LOC; baseline de chat.ts rebaselinado 1432→1458 (lógica nova). Fast QG + semgrep + dast verdes; 22/22 testes.

* chore(docs): update Discord invite link to a non-expiring one (#4067)

* chore(deps): freeze @huggingface/transformers in dependabot (hard-pin) (#4066)

Integrado em release/v3.8.28. Congela @huggingface/transformers no dependabot (pin exato 3.5.2, load-bearing p/ LLMLingua + memory embeddings, VPS-validado #4014). Fast QG + semgrep + dast verdes.

* ci(quality): flip TIA impacted-unit-tests gate from advisory to blocking (#4069)

The pre-existing release unit test-debt that kept the TIA "Impacted unit tests"
step advisory has been cleared:
- #4030 restored 16 lossless Zod/registry reds (from the oyi77 modularize refactors).
- #4063 fixed the last red — the LiveWS boot test — which was a real deterministic
  event-loop stall in the WS sidecar (cold ~7s lazy auth import racing a second
  connection), not an env flake; fixed (warm the import at startup) and relocated to
  the integration suite.

A full workflow_dispatch ci.yml run on release/v3.8.28 then showed all 8 Unit Tests
shards green. The remaining Integration Tests / Quality Ratchet reds are pre-existing
and unrelated (combo/resilience env-flakes; eslint/i18n baseline drift).

Removing continue-on-error makes PR->release block on unit-test regressions in the
TIA-selected impacted set (fail-safe still runs the full unit suite on hub/unmapped
changes). typecheck:core was already blocking. Closes the fast-gates "no tests on
PR->release" hole (Quality Gate v2 / Fase 9, P2).

* docs(compression): document LLMLingua optional deps + on-demand install (#4061)

Integrado em release/v3.8.28. Docs LLMLingua optional deps + on-demand install (F3.1).

* feat(dashboard): Combo Studio connection-cooldown badge (U1b Slice 2) (#4068)

Integrado em release/v3.8.28. Combo Studio connection-cooldown badge (U1b Slice 2 / F5.1).

* feat(compression): record Context Editing telemetry (engine: context-editing) (#4062)

Integrado em release/v3.8.28. Context Editing telemetry (F4.1).

* feat(sse): Context Editing relay coverage + 400-fallback (#4065)

Integrado em release/v3.8.28. Context Editing relay coverage (cc-*) + 400-fallback (F4.2/F4.3). Conflito de file-size-baseline.json (vs #4062) resolvido por união (ambas justificativas + base.ts 1292 + chatCore.ts 5898). Validado local no tree mergeado: typecheck:core ✓, eslint ✓, check:file-size ✓, 4/4 testes ✓; semgrep + semgrep-cloud verdes. Fast QG enfileirado (saturação de runner) — mergeado nos gates de política verificados (precedente #4034/#4020).

* feat(providers): add OrcaRouter (OpenAI-compatible routing gateway) (#4070)

Integrado em release/v3.8.28. Adiciona o provider OrcaRouter (OpenAI-compatible, API-key, DefaultExecutor). Ajuste de review: rebaseline de file-size de providers.ts 3147→3159 (+12 da entrada OrcaRouter). Validado local no tree sincronizado: provider-consistency ✓, docs-counts STRICT 227 ✓, typecheck:core ✓, teste 3/3 ✓, eslint ✓; semgrep + semgrep-cloud verdes. Fast QG/dast enfileirados (saturação de runner) — merge nos gates de política verificados (precedente #4034/#4065).

* test(infra): isolate DATA_DIR per test process; raise Stryker concurrency 1→4 (#4078)

* test(infra): isolate DATA_DIR per test process; raise Stryker concurrency 1→4

Every test process resolved DATA_DIR to the same default (~/.omniroute) when the env
var was unset (src/lib/dataPaths.ts::resolveDataDir), so concurrent test files opened
the SAME on-disk storage.sqlite. node:test spawns a process per file and Stryker spawns
one per sandbox, so this shared file caused cross-file state races:
- SQLite lock contention that hung `npm run test:unit` under high --test-concurrency
  (the ~95-min local hang), and
- the non-deterministic baseline that forced stryker.conf.json to concurrency: 1, which
  in turn could not finish the ~15k-mutant run inside the nightly timeout (the cancelled
  2026-06-16/17 nightly-mutation runs) — blocking Quality Gate v2 / Fase 9 Onda 2.

open-sse/utils/setupPolyfill.ts could NOT host the fix: it is imported by production
(bin/omniroute.mjs, proxyFetch.ts, proxyDispatcher.ts), where redirecting DATA_DIR would
point the live SQLite DB at a throwaway temp dir. So this adds a TEST-ONLY
tests/_setup/isolateDataDir.ts that gives each process its own temp DATA_DIR when none is
set (tests that set DATA_DIR explicitly still win), wired via --import into the test,
mutation and CI invocations.

Verified:
- Stryker dry-run A/B at concurrency=4: FAILS without the isolation import
  (account-fallback-service tap exit 9, a cross-file race) and PASSES with it.
- Full `npm run test:unit` green with isolation (0 fail; a one-off
  chatcore-translation-paths timeout flake did not reproduce and passes 3/3 isolated)
  and noticeably faster — the DB lock contention is gone.
- New tests/unit/isolate-datadir.test.ts guards the contract (unique temp DATA_DIR when
  unset; explicit DATA_DIR respected).

Wired the --import into: package.json (13 test scripts), stryker.conf.json (tap.nodeArgs
+ concurrency 1→4), .github/workflows/quality.yml (TIA step), ci.yml (the 5
unit/coverage/integration commands), and bumped nightly-mutation.yml timeout 120→180 for
the first cold run before the incremental cache is seeded.

* ci(quality): run the TIA gate at CI concurrency (4) to stop oversubscription flakes

The TIA "Impacted unit tests" step (made blocking in #4069) ran its fail-safe via
`npm run test:unit` — concurrency=20, tuned for multi-core dev machines. On a 4-vCPU CI
runner that is 5x oversubscribed, so timing-sensitive tests flake under the load (e.g.
`db-backup-extended` "The database connection is not open", `chatcore-translation-paths`
upstream-timeout). That intermittently fails a blocking gate on legitimate PRs — exactly
what surfaced on the DATA_DIR-isolation PR, whose package.json/workflow changes trip the
__RUN_ALL__ fail-safe.

Run both the impacted set and the fail-safe at --test-concurrency=4, matching the stable
ci.yml unit job. Adds a `test:unit:ci` script (test:unit at concurrency=4). The DATA_DIR
isolation in this PR keeps the parallel run race-free, so the only change here is matching
the runner's core count. Verified locally: db-backup-extended passes 8/8 in isolation
(5 with isolation, 3 without).

* docs(quality-gates): reconcile gate inventory with ci.yml + add ROI rationalization backlog (#4095)

The "authoritative" gate inventory in QUALITY_GATES.md had drifted from ci.yml: it omitted
9 wired gates — `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`
(lint job), `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`,
`check:codeql-ratchet` (quality-gate job), and `check:pr-evidence` (pr-test-policy job).
You can't rationalize an inventory you can't trust, so this reconciles it first.

Adds those 9 rows to their job tables and a "Rationalization Backlog (ROI review)" section
capturing the Fase 9 Onda 3 findings: mechanical merge/dedup candidates (CVE scanners
audit:deps↔osv, the two complexity ESLint passes, cycles↔circular-deps, the two /api
anti-hallucination gates, the doubly-run check:docs-sync, check:node-runtime ×11) and the
operator-only flip/drop decisions (typecheck:noimplicit vs the type-coverage ratchet,
test:vitest:ui parked fails, check:secrets frozen FPs, openapi-security-tiers, pr-evidence,
the orphaned semgrep baseline). Also flags the undocumented advisory docs-lint job and the
standalone scanner workflows.

Docs-only — no gate behavior changes. The merges (CI changes) and flips (policy) are
deferred to operator-scoped follow-ups; this PR only makes the map accurate.

* test(dashboard): smoke e2e for the Combo Live Studio page (#4075)

Integrated into release/v3.8.28

* fix(sse): friendly 413 message for ChatGPT web payload-too-large (#4080)

Integrated into release/v3.8.28

* feat(sse): port Claude Code quota-probe bypass + command meta-request helpers (#4083)

Integrated into release/v3.8.28

* feat(api): exact offline token counting for count_tokens fallback via tiktoken (#4087)

Integrated into release/v3.8.28

* feat(compression): RTK learn/discover (sample source + API + UI) (#4088)

Integrated into release/v3.8.28

* feat(dashboard): 2026-06-17 free-tier refresh — honest catalog, uncapped + boost tiers, Layout A budget table (#4089)

Integrated into release/v3.8.28

* feat(mitm): capture-pipeline self-test route (Gap 12) (#4093)

Integrated into release/v3.8.28

* fix(mitm): crash-safe system-state teardown + socket timeouts (ProxyBridge-inspired hardening) (#4084)

Integrated into release/v3.8.28 (Fast QG TIA red = 3 pre-existing timing flakes verified passing locally 82/82; PR own tests green)

* feat(mitm): attribute intercepted requests to originating process (Gap 1) (#4085)

Integrated into release/v3.8.28 (Fast QG TIA red = 3 pre-existing timing flakes verified passing locally 82/82; PR own tests green)

* fix(sse): route image requests only to confirmed-vision combo targets (#4071)

Integrated into release/v3.8.28

* fix(security): injection guard respects INJECTION_GUARD_MODE DB feature flag (#4077)

Integrated into release/v3.8.28

* fix(ws): proxy LAN /live-ws upgrades and add unset JWT_SECRET warning (#4079)

Integrated into release/v3.8.28

* fix(dev): force webpack in custom dev server (Turbopack 16.2.x panics) (#4092)

Integrated into release/v3.8.28

* ci(quality): dedup the doubly-run check:docs-sync + record validated ROI backlog (#4099)

Onda 3 (gate ROI-review) Phase 2. Two parts, both low-risk:

1. Remove the standalone `check:docs-sync` from the `lint` job — it already runs in the
   `docs-sync-strict` job (via `check:docs-all`) and the husky pre-commit hook, so the
   `lint`-job copy was a pure duplicate. No coverage lost.

2. Update the Rationalization Backlog in QUALITY_GATES.md with trust-but-verify findings:
   several "obvious" merges/flips from the ROI review turned out to hide debt and are NOT
   clean drop-ins —
   - CVE merge (audit:deps→osv): different semantics (hard high/critical vs regression-ratchet) — keep both.
   - cycles→circular-deps: dpdm reports 91 cycles (can't promote to blocking) and is broader-scope than the green curated check:cycles — keep both.
   - openapi-security-tiers flip: blocked by traffic-inspector routes missing the x-loopback-only annotation.
   - complexity + /api merges: valid but real config/script surgery — deferred.
   - node-runtime ×11: ~10s savings vs a cheap guard — low ROI, skip.

   The remaining flips (typecheck:noimplicit, test:vitest:ui, check:secrets, pr-evidence,
   semgrep) are operator policy decisions, left for the owner.

* chore(deps): bump actions/github-script from 7 to 9 (#4046)

Integrated into release/v3.8.28 (dependabot GH-Action bump; SHA-pin preserved)

* chore(deps): bump actions/setup-node from 4 to 6 (#4048)

Integrated into release/v3.8.28 (dependabot GH-Action bump; SHA-pin preserved)

* chore(deps): bump actions/upload-artifact from 4 to 7 (#4044)

Integrated into release/v3.8.28 (dependabot GH-Action bump; SHA-pin preserved)

* chore(deps): bump actions/cache from 4.3.0 to 5.0.5 (#4047)

Integrated into release/v3.8.28 (dependabot GH-Action bump; SHA-pin preserved)

* deps: bump the development group with 10 updates (#4051)

Integrated into release/v3.8.28 (dependabot dev group; cyclonedx 4->5 verified compatible with the SBOM invocation --ignore-npm-errors/--output-format JSON/--output-file)

* fix(dashboard): event-driven fail-open auto-refresh for embedded log views (#4054) (#4103)

The Request Logger gated each auto-refresh tick on a static
document.visibilityState === "visible" read. Hosts that report a permanent
non-"visible" state without ever firing a visibilitychange event (Docker
dashboard wrappers, embedded/proxied webviews) froze auto-refresh entirely —
only the manual Refresh button worked, a regression from 3.8.24's unconditional
polling.

The pause is now event-driven and fail-open: visibleRef starts true and is only
flipped to false on a real visibilitychange → hidden transition, so a host that
never signals a genuine background transition keeps polling, while normal
browser tabs still pause when actually backgrounded.

Regression test reproduces the misreporting-host case (RED) and the perf guard
is re-encoded under the event-driven semantics.

* fix(docker): raise build-stage Node heap to stop production-build OOM (#4076) (#4104)

The Docker builder stage ran `npm run build` with V8's default heap ceiling
(~2 GB). After #4052 forced the heavier webpack engine (Turbopack panics on this
Next.js version), the production optimization pass exceeded that ceiling and the
build died with "FATAL ERROR: ... JavaScript heap out of memory" at
[builder] npm run build.

The builder stage now sets NODE_OPTIONS=--max-old-space-size (default 4096 MB,
overridable via --build-arg OMNIROUTE_BUILD_MEMORY_MB) before the build; the
value propagates to the spawned next build (resolveNextBuildEnv spreads
process.env). Build-only — the runtime heap on the runner stage is unchanged,
and CI/local builds (which invoke npm run build directly) are unaffected.

Regression guard: tests/unit/dockerfile-build-heap-4076.test.ts asserts the
builder stage sets the heap ceiling, before npm run build, at >= 4096 MB.

* feat(agent-bridge): portable JSON import/export of config (Gap 4) (#4094)

Integrated into release/v3.8.28

* feat(cli): add 'omniroute launch' zero-config Claude Code launcher (#4097)

Integrated into release/v3.8.28 (Fast QG TIA red = pre-existing env-doc-contract drift [MITM_IDLE_TIMEOUT_MS/TURBOPACK from #4084/#4092] + opencode-plugin-dist env flake; #4097 own test 3/3 green)

* feat(mitm): loop-guard self-check + verbosity control in server.cjs (Gaps 14+15) (#4101)

Integrated into release/v3.8.28 (rebased onto release — dropped the already-squash-merged #4084 commits; only the Gaps 14+15 loop-guard/verbosity delta remains)

* feat(sse): generic 400 field-downgrade retry + Groq field stripping (#4096)

Integrated into release/v3.8.28

* feat(providers): add Wafer AI (Anthropic-compatible, Bearer auth) (#4098)

Integrated into release/v3.8.28

* chore(docs)

* fix(responses): clear /v1/responses keepalive timer on cancel/abort (timer + CPU leak) (#4105)

Integrated into release/v3.8.28 (r7).

* perf(gemini): cache reasoning close-tag regex instead of recompiling per token (#4106)

Integrated into release/v3.8.28 (r7).

* fix(usage): reap orphaned pending-request details (unbounded memory leak) (#4107)

Integrated into release/v3.8.28 (r7).

* perf(stream): use structuredClone instead of JSON round-trip for per-chunk reasoning split (#4108)

Integrated into release/v3.8.28 (r7).

* fix(dashboard): restore Update Available banner with npm-binary-free version fallback (#4100) (#4112)

getLatestNpmVersion() derived the latest version only from the npm CLI binary and returned null on any error, so Docker/desktop/locked-down installs without npm on PATH silently hid the home banner even when an update existed. Add resolveLatestVersion() (npm CLI -> registry HTTP fallback -> logged warning) and harden version parsing for v-prefix/pre-release strings. Extracted into testable src/lib/system/versionCheck.ts with TDD coverage.

* fix(auth): prune expired entries from login brute-force guard map (unbounded growth) (#4111)

Integrated into release/v3.8.28 (r8)

* fix(logger): hard-cap the error-dedup map to bound memory under unique-message bursts (#4113)

Integrated into release/v3.8.28 (r8)

* fix(circuit-breaker): enforce MAX_REGISTRY_SIZE (declared but never applied) (#4114)

Integrated into release/v3.8.28 (r8)

* perf(obfuscation): cache per-word regexes instead of recompiling every request (#4109)

Integrated into release/v3.8.28 (r8)

* perf(registry): precompute model->provider index in parseModelFromRegistry (#4110)

Integrated into release/v3.8.28 (r8)

* fix(timers): unref background interval timers so they don't block clean shutdown (#4117)

Integrated into release/v3.8.28 (r8)

* fix(webhook): clear abort timer in finally to avoid dangling timers on fetch error (#4115)

Integrated into release/v3.8.28 (r8)

* fix(combo): detach per-target listener from shared hedge abort signal (#4116)

Integrated into release/v3.8.28 (r8)

* chore(release): finalize v3.8.28 CHANGELOG + reconcile env-doc contract

- Build the complete [3.8.28] CHANGELOG section (55 bullets) covering every
  commit since v3.8.27, grouped by type with PR back-references and human
  contributor attribution (artickc's memory-leak/perf cluster, OrcaRouter,
  Wafer AI, MITM gaps, etc.); move the OrcaRouter bullet out of [Unreleased].
- Inject the EN [3.8.28] section into all 41 i18n CHANGELOG mirrors (parity).
- Reconcile the env/docs contract: document MITM_IDLE_TIMEOUT_MS + MITM_VERBOSE
  in .env.example and ENVIRONMENT.md; allowlist the framework-internal TURBOPACK
  and the Claude Code ANTHROPIC_AUTH_TOKEN in check-env-doc-sync.
- Fix 3 broken relative links in docs/providers/AGENTROUTER.md (regressed when
  the file was relocated this cycle) so docs-sync-strict passes.

* fix(quality): treat test→test renames as relocations, not deletions

The anti-test-masking gate's subcheck-1 collected deleted AND renamed test
files via `--diff-filter=DR --name-only` and flagged every one as "deleted —
human review required", contradicting its own documented contract ("DELETADOS
ou renomeados-e-NÃO-substituídos"): a rename test→test IS a substitution (the
test moved, coverage preserved). This false-positived on #4063's legitimate
relocation of live-ws-startup.test.ts (unit/cli → integration, asserts 2→2)
and would block every PR that relocates a test — surfacing only at release-day
because the Fast QG (PR→release) doesn't run test-masking.

The gate now parses `--name-status -M`: true deletions and test→non-test
renames still flag; a test→test rename is run through the assert-reduction
check across the move, so a clean relocation passes while gutting-via-rename
(dropped asserts / new tautologies / skips) still fires. Adds
partitionDeletedRenamed + 6 regression tests.

---------

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Demiurge The Single <megamen932@gmail.com>
Co-authored-by: jinhaosong-source <jinhao.song@myflashcloud.com>
Co-authored-by: diego-anselmo <contato@diegoanselmo.com.br>
Co-authored-by: Felipe Almeman <4226997+zhiru@users.noreply.github.com>
Co-authored-by: Rahul sharma <sharmaR0810@gmail.com>
Co-authored-by: Chirag Singhal <76880977+chirag127@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
2026-06-17 19:26:32 -03:00
Diego Rodrigues de Sa e Souza
c315a2394c Release v3.8.21 (#3593)
* chore(release): open v3.8.21 development cycle

* fix: pass through valid max_tokens-truncated responses instead of fake 502 (#3572) (#3595)

* fix: /v1/completions returns legacy text-completion format, not chat (#3571) (#3596)

* fix: z.ai/GLM coding plan no longer shows Monthly 0% when no monthly cap (#3580) (#3597)

* docs: mark DISCOVERY_TOOL_DESIGN endpoints as Phase-2 not-yet-implemented (#3498) (#3599)

* fix(agent-bridge): add validate-only upstream-ca/test route (#3488) (#3600)

* fix(gamification): add level/badges/badges-earned profile routes (#3484)

* security(oauth): migrate 5 public client_ids to resolvePublicCred (#3493)

* fix(mcp): ship MCP server source closure in npm files + coverage gate (#3578)

* fix: add reasoning token buffer for combo routing (fixes #3587) (#3588)

Integrated into release/v3.8.21

* Refactor: Extract chatCore phases into modular files (#3598)

Integrated into release/v3.8.21 — chatCore phase modularization. Adjusted: re-derive idempotencyKey for the save path after the check moved into the module (co-authored). Thanks @oyi77!

* docs(changelog): credit #3598 (chatCore modularization) + #3588 (combo reasoning buffer)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(api): implement GET /api/guardrails + POST /api/guardrails/test, drop shadow/guardrails doc-fiction (#3496) (#3602)

Integrated into release/v3.8.21 — implements GET /api/guardrails + POST /api/guardrails/test, removes shadow/guardrails doc-fiction. TDD-validated (5/5) + check-docs-symbols/typecheck/eslint green.

* fix(gemini): isolate textual reasoning wrappers (#3605)

Split-out PR C from #3584. Isolates textual reasoning wrappers (<think>/<thinking>/<thought>/<internal_thought>, including malformed/open tags) into reasoning_content across both the non-streaming sanitizer and the Gemini streaming translator, with split-chunk buffering. Additive to the existing textual tool-call pipeline; does not touch the #3569 native functionResponse path. Integrated into release/v3.8.21. Thanks @dhaern!

* fix(antigravity): normalize Gemini 3.5 Flash tier IDs (#3603)

Split-out PR A from #3584. Normalizes the Antigravity/agy Gemini 3.5 Flash tier IDs to clean public names (gemini-3.5-flash-low/medium/high), maps them to the live upstream IDs at the executor boundary, and removes Antigravity from the global model resolver so the executor owns wire normalization. Maintainer follow-up: kept gemini-3.5-flash-preview as a hidden backward-compat alias routing to the High tier (so saved combos/configs keep working). Live-validated the tier set via the agy CLI catalog. Integrated into release/v3.8.21. Thanks @dhaern!

* fix(agent-bridge): surface real MITM startup-failure cause, not always port 443 (#3606) (#3608)

Integrated into release/v3.8.21 (#3606)

* fix(oauth): surface real Kiro import-token failure cause, not a bare 500 (#3589) (#3609)

Integrated into release/v3.8.21 (#3589)

* docs(opencode-provider): soft-deprecate in favor of @omniroute/opencode-plugin (#3419) (#3613)

Integrated into release/v3.8.21 (#3419)

* fix(usage): normalize Antigravity and agy provider quotas (#3604)

Split-out PR B from #3584. Normalizes Antigravity/agy provider quotas: prefers retrieveUserQuota for live consumption, falls back to fetchAvailableModels and local usage_history, sanitizes cached Provider Limits so retired upstream IDs are not re-exposed, and schedules a deduplicated post-usage refresh. Maintainer follow-up: decoupled the post-usage refresh via a lightweight usageEvents bus (usageHistory no longer dynamic-imports providerLimits) so it does not pull the executors/translator graph into the typecheck-core surface — typecheck:core stays at 0. Integrated into release/v3.8.21. Thanks @dhaern!

* feat(cli): add autostart on/off/toggle shorthand for headless serve mode (#3331) (#3614)

Integrated into release/v3.8.21 (#3331)

* docs(changelog): credit #3603 (Flash tier IDs) + #3604 (provider quotas) + #3605 (reasoning wrappers)

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(review): resolve findings from /review-reviews battery (v3.8.21 hardening) (#3618)

Pre-release hardening from the /review-reviews battery — 15 findings resolved (L1-L13,L15) + L14 live-verified WONTFIX, convergence re-review clean. lint/typecheck:core/test:vitest(146)/build green; zero new test:unit failures vs baseline 797de433f.

* chore(release): v3.8.21 CHANGELOG + i18n + env-doc sync

---------

Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Raxxoor <manker_lol@hotmail.com>
2026-06-11 04:01:24 -03:00
diegosouzapw
66ddbb0f5a chore: remove Petals executor and tighten route typing
Remove the Petals executor from registration and exports.

Improve type safety by replacing broad any usage in MCP tool registration
with inferred types and documenting dynamic handler type limitations.

Add request validation for the agent bridge cert route and expand tests to
ensure switch buttons explicitly declare type="button", preventing implicit
form submissions.
2026-06-02 02:10:34 -03:00
diegosouzapw
4295ecc5a7 fix(mitm): wire configureUpstreamCa at boot + after POST so AGENTBRIDGE_UPSTREAM_CA_CERT has runtime effect (R5-1)
In startMitm(), read AGENTBRIDGE_UPSTREAM_CA_CERT (env wins over stored path in
<dataDir>/mitm/upstream-ca.path) and call configureUpstreamCa() at process start;
failures are caught and logged — boot continues without custom CA.  In the POST
/api/tools/agent-bridge/upstream-ca handler, call configureUpstreamCa() immediately
after persisting the new path so the CA takes effect without reboot; throws → 400
with sanitizeErrorMessage (Hard Rule #12).  New test file
tests/unit/mitm-upstream-ca-wiring.test.ts validates the path-selection logic and
the route wiring (8 tests, 0 failures).
2026-05-28 22:13:30 -03:00
diegosouzapw
59c983e201 feat(inspector): add POST /sessions/[id]/requests to persist live snapshots (R5-5 backend half)
Wires the previously-dead appendSessionRequest() DB function to a new
POST /api/tools/traffic-inspector/sessions/[id]/requests route.
appendSessionRequest now returns the inserted seq so callers can confirm order.
InspectorSessionRequestAppendSchema (1 MB cap) guards the endpoint.
Integration test covers seq increments 1-2-3, requestCount sync, 400/404 paths,
and stack-trace-free error responses.
2026-05-28 21:43:24 -03:00
diegosouzapw
8e518ae008 feat(api): wire DNS propagation for traffic-inspector custom hosts (fix1) 2026-05-28 11:23:48 -03:00
diegosouzapw
1c0015a9ab merge(F6): Traffic Inspector REST + WS routes into Group A parent 2026-05-28 07:29:56 -03:00
diegosouzapw
668010bcf2 feat(api): traffic-inspector sessions + internal ingest routes (F6) 2026-05-28 01:24:26 -03:00
diegosouzapw
c16ce8a9e1 feat(api): traffic-inspector hosts + capture-modes + tls routes (F6) 2026-05-28 01:24:20 -03:00
diegosouzapw
ef79eab224 feat(api): traffic-inspector ws + requests + replay + annotation routes (F6) 2026-05-28 01:24:14 -03:00
diegosouzapw
19c4ff9bb0 feat(api): agent-bridge state + server + agents + cert + bypass + upstream-ca routes (F5)
12 REST routes under /api/tools/agent-bridge/ covering all AgentBridge
backend surfaces: server lifecycle, per-agent state/DNS/mappings/detect,
cert status/download/regenerate, bypass pattern CRUD, upstream CA config.
All routes use Zod validation and route errors through sanitizeErrorMessage.

feat(authz): mark agent-bridge LOCAL_ONLY + SPAWN_CAPABLE (F5)

Adds /api/tools/agent-bridge/ to both LOCAL_ONLY_API_PREFIXES and
SPAWN_CAPABLE_PREFIXES in routeGuard.ts — satisfying Hard Rules #15 + #17.
2026-05-28 00:24:38 -03:00