diff --git a/CHANGELOG.md b/CHANGELOG.md index 912fe2ca683d..c5ae417412a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ ## [Unreleased] +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated β€” Next.js middleware matcher omitted `/home`, so any visit reached the page directly on `REQUIRE_LOGIN` deployments (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 β€” extract no-log state to `compliance/noLog.ts`, switch callers to the leaf module, keep `compliance/index.ts` re-exports for backwards compat (#2650) +- **deepseek:** guard PoW solver Web Worker handler so `require()` no longer throws `ReferenceError: onmessage is not defined` under Node strict mode (#2724) +- **combos:** include no-auth providers (FreeAIAPIKey, BluesMinds, FreeModel.dev, opencode, …) in the combo builder picker β€” they were invisible because they never get rows in `provider_connections` (#2737) +- **translator:** allow the `web_search` server-tool family (`web_search_20250305`, `web_search_20250101`, plain `web_search`) in the Responses API translator and preserve the original versioned name on output (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow so the Trae IDE no longer 500s during token import (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace so aliases set via the Settings UI (e.g. `gpt-5.4 β†’ cx/gpt-5.4`) are honored instead of being overridden by provider inference (#2618, #2208) +- **kiro:** fall back to `document.execCommand("copy")` when the Clipboard API is unavailable (HTTP/non-secure contexts), so the "Copy authorization link" button works on LAN deployments (#2689) +- **cli:** raise `omniroute serve` ready timeout from 20s to 60s and add a TCP-listening fallback so Windows users no longer get phantom timeouts during slow Next.js cold start (#2460) + +## [Unreleased] + ### ✨ New Features - **proxy:** serverless relay endpoints with rate limiting (#2734) diff --git a/bin/cli/commands/serve.mjs b/bin/cli/commands/serve.mjs index 17b58e30c6b4..24fa344d4a89 100644 --- a/bin/cli/commands/serve.mjs +++ b/bin/cli/commands/serve.mjs @@ -269,7 +269,7 @@ async function runWithSupervisor( }); if (!showLog) { - waitForServer(dashboardPort, 20000).then(async (up) => { + waitForServer(dashboardPort, 60000).then(async (up) => { if (up) { if (useTray) await maybeStartTray(dashboardPort, apiPort, supervisor); onReady(dashboardPort, apiPort, noOpen); diff --git a/bin/cli/utils/pid.mjs b/bin/cli/utils/pid.mjs index 1f3ff526dfe6..6c94437e372b 100644 --- a/bin/cli/utils/pid.mjs +++ b/bin/cli/utils/pid.mjs @@ -61,16 +61,50 @@ export function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } -export async function waitForServer(port, timeout = 15000) { +// #2460: Default raised from 15s to 60s so Windows users (slower Next.js +// cold start due to filesystem watchers, antivirus, etc.) get a working +// "server ready" signal instead of a phantom timeout while the server is +// still booting. TCP fallback marks the server as ready when the port +// has been listening for >= 3s consecutively but /api/monitoring/health +// has not yet been mounted β€” common during dev cold start. +export async function waitForServer(port, timeout = 60000) { const start = Date.now(); + let tcpListeningSince = null; while (Date.now() - start < timeout) { try { const res = await fetch(`http://localhost:${port}/api/monitoring/health`, { signal: AbortSignal.timeout(2000), }); if (res.ok) return true; - } catch {} + // Server responded but health endpoint is not ready yet β€” keep + // polling, but the fact that we got a response means TCP is open. + if (tcpListeningSince === null) tcpListeningSince = Date.now(); + } catch { + const listening = await isPortListening(port).catch(() => false); + if (listening) { + if (tcpListeningSince === null) tcpListeningSince = Date.now(); + if (Date.now() - tcpListeningSince >= 3000) return true; + } else { + tcpListeningSince = null; + } + } await sleep(500); } return false; } + +async function isPortListening(port) { + const net = await import("node:net"); + return new Promise((resolve) => { + const socket = net.connect({ host: "127.0.0.1", port, timeout: 1000 }); + const finish = (ok) => { + try { + socket.destroy(); + } catch {} + resolve(ok); + }; + socket.once("connect", () => finish(true)); + socket.once("error", () => finish(false)); + socket.once("timeout", () => finish(false)); + }); +} diff --git a/docs/i18n/ar/CHANGELOG.md b/docs/i18n/ar/CHANGELOG.md index e4ec1f60e2c7..93d35e90a534 100644 --- a/docs/i18n/ar/CHANGELOG.md +++ b/docs/i18n/ar/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/az/CHANGELOG.md b/docs/i18n/az/CHANGELOG.md index 61abf8c13885..55977e916b1a 100644 --- a/docs/i18n/az/CHANGELOG.md +++ b/docs/i18n/az/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/bg/CHANGELOG.md b/docs/i18n/bg/CHANGELOG.md index 61abf8c13885..55977e916b1a 100644 --- a/docs/i18n/bg/CHANGELOG.md +++ b/docs/i18n/bg/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/bn/CHANGELOG.md b/docs/i18n/bn/CHANGELOG.md index e6870e5f08f2..c0b7d896f3c9 100644 --- a/docs/i18n/bn/CHANGELOG.md +++ b/docs/i18n/bn/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/cs/CHANGELOG.md b/docs/i18n/cs/CHANGELOG.md index 78452adfcd92..e85189339f96 100644 --- a/docs/i18n/cs/CHANGELOG.md +++ b/docs/i18n/cs/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/da/CHANGELOG.md b/docs/i18n/da/CHANGELOG.md index 5ddaf0f8f3db..9118f5b7525a 100644 --- a/docs/i18n/da/CHANGELOG.md +++ b/docs/i18n/da/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/de/CHANGELOG.md b/docs/i18n/de/CHANGELOG.md index a786a8db71e5..709596b56ea0 100644 --- a/docs/i18n/de/CHANGELOG.md +++ b/docs/i18n/de/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/es/CHANGELOG.md b/docs/i18n/es/CHANGELOG.md index fdc84441d636..b6d833255daf 100644 --- a/docs/i18n/es/CHANGELOG.md +++ b/docs/i18n/es/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/fa/CHANGELOG.md b/docs/i18n/fa/CHANGELOG.md index fce3d9a86895..db1752c50fb6 100644 --- a/docs/i18n/fa/CHANGELOG.md +++ b/docs/i18n/fa/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/fi/CHANGELOG.md b/docs/i18n/fi/CHANGELOG.md index 33b83a670df4..6457b9b5722f 100644 --- a/docs/i18n/fi/CHANGELOG.md +++ b/docs/i18n/fi/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/fr/CHANGELOG.md b/docs/i18n/fr/CHANGELOG.md index d25e573e994c..7a5403714574 100644 --- a/docs/i18n/fr/CHANGELOG.md +++ b/docs/i18n/fr/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/gu/CHANGELOG.md b/docs/i18n/gu/CHANGELOG.md index 173e35de5fca..ed2baef172c0 100644 --- a/docs/i18n/gu/CHANGELOG.md +++ b/docs/i18n/gu/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/he/CHANGELOG.md b/docs/i18n/he/CHANGELOG.md index 14eba4f2ae72..cbe80b59d3e5 100644 --- a/docs/i18n/he/CHANGELOG.md +++ b/docs/i18n/he/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/hi/CHANGELOG.md b/docs/i18n/hi/CHANGELOG.md index bfa8ad68f6f3..0e23ef0a986c 100644 --- a/docs/i18n/hi/CHANGELOG.md +++ b/docs/i18n/hi/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/hu/CHANGELOG.md b/docs/i18n/hu/CHANGELOG.md index c0bc76b1a38e..2d6297764945 100644 --- a/docs/i18n/hu/CHANGELOG.md +++ b/docs/i18n/hu/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/id/CHANGELOG.md b/docs/i18n/id/CHANGELOG.md index b41fd38e06e4..3d7bf9aeb28a 100644 --- a/docs/i18n/id/CHANGELOG.md +++ b/docs/i18n/id/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/in/CHANGELOG.md b/docs/i18n/in/CHANGELOG.md index 8eb8afa0d5ed..836886b526d7 100644 --- a/docs/i18n/in/CHANGELOG.md +++ b/docs/i18n/in/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/it/CHANGELOG.md b/docs/i18n/it/CHANGELOG.md index 000c080ffa50..e6a92b4934e8 100644 --- a/docs/i18n/it/CHANGELOG.md +++ b/docs/i18n/it/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ja/CHANGELOG.md b/docs/i18n/ja/CHANGELOG.md index c3e153579ac0..1efa867771a0 100644 --- a/docs/i18n/ja/CHANGELOG.md +++ b/docs/i18n/ja/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ko/CHANGELOG.md b/docs/i18n/ko/CHANGELOG.md index c2dd0705fc50..404c0bf9261e 100644 --- a/docs/i18n/ko/CHANGELOG.md +++ b/docs/i18n/ko/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/mr/CHANGELOG.md b/docs/i18n/mr/CHANGELOG.md index 84d6728bbbb7..96074e285cb0 100644 --- a/docs/i18n/mr/CHANGELOG.md +++ b/docs/i18n/mr/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ms/CHANGELOG.md b/docs/i18n/ms/CHANGELOG.md index 4e4818db7261..4e8546938492 100644 --- a/docs/i18n/ms/CHANGELOG.md +++ b/docs/i18n/ms/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/nl/CHANGELOG.md b/docs/i18n/nl/CHANGELOG.md index 430c806ccda3..85e15ce194f9 100644 --- a/docs/i18n/nl/CHANGELOG.md +++ b/docs/i18n/nl/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/no/CHANGELOG.md b/docs/i18n/no/CHANGELOG.md index e0d186dd1f5d..eaa8d08d99e6 100644 --- a/docs/i18n/no/CHANGELOG.md +++ b/docs/i18n/no/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/phi/CHANGELOG.md b/docs/i18n/phi/CHANGELOG.md index 07c38a325318..4f51106d343d 100644 --- a/docs/i18n/phi/CHANGELOG.md +++ b/docs/i18n/phi/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/pl/CHANGELOG.md b/docs/i18n/pl/CHANGELOG.md index fda50f7d95d4..249aed3ddbf2 100644 --- a/docs/i18n/pl/CHANGELOG.md +++ b/docs/i18n/pl/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/pt-BR/CHANGELOG.md b/docs/i18n/pt-BR/CHANGELOG.md index 6a0c886c7a89..73db08997212 100644 --- a/docs/i18n/pt-BR/CHANGELOG.md +++ b/docs/i18n/pt-BR/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/pt/CHANGELOG.md b/docs/i18n/pt/CHANGELOG.md index c182f3c7ecd5..56cd6b40e831 100644 --- a/docs/i18n/pt/CHANGELOG.md +++ b/docs/i18n/pt/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ro/CHANGELOG.md b/docs/i18n/ro/CHANGELOG.md index 2ea2c6e1a19d..6e233b659f54 100644 --- a/docs/i18n/ro/CHANGELOG.md +++ b/docs/i18n/ro/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ru/CHANGELOG.md b/docs/i18n/ru/CHANGELOG.md index 2dadc9d6babb..733c391b887a 100644 --- a/docs/i18n/ru/CHANGELOG.md +++ b/docs/i18n/ru/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/sk/CHANGELOG.md b/docs/i18n/sk/CHANGELOG.md index 22e8618918fc..f1ef4f182068 100644 --- a/docs/i18n/sk/CHANGELOG.md +++ b/docs/i18n/sk/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/sv/CHANGELOG.md b/docs/i18n/sv/CHANGELOG.md index ac1b9ab37efd..0911fe1cace2 100644 --- a/docs/i18n/sv/CHANGELOG.md +++ b/docs/i18n/sv/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/sw/CHANGELOG.md b/docs/i18n/sw/CHANGELOG.md index 4e06d1be6ab1..8fc40c668de4 100644 --- a/docs/i18n/sw/CHANGELOG.md +++ b/docs/i18n/sw/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ta/CHANGELOG.md b/docs/i18n/ta/CHANGELOG.md index 710f8ed939fe..966f4bfc7210 100644 --- a/docs/i18n/ta/CHANGELOG.md +++ b/docs/i18n/ta/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/te/CHANGELOG.md b/docs/i18n/te/CHANGELOG.md index 9ff6b41223c4..15ba2858cc24 100644 --- a/docs/i18n/te/CHANGELOG.md +++ b/docs/i18n/te/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/th/CHANGELOG.md b/docs/i18n/th/CHANGELOG.md index e37988d07b44..6b39c9364931 100644 --- a/docs/i18n/th/CHANGELOG.md +++ b/docs/i18n/th/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/tr/CHANGELOG.md b/docs/i18n/tr/CHANGELOG.md index f86f6ad2a5d6..c261e947feea 100644 --- a/docs/i18n/tr/CHANGELOG.md +++ b/docs/i18n/tr/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/uk-UA/CHANGELOG.md b/docs/i18n/uk-UA/CHANGELOG.md index 42423784ec87..089ba996d5cb 100644 --- a/docs/i18n/uk-UA/CHANGELOG.md +++ b/docs/i18n/uk-UA/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/ur/CHANGELOG.md b/docs/i18n/ur/CHANGELOG.md index 4f8dbabb437f..d2a762ded872 100644 --- a/docs/i18n/ur/CHANGELOG.md +++ b/docs/i18n/ur/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/vi/CHANGELOG.md b/docs/i18n/vi/CHANGELOG.md index 332c6f326c3c..8216387c5b4c 100644 --- a/docs/i18n/vi/CHANGELOG.md +++ b/docs/i18n/vi/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/i18n/zh-CN/CHANGELOG.md b/docs/i18n/zh-CN/CHANGELOG.md index 3ff82eb4113e..5c2741da9e85 100644 --- a/docs/i18n/zh-CN/CHANGELOG.md +++ b/docs/i18n/zh-CN/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.8.5] β€” 2026-05-26 + +### πŸ”’ Security + +- **authz:** redirect `/home` and `/home/:path*` to `/login` when unauthenticated (#2712) + +### πŸ”§ Bug Fixes + +- **mcp:** break callLogs ↔ compliance ESM cycle that deadlocks the bundled MCP server on Node.js 24 (#2650) +- **deepseek:** guard PoW solver Web Worker handler under Node strict mode (#2724) +- **combos:** include no-auth providers in the combo builder picker (#2737) +- **translator:** allow the `web_search` server-tool family in the Responses API translator (#2695) +- **oauth:** register the missing `trae` provider with `import_token` flow (#2658) +- **model:** merge settings-based aliases with the legacy DB alias namespace (#2618, #2208) +- **kiro:** clipboard fallback for HTTP / non-secure contexts (#2689) +- **cli:** raise `omniroute serve` ready timeout to 60s with TCP fallback for Windows cold start (#2460) + +--- + ## [Unreleased] ### ✨ New Features diff --git a/docs/reference/openapi.yaml b/docs/reference/openapi.yaml index 6ffd6739522a..1bd8d0dc14a3 100644 --- a/docs/reference/openapi.yaml +++ b/docs/reference/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: OmniRoute API - version: 3.8.4 + version: 3.8.5 description: | OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible endpoint that routes requests to multiple AI providers with load balancing, diff --git a/open-sse/lib/deepseek-pow-solver.cjs b/open-sse/lib/deepseek-pow-solver.cjs index 9318ec513d14..4b4ab62722af 100644 --- a/open-sse/lib/deepseek-pow-solver.cjs +++ b/open-sse/lib/deepseek-pow-solver.cjs @@ -1,3 +1,3 @@ const r=(id)=>{if(id===46743)return{Buffer};return{}};const t={},e={}; -"use strict";let n,i;r(42551),r(40966),r(70968),r(76966),r(35399),r(36279),r(87801),r(16389),r(36073),r(27448),r(10681),r(32014),r(46596),r(39008),r(71),r(85540);var o=r(46743),f=Object.create,u=Object.defineProperty,s=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,c=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty,l=(t,e,r)=>(r=null!=t?f(c(t)):{},((t,e,r,n)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of a(e))h.call(t,i)||i===r||u(t,i,{get:()=>e[i],enumerable:!(n=s(e,i))||n.enumerable});return t})(!e&&t&&t.__esModule?r:u(r,"default",{value:t,enumerable:!0}),t)),p=(n=(t,e)=>{e.exports=(t,e)=>(r,n)=>{let i=2*n,o=2*e;r[i]=t[o],r[i+1]=t[o+1]}},()=>(i||n((i={exports:{}}).exports,i),i.exports)),g=l(p()),y=t=>{let{A:e,C:r}=t;for(let t=0;t<25;t+=5){for(let n=0;n<5;n++)(0,g.default)(e,t+n)(r,n);for(let n=0;n<5;n++){let i=(t+n)*2,o=(n+1)%5*2,f=(n+2)%5*2;e[i]^=~r[o]&r[f],e[i+1]^=~r[o+1]&r[f+1]}}},d=new Uint32Array([0,1,0,32898,0x80000000,32906,0x80000000,0x80008000,0,32907,0,0x80000001,0x80000000,0x80008081,0x80000000,32777,0,138,0,136,0,0x80008009,0,0x8000000a,0,0x8000808b,0x80000000,139,0x80000000,32905,0x80000000,32771,0x80000000,32770,0x80000000,128,0,32778,0x80000000,0x8000000a,0x80000000,0x80008081,0x80000000,32896,0,0x80000001,0x80000000,0x80008008]),b=t=>{let{A:e,I:r}=t,n=2*r;e[0]^=d[n],e[1]^=d[n+1]},v=[10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1],w=[1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44],x=l(p()),E=t=>{let{A:e,C:r,W:n}=t,i=0;(0,x.default)(e,i+1)(n,i);let o=0,f=0,u=0,s=32;for(;i<24;i++){let t=v[i],a=w[i];(0,x.default)(e,t)(r,0),o=n[0],f=n[1],s=32-a,n[u=a<32?0:1]=o<>>s,n[(u+1)%2]=f<>>s,(0,x.default)(n,0)(e,t),(0,x.default)(r,0)(n,0)}},m=l(p()),B=t=>{let{A:e,C:r,D:n,W:i}=t,o=0,f=0;for(let t=0;t<5;t++){let n=2*t,i=(t+5)*2,o=(t+10)*2,f=(t+15)*2,u=(t+20)*2;r[n]=e[n]^e[i]^e[o]^e[f]^e[u],r[n+1]=e[n+1]^e[i+1]^e[o+1]^e[f+1]^e[u+1]}for(let t=0;t<5;t++){(0,m.default)(r,(t+1)%5)(i,0),o=i[0],f=i[1],i[0]=o<<1|f>>>31,i[1]=f<<1|o>>>31,n[2*t]=r[(t+4)%5*2]^i[0],n[2*t+1]=r[(t+4)%5*2+1]^i[1];for(let r=0;r<25;r+=5)e[(r+t)*2]^=n[2*t],e[(r+t)*2+1]^=n[2*t+1]}},I=(t,e)=>{for(let r=0;r{for(let r=0;r>>8,e[r+2]=t[n+1]>>>16,e[r+3]=t[n+1]>>>24,e[r+4]=t[n],e[r+5]=t[n]>>>8,e[r+6]=t[n]>>>16,e[r+7]=t[n]>>>24}return e},U=function(t){let e,r,n,{capacity:i,padding:f}=t,u=i/8,s=200-i/4,a={keccak:(e=new Uint32Array(10),r=new Uint32Array(10),n=new Uint32Array(2),t=>{for(let i=1;i<24;i++)B({A:t,C:e,D:r,W:n}),E({A:t,C:e,W:n}),y({A:t,C:e}),b({A:t,I:i});e.fill(0),r.fill(0),n.fill(0)}),state:new Uint32Array(50),queue:o.Buffer.allocUnsafe(s),queueOffset:0};return this.getState=()=>a,this.setState=t=>{a.keccak=t.keccak,a.state.set(t.state.slice()),t.queue.copy(a.queue),a.queueOffset=t.queueOffset},this.absorb=t=>{for(let e=0;e=s&&(I(a.queue,a.state),a.keccak(a.state),a.queueOffset=0);return this},this.squeeze=t=>{let e={buffer:o.Buffer.allocUnsafe(u),padding:t,queue:o.Buffer.allocUnsafe(a.queue.length),state:new Uint32Array(a.state.length)};a.queue.copy(e.queue);for(let t=0;t(a.queue.fill(0),a.state.fill(0),a.queueOffset=0,this),this.copy=()=>{let t=new U({capacity:i,padding:f});return t.setState(this.getState()),t},this};onmessage=t=>{if("pow-challenge"!==t.data.type)return;let{algorithm:e,challenge:r,salt:n,difficulty:i,signature:f,expireAt:u}=t.data.challenge;try{let t=((t,e,r,n,i)=>{if("DeepSeekHashV1"!==t)throw Error("Unsupported algorithm: "+t);let f="".concat(r,"_").concat(i,"_"),u=function(t,e,r){if(t.length%2!=0)throw RangeError("c.length");if(r<=0||!Number.isSafeInteger(r))throw RangeError("d");for(var n=(function t(){var e=this;return this&&this.constructor===t?(this._sponge=new U({capacity:256}),this.update=t=>{if("string"==typeof t)return this._sponge.absorb(o.Buffer.from(t,"utf8")),this;throw TypeError("input not a string")},this.digest=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"hex";return e._sponge.squeeze(6).toString(t)},this.copy=()=>{let e=new t;return e._sponge=this._sponge.copy(),e},this):new t})(256).update(e),i=0;i(r=null!=t?f(c(t)):{},((t,e,r,n)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of a(e))h.call(t,i)||i===r||u(t,i,{get:()=>e[i],enumerable:!(n=s(e,i))||n.enumerable});return t})(!e&&t&&t.__esModule?r:u(r,"default",{value:t,enumerable:!0}),t)),p=(n=(t,e)=>{e.exports=(t,e)=>(r,n)=>{let i=2*n,o=2*e;r[i]=t[o],r[i+1]=t[o+1]}},()=>(i||n((i={exports:{}}).exports,i),i.exports)),g=l(p()),y=t=>{let{A:e,C:r}=t;for(let t=0;t<25;t+=5){for(let n=0;n<5;n++)(0,g.default)(e,t+n)(r,n);for(let n=0;n<5;n++){let i=(t+n)*2,o=(n+1)%5*2,f=(n+2)%5*2;e[i]^=~r[o]&r[f],e[i+1]^=~r[o+1]&r[f+1]}}},d=new Uint32Array([0,1,0,32898,0x80000000,32906,0x80000000,0x80008000,0,32907,0,0x80000001,0x80000000,0x80008081,0x80000000,32777,0,138,0,136,0,0x80008009,0,0x8000000a,0,0x8000808b,0x80000000,139,0x80000000,32905,0x80000000,32771,0x80000000,32770,0x80000000,128,0,32778,0x80000000,0x8000000a,0x80000000,0x80008081,0x80000000,32896,0,0x80000001,0x80000000,0x80008008]),b=t=>{let{A:e,I:r}=t,n=2*r;e[0]^=d[n],e[1]^=d[n+1]},v=[10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1],w=[1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44],x=l(p()),E=t=>{let{A:e,C:r,W:n}=t,i=0;(0,x.default)(e,i+1)(n,i);let o=0,f=0,u=0,s=32;for(;i<24;i++){let t=v[i],a=w[i];(0,x.default)(e,t)(r,0),o=n[0],f=n[1],s=32-a,n[u=a<32?0:1]=o<>>s,n[(u+1)%2]=f<>>s,(0,x.default)(n,0)(e,t),(0,x.default)(r,0)(n,0)}},m=l(p()),B=t=>{let{A:e,C:r,D:n,W:i}=t,o=0,f=0;for(let t=0;t<5;t++){let n=2*t,i=(t+5)*2,o=(t+10)*2,f=(t+15)*2,u=(t+20)*2;r[n]=e[n]^e[i]^e[o]^e[f]^e[u],r[n+1]=e[n+1]^e[i+1]^e[o+1]^e[f+1]^e[u+1]}for(let t=0;t<5;t++){(0,m.default)(r,(t+1)%5)(i,0),o=i[0],f=i[1],i[0]=o<<1|f>>>31,i[1]=f<<1|o>>>31,n[2*t]=r[(t+4)%5*2]^i[0],n[2*t+1]=r[(t+4)%5*2+1]^i[1];for(let r=0;r<25;r+=5)e[(r+t)*2]^=n[2*t],e[(r+t)*2+1]^=n[2*t+1]}},I=(t,e)=>{for(let r=0;r{for(let r=0;r>>8,e[r+2]=t[n+1]>>>16,e[r+3]=t[n+1]>>>24,e[r+4]=t[n],e[r+5]=t[n]>>>8,e[r+6]=t[n]>>>16,e[r+7]=t[n]>>>24}return e},U=function(t){let e,r,n,{capacity:i,padding:f}=t,u=i/8,s=200-i/4,a={keccak:(e=new Uint32Array(10),r=new Uint32Array(10),n=new Uint32Array(2),t=>{for(let i=1;i<24;i++)B({A:t,C:e,D:r,W:n}),E({A:t,C:e,W:n}),y({A:t,C:e}),b({A:t,I:i});e.fill(0),r.fill(0),n.fill(0)}),state:new Uint32Array(50),queue:o.Buffer.allocUnsafe(s),queueOffset:0};return this.getState=()=>a,this.setState=t=>{a.keccak=t.keccak,a.state.set(t.state.slice()),t.queue.copy(a.queue),a.queueOffset=t.queueOffset},this.absorb=t=>{for(let e=0;e=s&&(I(a.queue,a.state),a.keccak(a.state),a.queueOffset=0);return this},this.squeeze=t=>{let e={buffer:o.Buffer.allocUnsafe(u),padding:t,queue:o.Buffer.allocUnsafe(a.queue.length),state:new Uint32Array(a.state.length)};a.queue.copy(e.queue);for(let t=0;t(a.queue.fill(0),a.state.fill(0),a.queueOffset=0,this),this.copy=()=>{let t=new U({capacity:i,padding:f});return t.setState(this.getState()),t},this};/* #2724: guard Web Worker handler β€” Node.js require() loads this CJS in strict mode where bare `onmessage = ...` throws ReferenceError */typeof self!=="undefined"&&typeof postMessage!=="undefined"&&(globalThis.onmessage=t=>{if("pow-challenge"!==t.data.type)return;let{algorithm:e,challenge:r,salt:n,difficulty:i,signature:f,expireAt:u}=t.data.challenge;try{let t=((t,e,r,n,i)=>{if("DeepSeekHashV1"!==t)throw Error("Unsupported algorithm: "+t);let f="".concat(r,"_").concat(i,"_"),u=function(t,e,r){if(t.length%2!=0)throw RangeError("c.length");if(r<=0||!Number.isSafeInteger(r))throw RangeError("d");for(var n=(function t(){var e=this;return this&&this.constructor===t?(this._sponge=new U({capacity:256}),this.update=t=>{if("string"==typeof t)return this._sponge.absorb(o.Buffer.from(t,"utf8")),this;throw TypeError("input not a string")},this.digest=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"hex";return e._sponge.squeeze(6).toString(t)},this.copy=()=>{let e=new t;return e._sponge=this._sponge.copy(),e},this):new t})(256).update(e),i=0;i; const RESPONSES_STORE_MARKER = "_omnirouteResponsesStore"; const COPILOT_REASONING_SUMMARY_MARKER = "_omnirouteCopilotReasoningSummary"; +// Forward-compatible regex: matches web_search, web_search_20250305, and any future versioned names. +const WEB_SEARCH_TOOL_TYPES = /^web_search/; + function toRecord(value: unknown): JsonRecord { return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {}; } @@ -67,13 +70,15 @@ export function openaiResponsesToOpenAIRequest( const tool = toRecord(toolValue); const toolType = toString(tool.type); // Allow: function tools, tools already in Chat format (have .function property), CLI subagent tools, - // and namespace tools (MCP tool groups used by Codex/OpenAI Responses API). + // namespace tools (MCP tool groups used by Codex/OpenAI Responses API), and web_search server tools + // (Anthropic versioned: web_search_20250305, web_search_20250101, etc. β€” or plain web_search). if ( toolType && toolType !== "function" && toolType !== "custom" && toolType !== "command" && toolType !== "namespace" && + !WEB_SEARCH_TOOL_TYPES.test(toolType) && !tool.function ) { throw unsupportedFeature( @@ -255,6 +260,13 @@ export function openaiResponsesToOpenAIRequest( result.tools = root.tools.map((toolValue) => { const tool = toRecord(toolValue); if (tool.function) return toolValue; + const toolType = toString(tool.type); + // Pass web_search server tools through with their original type (versioned or plain). + // These have no Chat Completions equivalent; preserve as-is so upstreams that understand + // Anthropic-style web_search_YYYYMMDD naming receive the exact name they expect. + if (WEB_SEARCH_TOOL_TYPES.test(toolType)) { + return toolValue; + } return { type: "function", function: { diff --git a/package-lock.json b/package-lock.json index 688aff16b987..929734a3103c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute", - "version": "3.8.4", + "version": "3.8.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute", - "version": "3.8.4", + "version": "3.8.5", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index b20a742a8e8a..884a186db3ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omniroute", - "version": "3.8.4", + "version": "3.8.5", "description": "Unified AI router with 160+ providers, RTK+Caveman compression, auto fallback, MCP/A2A, desktop, PWA, and OpenAI-compatible APIs.", "type": "module", "bin": { diff --git a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx index fef72850605a..1f123ba19ffe 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx +++ b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx @@ -61,6 +61,7 @@ import { normalizeModelCatalogSource, } from "@/shared/utils/modelCatalogSearch"; import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard"; +import { copyToClipboard } from "@/shared/utils/clipboard"; import { MODEL_COMPAT_PROTOCOL_KEYS, type ModelCompatProtocolKey, @@ -7355,11 +7356,11 @@ function AddApiKeyModal({ const copyCommandCodeValue = async (value: string | undefined, key: string) => { if (!value) return; - try { - await navigator.clipboard.writeText(value); + const ok = await copyToClipboard(value); + if (ok) { setCopiedCommandCodeField(key); window.setTimeout(() => setCopiedCommandCodeField(null), 1500); - } catch { + } else { setSaveError("Copy failed. Select the text and copy it manually."); } }; diff --git a/src/lib/combos/builderOptions.ts b/src/lib/combos/builderOptions.ts index 6bb17a8a7181..12d2add45033 100644 --- a/src/lib/combos/builderOptions.ts +++ b/src/lib/combos/builderOptions.ts @@ -13,6 +13,7 @@ import { getSyncedCapabilities } from "@/lib/modelsDevSync"; import { getModelsByProviderId } from "@/shared/constants/models"; import { AI_PROVIDERS, + NOAUTH_PROVIDERS, isAnthropicCompatibleProvider, isClaudeCodeCompatibleProvider, isOpenAICompatibleProvider, @@ -514,6 +515,131 @@ export async function getComboBuilderOptions(): Promise(); + const builtInModels = getModelsByProviderId(providerId); + const syncedModels = normalizeSyncedModels( + (syncedModelsMap as Record)[providerId] + ); + const customModels = normalizeCustomModels( + (customModelsMap as Record)[providerId] + ); + const fallbackModels = getCompatibleFallbackModels(providerId, builtInModels); + const acceptsArbitraryModel = + Boolean((AI_PROVIDERS[providerId] as JsonRecord | undefined)?.passthroughModels) || + isOpenAICompatibleProvider(providerId) || + isAnthropicCompatibleProvider(providerId) || + isClaudeCodeCompatibleProvider(providerId); + + for (const model of syncedModels) { + const resolved = getResolvedModelCapabilities({ + provider: providerId, + model: toStringOrNull(model.id), + }); + addModelOption(modelMap, providerId, { + id: toStringOrNull(model.id), + name: toStringOrNull(model.name), + source: "imported", + supportedEndpoints: toStringArray(model.supportedEndpoints), + contextLength: toNumberOrNull(model.inputTokenLimit) ?? resolved.contextWindow, + outputTokenLimit: toNumberOrNull(model.outputTokenLimit) ?? resolved.maxOutputTokens, + supportsThinking: + typeof model.supportsThinking === "boolean" + ? model.supportsThinking + : (resolved.supportsThinking ?? undefined), + }); + } + + for (const model of builtInModels as RegistryModel[]) { + const resolved = getResolvedModelCapabilities({ + provider: providerId, + model: toStringOrNull(model.id), + }); + addModelOption(modelMap, providerId, { + id: toStringOrNull(model.id), + name: toStringOrNull(model.name), + source: "system", + contextLength: toNumberOrNull(model.contextLength) ?? resolved.contextWindow, + outputTokenLimit: resolved.maxOutputTokens, + supportsThinking: resolved.supportsThinking ?? undefined, + }); + } + + for (const model of customModels) { + if (model.isHidden === true) continue; + const source = ["api-sync", "auto-sync", "imported"].includes( + toStringOrNull(model.source)?.toLowerCase() || "" + ) + ? "imported" + : ("custom" as BuilderModelSource); + const resolved = getResolvedModelCapabilities({ + provider: providerId, + model: toStringOrNull(model.id), + }); + addModelOption(modelMap, providerId, { + id: toStringOrNull(model.id), + name: toStringOrNull(model.name), + source, + supportedEndpoints: toStringArray(model.supportedEndpoints), + apiFormat: toStringOrNull(model.apiFormat), + contextLength: toNumberOrNull(model.inputTokenLimit) ?? resolved.contextWindow, + outputTokenLimit: toNumberOrNull(model.outputTokenLimit) ?? resolved.maxOutputTokens, + supportsThinking: + typeof model.supportsThinking === "boolean" + ? model.supportsThinking + : (resolved.supportsThinking ?? undefined), + }); + } + + if (Array.isArray(fallbackModels)) { + for (const model of fallbackModels) { + const resolved = getResolvedModelCapabilities({ + provider: providerId, + model: toStringOrNull(model.id), + }); + addModelOption(modelMap, providerId, { + id: toStringOrNull(model.id), + name: toStringOrNull(model.name), + source: "fallback", + contextLength: + typeof (model as { contextLength?: number }).contextLength === "number" + ? (model as { contextLength?: number }).contextLength || null + : resolved.contextWindow, + outputTokenLimit: resolved.maxOutputTokens, + supportsThinking: resolved.supportsThinking ?? undefined, + }); + } + } + + const displayName = (providerEntryName(providerId) || + getProviderDisplayName(providerId, null) || + providerId) as string; + + providers.push({ + providerId, + providerType: providerVisual.providerType, + displayName, + alias: providerVisual.alias, + prefix: null, + icon: providerVisual.icon, + color: providerVisual.color, + source: providerVisual.source, + acceptsArbitraryModel, + connectionCount: 0, + activeConnectionCount: 0, + modelCount: modelMap.size, + connections: [], + models: Array.from(modelMap.values()).sort(compareModels), + }); + } + const comboRefs = (combos as JsonRecord[]) .filter((combo) => combo.isHidden !== true && combo.isActive !== false) .map((combo) => ({ diff --git a/src/lib/compliance/index.ts b/src/lib/compliance/index.ts index b966813c8144..29b848500838 100644 --- a/src/lib/compliance/index.ts +++ b/src/lib/compliance/index.ts @@ -413,90 +413,10 @@ export function countAuditLog(filter: AuditLogFilter = {}) { } // ─── No-Log Opt-Out ──────────────── - -/** @type {Set} API key IDs with logging disabled */ -const noLogKeys = new Set(); -const noLogDbCache = new Map(); -let noLogColumnVerified = false; -let hasNoLogColumn = false; -const NO_LOG_CACHE_TTL_MS = 30_000; -const noLogIdsFromEnv = (process.env.NO_LOG_API_KEY_IDS || "") - .split(",") - .map((value) => value.trim()) - .filter(Boolean); -for (const id of noLogIdsFromEnv) { - noLogKeys.add(id); -} - -/** - * Set whether an API key opts out of request logging. - * - * @param {string} apiKeyId - * @param {boolean} noLog - */ -export function setNoLog(apiKeyId: string, noLog: boolean) { - if (noLog) { - noLogKeys.add(apiKeyId); - } else { - noLogKeys.delete(apiKeyId); - } - noLogDbCache.set(apiKeyId, { value: noLog, timestamp: Date.now() }); -} - -function ensureNoLogColumn(db: SqliteAdapter) { - if (noLogColumnVerified) { - return hasNoLogColumn; - } - - try { - const columns = db.prepare("PRAGMA table_info(api_keys)").all() as Array<{ name: string }>; - hasNoLogColumn = columns.some((column) => column.name === "no_log"); - } catch { - hasNoLogColumn = false; - } - - noLogColumnVerified = true; - return hasNoLogColumn; -} - -function readNoLogFromDb(apiKeyId: string): boolean { - const db = getDb(); - if (!db || !apiKeyId) return false; - if (!ensureNoLogColumn(db)) return false; - - const cached = noLogDbCache.get(apiKeyId); - if (cached && Date.now() - cached.timestamp < NO_LOG_CACHE_TTL_MS) { - return cached.value; - } - - try { - const row = db.prepare("SELECT no_log FROM api_keys WHERE id = ?").get(apiKeyId) as - | { no_log?: number } - | undefined; - const value = Boolean(row && Number(row.no_log) === 1); - noLogDbCache.set(apiKeyId, { value, timestamp: Date.now() }); - return value; - } catch { - return false; - } -} - -/** - * Check if an API key has opted out of logging. - * - * @param {string} apiKeyId - * @returns {boolean} - */ -export function isNoLog(apiKeyId: string) { - if (!apiKeyId) return false; - if (noLogKeys.has(apiKeyId)) return true; - - const persistedNoLog = readNoLogFromDb(apiKeyId); - if (persistedNoLog) { - noLogKeys.add(apiKeyId); - } - return persistedNoLog; -} +// Moved to ./noLog.ts to break the callLogs β†’ compliance β†’ callLogs ESM cycle +// that deadlocks the bundled MCP server under Node.js 24 (#2650). Re-exported +// here so downstream callers that import from "../compliance" keep working. +export { isNoLog, setNoLog } from "./noLog"; // ─── Log Retention / Cleanup ──────────────── diff --git a/src/lib/compliance/noLog.ts b/src/lib/compliance/noLog.ts new file mode 100644 index 000000000000..6b04cfd3195c --- /dev/null +++ b/src/lib/compliance/noLog.ts @@ -0,0 +1,86 @@ +import type { SqliteAdapter } from "@/lib/db/adapters/types"; +import { getDbInstance } from "../db/core"; + +// #2650: extracted from compliance/index.ts to break the +// callLogs.ts β†’ compliance/index.ts β†’ callLogs.ts cycle that deadlocks +// the bundled MCP server under Node.js 24's stricter ESM evaluation. + +function getDb(): SqliteAdapter | null { + try { + return getDbInstance(); + } catch { + return null; + } +} + +const noLogKeys = new Set(); +const noLogDbCache = new Map(); +let noLogColumnVerified = false; +let hasNoLogColumn = false; +const NO_LOG_CACHE_TTL_MS = 30_000; + +const noLogIdsFromEnv = (process.env.NO_LOG_API_KEY_IDS || "") + .split(",") + .map((value) => value.trim()) + .filter(Boolean); +for (const id of noLogIdsFromEnv) { + noLogKeys.add(id); +} + +export function setNoLog(apiKeyId: string, noLog: boolean): void { + if (noLog) { + noLogKeys.add(apiKeyId); + } else { + noLogKeys.delete(apiKeyId); + } + noLogDbCache.set(apiKeyId, { value: noLog, timestamp: Date.now() }); +} + +function ensureNoLogColumn(db: SqliteAdapter): boolean { + if (noLogColumnVerified) { + return hasNoLogColumn; + } + + try { + const columns = db.prepare("PRAGMA table_info(api_keys)").all() as Array<{ name: string }>; + hasNoLogColumn = columns.some((column) => column.name === "no_log"); + } catch { + hasNoLogColumn = false; + } + + noLogColumnVerified = true; + return hasNoLogColumn; +} + +function readNoLogFromDb(apiKeyId: string): boolean { + const db = getDb(); + if (!db || !apiKeyId) return false; + if (!ensureNoLogColumn(db)) return false; + + const cached = noLogDbCache.get(apiKeyId); + if (cached && Date.now() - cached.timestamp < NO_LOG_CACHE_TTL_MS) { + return cached.value; + } + + try { + const row = db.prepare("SELECT no_log FROM api_keys WHERE id = ?").get(apiKeyId) as + | { no_log?: number } + | undefined; + const value = Boolean(row && Number(row.no_log) === 1); + noLogDbCache.set(apiKeyId, { value, timestamp: Date.now() }); + return value; + } catch { + return false; + } +} + +export function isNoLog(apiKeyId: string): boolean { + if (!apiKeyId) return false; + if (noLogKeys.has(apiKeyId)) return true; + + const persistedNoLog = readNoLogFromDb(apiKeyId); + if (persistedNoLog) { + noLogKeys.add(apiKeyId); + } + return persistedNoLog; +} diff --git a/src/lib/db/apiKeys.ts b/src/lib/db/apiKeys.ts index 9f44fab27114..4fd42fcb3b38 100644 --- a/src/lib/db/apiKeys.ts +++ b/src/lib/db/apiKeys.ts @@ -8,7 +8,7 @@ import { getDbInstance, rowToCamel } from "./core"; import { backupDbFile } from "./backup"; import { registerDbStateResetter } from "./stateReset"; import { getKeyGroupsForApiKey, checkKeyModelAccess } from "./apiKeyGroups"; -import { setNoLog } from "../compliance"; +import { setNoLog } from "../compliance/noLog"; // ──────────────── Performance Optimizations ──────────────── diff --git a/src/lib/db/detailedLogs.ts b/src/lib/db/detailedLogs.ts index f811e751a082..7fdab54e1548 100644 --- a/src/lib/db/detailedLogs.ts +++ b/src/lib/db/detailedLogs.ts @@ -8,7 +8,7 @@ import { v4 as uuidv4 } from "uuid"; import { getDbInstance } from "./core"; import { getSettings } from "./settings"; -import { isNoLog } from "../compliance"; +import { isNoLog } from "../compliance/noLog"; import { protectPayloadForLog, serializePayloadForStorage, diff --git a/src/lib/oauth/constants/oauth.ts b/src/lib/oauth/constants/oauth.ts index c21fabac5de0..d829e8f7413b 100644 --- a/src/lib/oauth/constants/oauth.ts +++ b/src/lib/oauth/constants/oauth.ts @@ -290,6 +290,24 @@ export const CURSOR_CONFIG = { }, }; +// Trae IDE Configuration (#2658) +// +// Trae is an AI-native IDE by ByteDance. Authentication is currently imported +// token only β€” users sign in inside Trae and paste the resulting API token +// here. ByteDance has not published a public OAuth client_id/secret or a CLI +// with extractable credentials, so no automated discovery is possible yet. +// If ByteDance ever publishes a public device-code or PKCE flow, swap +// flowType in src/lib/oauth/providers/trae.ts and wire endpoints below. +export const TRAE_CONFIG = { + apiEndpoint: "https://api.trae.ai", + clientType: "ide", + tokenStoragePaths: { + linux: "~/.config/Trae/User/globalStorage/state.vscdb", + macos: "/Users//Library/Application Support/Trae/User/globalStorage/state.vscdb", + windows: "%APPDATA%\\Trae\\User\\globalStorage\\state.vscdb", + }, +}; + // Windsurf / Devin CLI Configuration // // Authentication uses PKCE Authorization Code Flow β€” same pattern as Codex CLI. diff --git a/src/lib/oauth/providers/index.ts b/src/lib/oauth/providers/index.ts index 31651dac5b58..a126b93af728 100644 --- a/src/lib/oauth/providers/index.ts +++ b/src/lib/oauth/providers/index.ts @@ -21,6 +21,7 @@ import { github } from "./github"; import { gitlabDuo } from "./gitlab-duo"; import { kiro } from "./kiro"; import { cursor } from "./cursor"; +import { trae } from "./trae"; import { kilocode } from "./kilocode"; import { cline } from "./cline"; import { windsurf } from "./windsurf"; @@ -39,6 +40,7 @@ export const PROVIDERS = { kiro, "amazon-q": kiro, cursor, + trae, kilocode, cline, windsurf, diff --git a/src/lib/oauth/providers/trae.ts b/src/lib/oauth/providers/trae.ts index f11b4edeaa5b..ddc45134c444 100644 --- a/src/lib/oauth/providers/trae.ts +++ b/src/lib/oauth/providers/trae.ts @@ -21,11 +21,12 @@ import { TRAE_CONFIG } from "../constants/oauth"; export const trae = { config: TRAE_CONFIG, flowType: "import_token", - mapTokens: (tokens) => ({ + mapTokens: (tokens: { accessToken: string; expiresIn?: number; machineId?: string }) => ({ accessToken: tokens.accessToken, refreshToken: null, expiresIn: tokens.expiresIn || 86400, providerSpecificData: { + machineId: tokens.machineId, authMethod: "imported", }, }), diff --git a/src/lib/usage/callLogs.ts b/src/lib/usage/callLogs.ts index ca3329110abc..b636ea7e44f0 100644 --- a/src/lib/usage/callLogs.ts +++ b/src/lib/usage/callLogs.ts @@ -18,7 +18,7 @@ import { getPromptCacheCreationTokensOrNull, getReasoningTokensOrNull, } from "./tokenAccounting"; -import { isNoLog } from "../compliance"; +import { isNoLog } from "../compliance/noLog"; import { sanitizePII } from "../piiSanitizer"; import { protectPayloadForLog, parseStoredPayload } from "../logPayloads"; import { getCallLogMaxEntries, getCallLogRetentionDays, getCallLogsTableMaxRows } from "../logEnv"; diff --git a/src/proxy.ts b/src/proxy.ts index cfce41dd4726..eaa312e0911c 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -9,6 +9,8 @@ export const config = { matcher: [ "/", "/dashboard/:path*", + "/home", + "/home/:path*", "/api/:path*", "/v1/:path*", "/v1", diff --git a/src/server/authz/pipeline.ts b/src/server/authz/pipeline.ts index 137d4458c708..36f0a96759c6 100644 --- a/src/server/authz/pipeline.ts +++ b/src/server/authz/pipeline.ts @@ -61,7 +61,12 @@ function rejectionResponse( } function isDashboardPath(pathname: string): boolean { - return pathname === "/dashboard" || pathname.startsWith("/dashboard/"); + return ( + pathname === "/dashboard" || + pathname.startsWith("/dashboard/") || + pathname === "/home" || + pathname.startsWith("/home/") + ); } function isManagementDashboardRoute( diff --git a/src/shared/components/KiroSocialOAuthModal.tsx b/src/shared/components/KiroSocialOAuthModal.tsx index 3af87e72e603..ae31b6d1f738 100644 --- a/src/shared/components/KiroSocialOAuthModal.tsx +++ b/src/shared/components/KiroSocialOAuthModal.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useRef } from "react"; import Modal from "./Modal"; import Button from "./Button"; +import { copyToClipboard } from "@/shared/utils/clipboard"; type KiroSocialOAuthModalProps = { isOpen: boolean; @@ -133,7 +134,7 @@ export default function KiroSocialOAuthModal({ {authUrl.length > 80 ? authUrl.slice(0, 80) + "..." : authUrl}