Retargetado para release/v3.8.51 (release/v3.8.50 está congelada — freeze issue #11439). Validado em lote combinado (batch-0824h2, junto de #11435/#11436/#11437) contra o tip de release/v3.8.51: typecheck:core limpo, gates estáticos OK, 127/127 testes focados passando.
Investigação sólida com repro real via container isolado, três causas independentes identificadas e corrigidas com testes de regressão dedicados para cada uma. Obrigado pela contribuição!
Merging --admin: this is itself the base-red drain PR (compression/i18n-vi/i18n-pt-br/kiro/memory mini-cluster). Remaining fails (ESLint warnings ratchet drift, dast-smoke advisory) are not blocking; isRequired:null on dast-smoke.
Validated on a 4-PR combined board: provider-patch-ratelimit-protection-11278 2/2 + 56/56 sibling suites, typecheck:core clean, gates within baseline. PUT /api/providers/[id] can no longer silently enable rate-limit protection just because EditConnectionModal sends rateLimitOverrides on every save — the runtime toggle now strictly follows the persisted DB row. Closes#11278.
Validated on a 2-PR combined board: routeGuard 36/36 (within the 68/68 focused-file total), a2a-task-owner-idor 7/7, a2a-tasks-auth, search-baseurl-ssrf-guard, cli-serve-hostname, spawn-capable-prefixes-client-safe all green, typecheck:core + dashboard-typecheck clean, gates within baseline. Five real High-severity advisories fixed with TDD (each failing-then-passing): settings export/import-json ALWAYS_PROTECTED completion, MITM route LOCAL_ONLY+SPAWN_CAPABLE gating, search baseUrl SSRF/IMDS guard, A2A REST task auth+ownership (previously none at all), and the loud boot exposure warning. GHSA-cjv9 confirmed already closed on this base (verified). Round 3 of the advisory sweep.
Validated on the combined 8-PR board + the branch itself: vertex-anthropic-models 4/4 (new — pushed to your branch as a fix-in-place commit per Hard Rule #8, covering the parser's global/project-scoped resource names, malformed-input handling, and the claude-* → targetFormat heuristic on vertex/vertex-partner), 88/88 across the board's focused suites, typecheck:core clean, gates within baseline. Anthropic partner models on Vertex AI now discover dynamically via the Model Garden publisher endpoint and route through the Claude translator even for models outside the static registry. Thank you @maci0!
Validated on the combined 8-PR board: ollama-local-capabilities-routing 3/3, managed-model-import 9/9 (including the integration with the carried Gemini-3.5-Flash cleanup from #11259), 88/88 across the board's focused suites, typecheck:core + dashboard-typecheck clean, gates within baseline. This brings #11088 to the release line — it had squash-merged to main by base error (mine) — AND fixes the two defects the port caught: the global filter drop that leaked image/video models into OpenAI chat selections (now scoped to self-hosted providers) and the unregistered hard-lease credential site. Exemplary port discipline: byte-identical carry + the corrections in a separate reviewable commit + the superpowers docs deliberately left out. main still needs the same two-line fix. Thank you @yourspraveen!
Validated on the resolved merge against the current tip (527da656 + the post-#11281 rebaseline): the single conflict was a comment-only collision in providers/[id]/models/route.ts (kept the tip's #10828-ordering note). Focused suites 125/125 across all 13 touched test files (build-sqlite-stub, cc-compatible, copilot-claude-messages, copilot-gemini-route, executor-github, ghe-copilot, github-copilot-discovery-token, github-copilot-model-discovery, noauth-sibling-7620, provider-header-profiles, provider-models-config, request-log-payloads, upstream-error-passthrough), typecheck:core clean, file-size/changelog-integrity OK. Merged --admin over the inherited 2026-08-23 base-red cluster (#9985) — the reds are proven tip failures (CLI catalog cluster + @testing-library allowlist, being drained by #11280), not from this diff. Note: the rebase means several items the body listed (relay x-relay-path SSRF, /v1/search blocked-providers, #10736 rotation fence, #10903, #10865, #10899, #10916) already landed upstream and are NOT in this delta — the delta is: better-sqlite3 build guard + build heap/worker caps + telemetry-off (#10060 re-derived), credential-echo passthrough refusal + OCR/moderation redaction + call-log key redaction, Copilot CLI 1.0.81-6 wire identity + Claude→/v1/messages name-matched routing + discovery token fix, CC model_not_found 400, compat overrides for no-auth aliases (#7620-pinned). The Copilot wire-identity change is the one to watch in production. Thank you @arminanton — and the ported-author credits in the commit history (@rqzbeh, yidecode, the #10899/#10916 authors) are preserved. Your config-posture finding (REQUIRE_API_KEY default vs 0.0.0.0) is noted for a maintainer decision, as you scoped it.
TDD: 4 red-to-green tests reproducing the two review findings + 6 new cases; 30/30 in tests/unit/codex-app-server.test.ts; typecheck/eslint/env-doc-sync/file-size clean. Merged --admin over the inherited 2026-08-23 base-red cluster (#9985): the remaining reds (CLI catalog/registry tests, @testing-library allowlist) are proven tip failures unrelated to this diff — shard logs show only CLI-cluster failures, and this PR itself drains the mutation-test-coverage red (stryker registration for #11267's test). Behavior change for app-server deployments is documented in the PR body (sandbox default + binding refusal).
Validated: qdrant-routes integration suite 19/19 on the rebased branch, typecheck:core clean. I retargeted the PR from main to release/v3.8.50 and rebased your single commit onto the release tip (authorship untouched) — no content changes. Embedding models now list from configured/credentialed providers via the embedding registry, with vector dimensions in labels and the unconfigured OpenAI fallback removed. Thank you @rafacpti23!
Validated on the combined 12-PR batch board + the resolved merge against the post-#11232 tip: focused suites 73/73 (learned-reasoning-effort-caps, synced-capabilities-learned-effort-override, synced-effort-suffix-learned-validation, effort-tiers-loop-catalog-e2e, reasoning-effort-clamp-and-retry, reasoning-effort-learned-capability) + opencode-plugin effort-tier-variants 4/4, typecheck:core clean, gates within baseline. The stacked-branch conflict after #11232 squash-landed was resolved by hand (the learned-caps module keeps both the Set API and the new model-scoped lookup). The effort_tiers loop is closed end-to-end: catalog advertises exactly what the upstream accepts, and -<tier> suffix variants resolve against the learned set. Thank you @maxmad64bis!
The structural admission gate (src/shared/middleware/chatBodyAdmission.ts —
the bounded heavyweight lease + healthy-headroom path from #10110/#10437)
returns its 503 chat_admission_busy BEFORE request logging, so a shed left
no trace: no counter, no log line, and the process-wide snapshot was never
consumed by any route. This adds pure observability — admission behavior,
defaults, and thresholds are untouched.
- chatBodyAdmission.ts: in-memory shed history (shedTotal + shedsByReason)
on ChatAdmissionController, recorded at the two capacity-driven give-up
points in acquireHeavyWithin (queue_timeout when the bounded wait
expires, queued_bytes_budget when the heap valve refuses to park). A
client abort mid-wait is deliberately not counted — capacity was never
denied. Each shed also emits exactly one structured pino warn (module
chat-admission) with reason/activeHeavy/waiting/queuedBytes and the HMAC
session fingerprint — never a raw credential. PerConnectionAdmission
Controller.snapshot() now carries the counters plus activeHealthyHeadroom.
- /api/monitoring/health: the structural snapshot is exposed under a new
additive chatAdmission key next to the existing adaptiveAdmission (the
shadow-mode layer) — allowlisted projection in observability.ts, nothing
removed from the current payload.
- Tests: tests/unit/chat-admission-visibility-11244.test.ts (RED→GREEN:
shed counting per reason, abort exclusion, snapshot shape, and the warn
log carrying the fingerprint but never the raw API key) + a chatAdmission
allowlist-projection test in observability-payloads.test.ts.
Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Merged after conflict resolution: the 5 conflicting test files were the base-red drains that #11201 already landed on the tip — kept the tip versions; the feature content is untouched. Validated on the combined batch board + this branch: codex-app-server + codex-gpt56-catalog 25/25, typecheck:core clean, docs-counts green (351 providers), provider-consistency 268/351/0. The opt-in codex-app-server transport (JSON-RPC-over-WS, turn/completed-awaited close, Responses SSE bridge) leaves the default codex path untouched. Thank you @arminanton — a 3.4k-line transport with the docs wave and tests to match!
Merged after conflict resolution (validated on the combined batch board + this branch): stale drift files (package.json/package-lock/.gitignore) kept at tip; the two modals merged additively — AWS SigV4 fields coexist with the chatgpt-web-codex tunnel fields and the #11156 Enter-handler mirror (vitest 2/2 re-run). file-size gate green with the dated AddApiKeyModal 1173 entry (owner-authorized). aws-polly modal + provider-validation-specialty 127/127. Base was mistakenly main; retargeted to release/v3.8.50. Credentials stay in the protected field; nothing logged. Thank you @rafacpti23!
Validated on the combined batch board over tip 0b41259f: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.
max_context_window now wins over the pricing-tier context_window in Codex catalog parsing — context-aware fallback stops demoting codex behind smaller targets. Live evidence (390K served past 272K) plus the live-shape regression test. Thank you @excessivechaos!
Validated on the combined batch board over tip 8a42aeeb: static gates clean (changelog, file-size 159 frozen, complexity 2621<=2774, cognitive 1181<=1223, dead-code 408<=416), typecheck:core clean, 107 focused tests green.
Zero-credential /v1/search now actually reaches the fallback-only providers (duckduckgo-free/searxng) instead of erroring before the last-resort block could run — the dead-code path is live. Also carries a one-line suppressHydrationWarning on the logo. Thank you @Egorich-print!
Validated on the combined batch board + this branch: oauth-400-recovery + quota-connection-recovery 22/22; file-size gate green with the test/route.ts 1215 frozen entry (dated annotation for the +190 rebuilt-probe lines, owner-authorized). Unknown expiry + refresh token now means proactive refresh before probing, a hard 400 gets exactly one refresh+retry with fresh-token assertion, and the recovery tick clears stale error labels — the four dead-for-weeks antigravity connections from the production report would have self-healed. TDD with bug-injection proof on each leg. Thank you @HouMinXi!
Merged after conflict triage: the six base-red repair files (vi.json, opencode.ts JSDoc, context-manager test, the three webhook dispatcher tests, the uncloseai orphan-test rename) were already drained on the tip by today's #11130/#11157/#11160/#11113 — those hunks resolved to the tip shape. What lands is the production-fix set: GLM transport-aware Anthropic headers, Claude Code-compatible model-listing rejection, combo live-test single-probe, zero-cost Auto-Combo interval normalization, recovery-clearing union handling, LLMLingua real-path compare, macOS netstat PID discovery, AI Horde R2 strict public-host validation. Sweep of every touched test file: 243/243 green; typecheck + file-size clean. (guide-settings-route's 4 reds reproduce on the pure tip — pre-existing drift from #11079, not from here.) Thank you @backryun!
Merged after count reconciliation: the branch's regenerated docs claimed 57 free forever / 157 migrations from its older base; gate-verified values on the current tip are 56 free forever (Logfare carries a Free badge via gateways.ts freeNote but has no freeModelCatalog per-model entries, so the live-code counter stays at 56) and 159 migrations — the README/SVGs now match the check:docs-counts output exactly. provider-consistency OK at 267 registry / 349 canonical. logfare-registry 4/4, icon + KNOWN_PNGS + discovery-set membership all verified present. Closes#10644. Thank you @jonlwheat2-gif!
Validated on the combined board over tip 80d931ae: quota-redis-store (incl. the KEY_PREFIX derivation test), local-redis-status and rate-limiter-redis-optional green, typecheck:core clean. One pre-merge fix pushed to the branch: docs/reference/ENVIRONMENT.md gained the REDIS_KEY_PREFIX row (env-doc-sync gate requires every .env.example var documented). Board note: the redis tests leave an ioredis retry handle open and hang the runner exit locally — assertions all pass; pre-existing pattern, not from this PR. Thank you @MeRezaRezaei!
Validated on a combined board over tip aa128736 (incl. sibling #11081): call-logs-row-filter 4/4 green, typecheck:core clean. The merged-row predicate fix closes a real gap — in-memory (in-flight/recently-completed) rows bypassed every filter except correlationId; rowMatchesFilter() now applies search/model/provider/account/apiKey/status/combo uniformly while DB rows stay idempotent. Thank you @AndrianBalanescu!
Validated on a combined board over tip aa128736: focused tests local-rerank-logging + call-logs-row-filter green (7/7 across runs), typecheck:core clean. One pre-merge fix: widened waitForCallLogSaves 5s→15s — the call-log artifact writer's fsync latency exceeds 5s under a loaded host (pre-existing call-log-save-drain flakes identically on the pure tip), so the budget was load-flaky, not the code. Local rerank now logs call entries on success and error paths like embeddings/cloud rerank, captures full request/response payloads, attaches x-omniroute-* headers, and falls back /v1/rerank→/rerank on 404. Thank you @AndrianBalanescu!
Cherry-picked the three value commits onto the current tip, dropping the stale base-red sync commits. Focused tests: search-blocked-providers-11100 + search-registry/searxng-loopback/chat-guard/x-search suites 65/65. Fixes#11100 (endpoint half) — GET /v1/search now honors blockedProviders via getAllSearchProviders. Thank you @rqzbeh!
Validated on the combined batch board over release/v3.8.50 tip d91238b7: static gates clean, typecheck:core clean, focused tests green.
Strict schema + {sanitized, rejected} DB boundary — silent validation degradation now answers 400 with the offending keys. Caller audit done: only the providers write path consumes the sanitizers. Thank you @maxmad64bis!
Inherited base-red at merge time (discriminated against the pure base tip, both reproduce WITHOUT this diff): getTokenLimit test + Vietnamese i18n key parity (new UI strings merged untranslated) + No new ESLint warnings gate. Merge integrity, Docs Gates, Vitest, Fast Production Build: green.
⭐5 — /v1/combos strip connectionId de propósito; dois passos pinando contas DIFERENTES do mesmo provider viram objetos byte-idênticos e um cliente conclui que não há failover. Adiciona accountPinned (boolean derivado do connectionId, nunca vaza o id) em cada passo model; sempre true/false, nunca em combo-ref. Sem rota/schema/mudança de caller. TDD. Fecha #10968.
⭐4 — Suporte de backend nativo Bun + Dockerfile.bun multi-stage + fallback dinâmico de driver SQLite (better-sqlite3 prioritário sob Bun, bun:sqlite fallback; Node preservado) + correção de estabilidade do DAST CI smoke.
Validado a fundo (worktree board sobre tip): bun-support 4/4, typecheck:core limpo, dashboard-typecheck OK (220 dentro do baseline), open-sse-typecheck OK (5 pré-existentes), gate de runtime OK sob Node, changelog-integrity OK, file-size/complexity/cognitive/dead-code OK. Verificado que o driver preserva a cadeia Node/falback conforme AGENTS.md; teste bun-support presente. Baselines de typecheck removidos são ratchet honesto (erros não existem mais).
OBS: destravei 2 base-reds do tip neste turno (push direto 7ffa3ef): movi o changelog fragment da #11050 da seção inválida breaking/ para fixes/, e rebaselinei AddApiKeyModal 1067->1073 (crescimento da #11056). Sem isso a #11039 e o resto da fila ficariam vermelhos.
⭐5 — LIMIT negativo = "sem limite" no SQLite: ?limit=-1 retornava a leaderboard inteira em endpoint management autenticado; ceil por Math.min só no upper. Duas camadas: route rejeita não-inteiro/fora de range com 400 (mesmo contrato de parseListLimit), getTopN clampeia como backstop defense-in-depth + exporta LEADERBOARD_MAX_LIMIT. TDD red→green, 5 casos novos, 84/84 suíte gamification. Fecha #11058.
⭐5 — Provider x-search de primeira classe (SuperGrok/xAI x_search) em POST /v1/search e MCP omniroute_x_search. Fallback de credenciais xai-oauth→xao→xai; distinto de web search e do X Developer MCP.
Reconciliado com o release tip (que já incluía #10981 "skip catalog-default SearXNG" deste mesmo lote): merge trouxe 5 conflitos reais de contagem gerada (llm.txt/README.md/AGENTS.md/PROVIDER_REFERENCE.md/SVGs/46 mirrors i18n, todos verificados como bump puro 347→348, sem perda de conteúdo do HEAD) + 1 conflito real de mergeable=CONFLICTING.
Durante a validação, os 3 testes novos de SearXNG expuseram um bug real de interação com #10981: `isUnconfiguredLoopbackSearchProvider()` checava o baseUrl ESTÁTICO do catálogo em vez do baseUrl efetivo (após override de `provider_options.baseUrl` ou `providerSpecificData.baseUrl` da conexão), então QUALQUER request a searxng-search — mesmo com override customizado — era rejeitado como se fosse o default não-configurado. Corrigido em `open-sse/handlers/search.ts` (resolve o baseUrl efetivo via `resolveSearchBaseUrl()` antes do skip-check, tanto para o provider primário quanto o alternate). Um teste do próprio #10988 que assumia o comportamento pré-#10981 (default localhost:8888 sempre atendido) foi atualizado para refletir o comportamento já mesclado e intencional (503 quando não configurado).
Validação completa: typecheck limpo, 70/70 testes unit (search-route/search-registry/x-search-provider/searxng-loopback-default), 24/24 vitest MCP, 14/14 integration (search-providers-catalog), lint limpo nos arquivos tocados, docs-counts-sync OK (2 drifts soft pré-existentes, não relacionados), gates estáticos (file-size/complexity/cognitive/dead-code/changelog) todos OK.
⭐5 — Default do catálogo searxng-search (localhost:8888) sempre falha em Docker/K8s, queima o próximo provider (Brave free-tier 429). Agora pula o default não-configurado a menos que baseUrl tenha sido sobrescrito; fallback duckduckgo-free continua disponível. 3/3 testes. Fecha #10976.
⭐5 — Remove leitura morta de existingConnections em route.ts, resíduo do mesmo commit 5b5e21a99 que já removeu o guard que a usava (#1566). Zero comportamento alterado, 14/14 testes-irmãos verdes. Sibling de #10974.
⭐5 — Remove ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE, flag morta desde 5b5e21a99 (que removeu o guard que a lia, resolvendo #1566). Zero mudança de comportamento; EXPECTED_FEATURE_FLAG_COUNT é o regression guard. Sibling de #10973 (mesma raiz).
⭐5 — Cursor PKCE login com Bearer quota, auto router e empty-turn errors. Feature completa e testada (11 arquivos de teste, 133 testes focados, todos verdes).
**Validação (worktree combinado `.claude/worktrees/fix-9909`, board sobre `origin/release/v3.8.50`):**
- 3 conflitos reais resolvidos: `config/quality/eslint-suppressions.json` (aditivo), `open-sse/config/providers/registry/cursor/index.ts` (dedup de 208 entradas de catálogo, 0 IDs duplicados verificado), `open-sse/executors/cursor.ts` (imports aditivos).
- `npm run typecheck:core`: limpo.
- `check-changelog-integrity`, `check-file-size`, `check-complexity` (2615/2774), `check-cognitive-complexity` (1175/1223), `check-dead-code` (410/416): todos OK.
- `check-public-creds`: 1 entrada obsoleta pré-existente na allowlist (`copilot-m365-web.ts:330`), já presente no tip da release — não é desta PR.
- `npm run lint`: 0 errors (5 warnings pré-existentes).
- Testes focados (`cursor-agent-cli-version`, `cursor-available-models`, `cursor-catalog-combo-compat`, `cursor-errors-classify`, `cursor-login-pkce`, `cursor-model-effort-suffix-7289`, `cursor-streaming`, `cursor-token-extractor`, `cursor-token-refresh-wiring`, `cursor-usage-fetcher`, `empty-stream-no-content-8649`): 133/133 verdes.
- Corrigido durante a validação: 1 teste novo da própria PR (`cursor-model-effort-suffix-7289.test.ts`, "splits effort off legacy grok- ids") colidia com `CURSOR_MODEL_ALIASES` já mesclado na release (mapeia `grok-4.5-high` → `cursor-grok-4.5-high` antes do fallback legado rodar); ajustado para usar um id não-aliasado (`grok-3-high`) que de fato exercita o fallback — commit `68b58ed`.
Obrigado pela contribuição, @yansigit — feature robusta com boa cobertura de testes.
Validado no worktree combinado: mesmos gates + testes focados verdes. Extensão opt-in bem desenhada sobre #10909 (dimensão de uso real via call_logs). CI vermelho é o base-red já rastreado em #9985.
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint e 52 testes focados (kimi-jwt, kimi-credentials-extract, kimi-token-refresh, kimi-web-401-retry, provider-refresh-token-route, token-health-check-kimi) todos verdes. Implementação sólida e bem testada de ciclo de vida de token para Kimi Web. CI vermelho é o base-red já rastreado em #9985. Obrigado!
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint todos verdes. Fix de UX real e bem documentado (cards de Account Split mostravam UUID cru em vez de email/nome da conta). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint todos verdes. Fix real bem documentado (loopback readiness gate memorizava falha permanentemente + log-spam por caller). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint e testes focados (auth-login-route, login-bootstrap-route, feature-flags-settings — corrigi EXPECTED_FEATURE_FLAG_COUNT 51→52 fix-in-place, novo flag adicionado sem atualizar a própria contagem) todos verdes. CI vermelho é o base-red já rastreado em #9985. Obrigado!
Reconciliado com #10935 (já mergeada) — mesclado o guard inline recém-mergeado com a extração para `privateHostname.ts` deste PR, mantendo a intenção original: os 3 workers de relay agora usam a MESMA função compartilhada. Validado: lint limpo, 49/49 testes focados passando (incluindo verificação de que nenhum worker mantém cópia inline). Hardening de segurança real e bem documentado (4 gaps de bypass: `::`, `localhost.`, `::127.0.0.1`, `feb0::1`). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Reconciliado com a release (mesmo drift dos PRs irmãos) e corrigi 2 problemas de lint reais: import restrito `@/lib/localDb` → `@/lib/db/settings`, e `no-explicit-any` no teste (tipo explícito no callback do map). Validado: lint limpo, 2/2 testes focados passando. Fix real de segurança — endpoints de busca agora respeitam `blockedProviders`. CI vermelho é o base-red já rastreado em #9985. Obrigado!
Reconciliado com a release (mesmo drift de typecheck-baseline/glm.ts/fetchTimeout.ts/stryker.conf.json que os PRs irmãos) e corrigi o `no-explicit-any` no teste novo (o tipo `ModelCompatOverride` já expõe apiFormat/targetFormat/supportsVision — o cast era desnecessário). Validado: lint limpo, 2/2 testes focados passando. Fix real e bem documentado (persistência de overrides de protocolo por modelo). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Adds a Grok Build card to the CLI Code dashboard: configures the main model and per-subagent model overrides, surgically upserts only the [model.omniroute] section of config.toml (preserving unrelated user sections), resolves config.toml via GROK_HOME or the CLI config home, and omits API keys from settings responses. Closes#10829.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 14 files):
- 6/48 focused node:test cases in tests/integration/cli-settings-grok-build.test.ts initially failed with 422 instead of 200/409 — traced to this route being the first CLI-tool settings route to actually pass a targetPath into the shared guardCliConfigWrite/ensureCliConfigWriteAllowed container-ephemeral-write guard (every other cli-tools/*-settings route calls it with no path, which always no-ops). This devbox genuinely runs inside Docker with no bind mount for the test's tmpdir fixtures, so the guard correctly refused — a real environment-dependent gap in the PR's own test setup (missing OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE=1, the pattern already used by tests/unit/cli-tools-apply-container-422.test.ts for this exact guard). Fixed by setting that flag in the test file's setup, pushed fix-in-place.
- 61/61 tests pass after the fix (grok-build-config, check-tool-config-status, all-statuses-route, cli-settings-grok-build, plus 13/13 UI tests via vitest for GrokBuildToolCard/ToolDetailClient).
- Verified the "omit API keys from settings responses" claim: GET applies omitApiKeys() to both config/settings before responding.
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: tuandinh0801 <tuandinh0801@users.noreply.github.com>
Dashboard-installed SkillsMP and skills.sh skills now store under the canonical global skill scope and merge into every API-key-scoped lookup, so marketplace installs actually reach API keys instead of staying invisible outside the installing session. Tenant-owned skill overrides stay isolated; existing skillsmp/skillssh rows are recognized without a migration, with canonical rows preferred on identity overlap. Closes#9716.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 9 files):
- 94/94 skills-*.test.ts tests pass, including the tenant-isolation regression coverage in skills-injection.test.ts (global skills reach a different API key without leaking another tenant's skills).
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: kriptoburak <kriptoburak@users.noreply.github.com>
Adds Zed Hosted Models to OAUTH_TEST_CONFIG so the dashboard connection test no longer reports "Provider test not supported" for that provider.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 1 file):
- tests/unit/oauth-test-config-8408.test.ts (including its "every OAuth provider ID has an OAUTH_TEST_CONFIG entry" check) — 3/3 pass.
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: Hsia97 <Hsia97@users.noreply.github.com>
Adds a snapshot-generation button to each Auto-Combo catalog card: computeSnapshotWeights() scores candidates (taskFit/stability/tierPriority/costInv) at combo-creation time instead of the previous hardcoded weight:1, and the new POST /api/combos/duplicate endpoint materializes any auto/* template into a persistent, editable static combo with normalized weights. Closes#10231.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 51 files):
- 19/19 focused tests pass (snapshot-weights, combos-duplicate-route, combos-duplicate-resolution-audit) — covers auth gate (401/403), input validation (400/422), success shape, weight normalization, naming/dedup, and error-response sanitization (no stack traces).
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: swingtempo <swingtempo@users.noreply.github.com>
Canonical provider id renamed freepik → magnific (Magnific Mystic official API), with a permanent redirect + runtime alias so old freepik/<model> traffic and /dashboard/providers/freepik URLs keep working. Existing provider=freepik connection rows are rewritten to magnific by migration 160.
Closes#10604.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 138 files):
- Focused suite: 54/54 tests pass (magnific-image-handler, provider-validation-image-only, provider-alias-uniqueness, redirects-cli-renames).
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: RaviTharuma <RaviTharuma@users.noreply.github.com>
v1SearchSchema.provider was a hard-coded z.enum that rejected any id outside
its list before the route's own resolveSearchProvider() check ever ran,
so unknown/short-alias provider ids (grok, brave, serper, ...) always
surfaced a generic "Invalid request" instead of the informative
"Unknown search provider: <id>" message. Relax the schema to a free-form
string and let resolveSearchProvider() own runtime validation (as it
already did for ids that passed the enum). Also extend
SEARCH_PROVIDER_ALIASES with short-form aliases mirroring the existing
jina/jina-ai pattern (brave, serper, perplexity, exa, tavily, google-pse,
linkup, ollama, searchapi, youcom, searxng, zai, duckduckgo), and surface
the first Zod validation issue's field name instead of the generic
message for other still-invalid fields (e.g. search_type).