Commit Graph

645 Commits

Author SHA1 Message Date
Xiangzhe
4a5e123bad fix(auth): honor REQUIRE_API_KEY feature flag (#3188)
Integrated into release/v3.8.11
2026-06-05 00:53:27 -03:00
Diego Rodrigues de Sa e Souza
68d5a0ab27 Release v3.8.10 (#3140)
* chore(release): open v3.8.10 development cycle

Bump 3.8.9 → 3.8.10 across package.json, lockfile, electron, open-sse, and
docs/reference/openapi.yaml; add the [3.8.10] CHANGELOG section (root + 41 i18n
mirrors) as the integration target for the cycle. Entries land here as work
merges into release/v3.8.10; finalized by the release flow.

* fix(providers): resolve web provider alias collisions

Assign unique aliases to HuggingChat, Kimi Web, and Qwen Web so they no longer shadow primary providers or trigger startup warnings.

Add a unit test to enforce provider alias uniqueness and prevent future collisions. Also expand local ignore and VS Code exclude rules for agent, build, and worktree artifacts.

* fix(responses): normalize image_url parts across input paths (#3150)

Normalize image_url parts across all Responses input paths. Integrated into release/v3.8.10.

* fix(api-manager): preserve API key expiration local time (#3146)

Preserve API key expiration local time + clear button. Integrated into release/v3.8.10.

* Strip previous_response_id for stateless Responses upstreams (#3143)

Strip previous_response_id for stateless Responses upstreams (auto/strip/preserve). Integrated into release/v3.8.10.

* fix(opencode-plugin): map thinking cap to interleaved in model+combo (#3138)

Map caps.thinking to ModelV2.capabilities.interleaved for opencode-plugin. Integrated into release/v3.8.10.

* fix(providers): use synced models as fallback for all providers (#3148)

Use synced models as authoritative local catalog for all providers (+regression test). Integrated into release/v3.8.10.

* fix(qoder): bifurcate validation by token type — PAT→Cosy, regular API key→dashscope (#3149)

Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.

* fix(antigravity): dynamic model resolution via MITM alias table (#3144)

Dynamic antigravity MITM model resolution in the executor (+bug fix +regression test; DB import dropped from client-reachable config). Integrated into release/v3.8.10.

* Feature/batch allow big (#3128)

Podman deployment options + larger upload body-size limits (+CONTAINER_HOST docs). Integrated into release/v3.8.10.

* fix(fireworks): preserve fully-qualified router/model IDs (#3133) (#3160)

Fireworks router IDs (accounts/fireworks/routers/...) were double-prefixed
with accounts/fireworks/models/ → upstream 404. Add optional
acceptedModelIdPrefixes to the registry entry and skip the prepend when the
model already starts with an accepted prefix.

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

* fix(llama-cpp): route to configured local baseUrl instead of OpenAI (#3136) (#3161)

llama-cpp was missing from the local-provider group in buildUrl(), so it
fell through to the OpenAI baseUrl and returned an OpenAI 401. Add the
case to resolve the connection's providerSpecificData.baseUrl.

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

* fix(t3-chat-web): parse cookies + convexSessionId from stored credential (#3007) (#3162)

The executor read credentials.cookies/convexSessionId, but the pipeline
only stores the pasted string under apiKey → t3.chat always 400'd. Parse
both values from apiKey (fallback accessToken), mirroring validation.ts.

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

* fix(minimax): stop capping MiniMax-M3 / M2.7 max_tokens at 8192 (#3141) (#3163)

MiniMax-M3 had no MODEL_SPECS entry and capitalized MiniMax-M2.7 missed
its lowercase spec (case-sensitive lookup) → both fell to the 8192 default
cap. Add the M3 spec (512K output), alias the capitalized ids, and make
getModelSpec lookups case-insensitive.

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

* fix(github-copilot): discover model catalog live from api.githubcopilot.com (#3120, #3121) (#3164)

The github (Copilot) provider had a static hardcoded catalog with no
discovery source, so Import Models never refreshed (#3120) and advertised
non-entitled models that 400 on use (#3121). Add a live /models fetch with
fallback to the static list.

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

* fix(combo): invalidate nested-combo cache on edits + log DATA_DIR (#3147) (#3165)

Editing a combo did not invalidate the 10s nested-combo expansion caches
(chat.ts getCombosCachedForChat + chatCore.ts getCombosCached; the exported
clearCombosCache was dead code), so a removed nested target/model could be
served as a phantom for up to 10s. Wire a shared monotonic combos-cache
version in readCache (bumped by invalidateDbCache("combos") on every combo
write); both cache layers treat a version mismatch as a miss.

Also log the resolved DATA_DIR/SQLITE_FILE absolute path at DB init so the
reporter's 'persists across restart + volume wipe' symptom (a multi-replica
Docker volume/DATA_DIR mismatch, not a routing bug) is diagnosable from logs.

Includes consolidated CHANGELOG entries for #3133/#3136/#3007/#3141/#3120/#3121.

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

* fix(web-tools): parse bare JSON tool calls (#3157)

Parse bare JSON tool calls for deepseek-web (#2820) + fuzzy tool-name matching. Integrated into release/v3.8.10.

* fix(misc): minor fixes across reasoning cache, account fallback, binary manager (#3177)

Misc: ProviderProfile export, DeepSeek reasoning regex, binary guard. Integrated into release/v3.8.10.

* fix(kiro): minor OAuth social exchange tweaks (#3176)

Kiro social OAuth: optional targetProvider passthrough. Integrated into release/v3.8.10.

* deps: bump hono from 4.12.18 to 4.12.23 (#3179)

Bump hono to 4.12.23. Integrated into release/v3.8.10.

* fix(providerRegistry): update kilocode format and executor (#3166)

kilocode: openai format + default executor (matches kilo-gateway) + registry test. Integrated into release/v3.8.10.

* feat(metrics): cross-request TTFT and gap latency after tool calls (#3173)

Cross-request TTFT + gap-after-tool latency metrics (+test). Integrated into release/v3.8.10.

* feat(dashboard): provider stats API endpoint and dashboard page (#3175)

Provider stats dashboard + API (SQL moved to db module per Hard Rule #5, +test). Integrated into release/v3.8.10.

* fix(usage): sequential+spaced OAuth quota sync, reactive force-refresh, actionable 401 (#3156)

Sequential+spaced OAuth quota sync, reactive force-refresh on 401, actionable 401 in UI. Integrated into release/v3.8.10.

* fix(healthcheck): per-provider proactive-refresh skip list (rescue short-TTL OAuth) (#3159)

Per-provider proactive-refresh skip list (OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS) to rescue short-TTL OAuth. Integrated into release/v3.8.10.

* feat(quota): show OAuth token expiry on provider cards (small, blue, informative) (#3178)

Show OAuth token expiry on provider cards (small, blue, informative). Integrated into release/v3.8.10.

* fix(providers): empty refresh must not resurface just-cleared synced models (#3181)

Empty refresh must not resurface just-cleared synced models (fixes the release-blocking provider-models-route test). Integrated into release/v3.8.10.

* chore(release): v3.8.10 — 2026-06-04 (finalize CHANGELOG)

---------

Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Xiangzhe <32761048+xz-dev@users.noreply.github.com>
Co-authored-by: Jan Leon <Jan.gaschler@gmail.com>
Co-authored-by: M.M <mr.maatoug@gmail.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>
Co-authored-by: totaltube <totaltube@users.noreply.github.com>
Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>
Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>
Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nicolas Lorin <androw95220@gmail.com>
2026-06-04 20:05:38 -03:00
diegosouzapw
b6bda19919 fix(quality): explicit promise-existence checks + protocol-aware WebDAV URL
SonarCloud new-code findings:
- combo.ts / sync-models route: `if (cachedPromise)` -> `!= null` (intentional
  in-flight-promise reuse; explicit existence check, no behaviour change).
- ObsidianSourceCard WebDAV URL: inherit window.location.protocol instead of
  hard-coding http:// (https when behind a TLS proxy) — clears the http hotspot.
2026-06-03 23:53:03 -03:00
diegosouzapw
8dd9749a93 fix(build): correct modelResolution import path in responses route (#3113)
The webpack build failed: route.ts imported '../internal/codex-responses-ws/
modelResolution' (resolves to api/v1/internal/, which doesn't exist). The module
lives at api/internal/codex-responses-ws/. Switched to the @/app/api/... alias.
typecheck/tests passed (tsx resolves leniently; tests import the module directly),
only the production build caught it.
2026-06-03 19:47:42 -03:00
Oğuzhan Sert
8dc93ade6d fix(i18n): Turkish locale-aware search and sorting (#3115)
* feat(i18n): add Turkish locale-aware text helpers (search/sort)

* test(i18n): cover null/whitespace edges + document compareTr/normalize contract

* fix(i18n): route dashboard search through Turkish-safe matchesSearch

* fix(i18n): sort user-visible lists with Turkish collation (compareTr)

* fix(i18n): keep providerId tiebreaker as ASCII sort (technical id)

* docs(i18n): document intentional lang=en in global-error boundary

* chore(lint): guard against locale-unsafe toLowerCase().includes search

* fix(i18n): migrate missed provider-name search + harden lint disable placement

* fix(i18n): downgrade no-restricted-syntax to warn (incremental adoption)

The rule errored on ~19 pre-existing toLowerCase().includes() call-sites in
src/app accumulated since this PR's base. Keep it as a warning so the guard-rail
guides future code without breaking the 0-errors lint gate (project policy:
0 errors, warnings tolerated).

---------

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
2026-06-03 18:58:01 -03:00
Diego Rodrigues de Sa e Souza
ed170229e7 fix(responses): resolve bare ChatGPT model ids to codex on HTTP fallback path (#3113)
When the Codex CLI falls back from WebSocket to HTTP (after 1008 Policy
Violation or reconnect exhaustion), it POSTs to /v1/responses with the
bare model id it was configured with (e.g. "gpt-5.5") — never the
provider-prefixed form. OmniRoute's normal routing resolved that bare id
to openrouter, not codex, producing:

  "No credentials for provider: openrouter"

Fix: add resolveResponsesApiModel() (extending modelResolution.ts) and
call it in /v1/responses before delegating to handleChat. The function
applies the same codex-preference logic as resolveCodexWsModelInfo:

  bare "gpt-5.5" → codex/gpt-5.5 has a codex provider → rewrite 
  bare "gpt-4o"  → codex/gpt-4o not in registry      → pass through 
  "anthropic/x"  → has "/" → skip resolution           → pass through 

Errors are caught; original request is returned on any failure.
8 unit tests added (TDD — watched each fail before implementing).

Refs: openai/codex#15492, openai/codex#13041, openai/codex#13039
2026-06-03 18:12:34 -03:00
Diego Rodrigues de Sa e Souza
8a25d9e229 fix(dashboard): make 'Import from /models' work for no-auth providers (#3047) (#3099)
No-auth providers (OpenCode Free) have no connection row, so handleImportModels returned early and /api/providers/[id]/models 404'd — the import button silently no-op'd. The route now serves the provider's registry/static model catalog when called with a no-auth provider id, and handleImportModels falls back to the provider id when there is no connection. Test: route returns the opencode catalog (source local_catalog) and still 404s for unknown ids.
2026-06-03 07:48:19 -03:00
Xiangzhe
948f232517 fix: sync SiliconFlow models from configured endpoint (#3094)
Integrated into release/v3.8.9. SiliconFlow tests pass.
2026-06-03 07:19:38 -03:00
Brandon Bennett
9db306e2f8 feat(observability): add Obsidian context source with 24 MCP tools (#3077)
Integrated into release/v3.8.9. Fixes applied: removed .serena/ from repo (gitignored), resolved import conflicts preserving agentSkillTools, fixed TS errors.
2026-06-03 06:45:04 -03:00
diegosouzapw
5943e5d528 feat: add Codex WS flag and Xiaomi MiMo usage tracking
Add a global OMNIROUTE_CODEX_WS_ENABLED kill-switch for Codex WebSocket transport, defaulting to enabled if feature flag lookup fails.

Track Xiaomi MiMo monthly token usage from OmniRoute usage history and expose it through the usage fetcher provider list.
2026-06-03 00:41:11 -03:00
diegosouzapw
0f900f1d56 fix(usage): handle MiniMax coding plan percent quotas
Support MiniMax Coding Plan quota responses that expose remaining usage as
percentages instead of request counts, including the text quota surfaced under
the `general` model.

Also document Codex CLI WebSocket configuration, clarifying that bare ChatGPT
model ids must be used instead of `codex/`-prefixed ids.
2026-06-03 00:41:10 -03:00
diegosouzapw
e438139b03 feat(quota): live real-time codex quota on the page (cascade-safe serialized refresh)
Symptom: freshly-added Codex accounts (e.g. davi/gabriel) showed "No quota data"
even when healthy. Root cause: the quota path reuses the access_token without
refreshing rotating providers (#3019, anti Auth0 family-revocation cascade), so a
Codex account whose short-lived access_token has expired can never surface quota
from the sync — the live fetch returns "Codex token expired".

Fix (opt-in, cascade-safe):
- refreshAndUpdateCredentials gains `allowRotatingRefresh` + a pure exported gate
  `shouldAttemptRotatingRefresh`. The actual token mint is wrapped in
  `serializeRefresh` (one refresh at a time per Auth0 rotation group) — so even N
  concurrent per-account requests can never refresh siblings in parallel.
- The BULK scheduler (syncAllProviderLimits, concurrent) keeps the flag OFF →
  #3019 fully preserved (guardian test codex-quota-sync-no-proactive-refresh stays
  green). Only the on-demand, per-connection path (`GET /api/usage/[connectionId]`)
  opts in.
- Frontend: the quota page auto-fetches LIVE on open for the VISIBLE connections
  that have no cached quota (scoped to what's on screen — not all connections —
  and skips entries already cached), so expired-token Codex accounts surface real
  quota automatically and cascade-safely.

Adds unit coverage for the gate (bulk skips rotating, on-demand allows; non-rotating
always eligible). typecheck / lint clean.
2026-06-02 09:53:50 -03:00
diegosouzapw
66ddbb0f5a chore: remove Petals executor and tighten route typing
Remove the Petals executor from registration and exports.

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

Add request validation for the agent bridge cert route and expand tests to
ensure switch buttons explicitly declare type="button", preventing implicit
form submissions.
2026-06-02 02:10:34 -03:00
terence71-glitch
08c70572fb fix(proxy): resolve registry assignments for combo and key levels (#3048)
* fix(proxy): resolve registry assignments for combo and key levels

* fix(proxy): guard registry scope level lookup
2026-06-01 19:47:46 -03:00
Diego Rodrigues de Sa e Souza
20c31493af feat(plugins): plugins framework + per-API-key disable-non-public-models (#3041)
Integrates two community contributions into release/v3.8.8 with security hardening and conflict resolution.

- **Plugins framework** (#2913 — thanks @oyi77): hooks + registry unification, plugin SDK (`definePlugin`), worker-thread sandbox, per-plugin hook rate limiting, SHA-256 integrity verification, semver-gated upgrade, and execution analytics. Plugin routes are loopback-only (`isLocalOnlyPath`); `child_process` exec is opt-in via `OMNIROUTE_PLUGINS_ALLOW_EXEC` (default off).
- **API key option: disable non-published models** (#3017 — thanks @androw): a per-key flag restricting the key to discovered public models (combos / `auto/*` / `qtSd/*` routing still allowed).

Hardening applied during integration: migration renumber (089/090/091), `/api/plugins` LOCAL_ONLY route-guard classification (closes the plugin-RCE vector), atomic install/upgrade with path containment, `O_EXCL` tmp-file creation (TOCTOU), rate-limit-map eviction, `validatePluginConfig` on configure, `buildErrorBody` on all plugin error paths. 246/246 tests; typecheck / cycles / docs-sync clean.

Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Nicolas Lorin <androw95220@gmail.com>
2026-06-01 15:43:55 -03:00
Hernan Javier Ardila Sanchez
482e4690eb fix(dashboard): use lightweight ping endpoint for MaintenanceBanner (fixes #3040) (#3043)
Integrated into release/v3.8.8. Applied review fixes: moved the SELECT 1 into a pingDb() db helper (no raw SQL in route, Hard Rule #5) + the 503 catch no longer leaks err.message (Hard Rule #12). Thanks @herjarsa!
2026-06-01 14:31:42 -03:00
Chewji
6b7ae9ad2e fix(mcp): resolve streamable http transport readiness offline status (#3037)
Integrated into release/v3.8.8. Fixes MCP streamable-HTTP transport readiness reporting when offline + session sweep. Thanks @Chewji9875!
2026-06-01 09:59:23 -03:00
Diego Rodrigues de Sa e Souza
099cb67317 Merge pull request #3032 from diegosouzapw/feat/quota-share-v2
feat(quota): Quota Share v2 — nav move, 3-col grouped layout, endpoints+key preview, full pool edit
2026-06-01 07:03:14 -03:00
diegosouzapw
ac5ac0c2a7 fix(api): guard rotating providers in manual token-refresh route (Codex family-revocation)
POST /api/providers/[id]/refresh was the last unguarded proactive-refresh
entry point for rotating-refresh providers. The dashboard auto-refreshes every
expiring connection on a page load (and an old cached frontend bulk-calls this
endpoint), so each Codex account's single-use refresh_token got rotated; Auth0
then revoked the whole token family (openai/codex#9648) — every account but the
last died with [403] <!DOCTYPE. refreshAndUpdateCredentials (quota-sync) and the
connection-test route were already guarded; this closes the gap.

The route now skips proactive rotation when rotationGroupFor(provider) !== null
and returns {success,skipped,message}, deferring genuine expiry to the reactive,
serialized 401 path. Non-rotating providers keep refreshing on demand.

Test: codex-manual-refresh-rotating-guard (source-assertion, matches the
token-refresh-race-comprehensive #2941 style).
2026-06-01 03:00:13 -03:00
diegosouzapw
342f12b77a feat(quota): GET /api/quota/keys/[id]/models — preview the qtSd/ models a key sees 2026-06-01 02:39:37 -03:00
diegosouzapw
e5392a7eaa fix(quota): pool PATCH prunes OLD group/provider combos before re-sync (no orphan qtSd/ on switch) 2026-06-01 02:35:26 -03:00
diegosouzapw
e694674851 feat(quota): pool PATCH accepts groupId + connectionIds, re-syncs combos on connection change 2026-06-01 02:28:21 -03:00
diegosouzapw
58a7d97b3f Merge branch 'release/v3.8.8' into feat/quota-share-redesign
# Conflicts:
#	src/lib/db/apiKeys.ts
#	src/lib/db/migrationRunner.ts
#	src/server/authz/policies/management.ts
#	src/server/authz/routeGuard.ts
#	tests/unit/route-guard-private-lan.test.ts
2026-05-31 21:08:30 -03:00
diegosouzapw
efa8f0af23 feat(quota): /api/quota/groups CRUD (rename re-syncs combos)
Add GET/POST /api/quota/groups and PATCH/DELETE /api/quota/groups/[id].
PATCH rename calls renameGroup then re-syncs quotaShared-* combos (via
dynamic-import syncQuotaCombos) for every pool in the group, since combo
names embed the group slug. DELETE maps the deleteGroup throw (protected
group-demo or pools still referencing the group) to 409 Conflict via
buildErrorBody — never 500. All handlers are management-gated via
requireManagementAuth and route all errors through buildErrorBody (Hard
Rule #12). 37-assertion source-scan test verifies auth, error sanitisation,
response shapes, Zod validation, PATCH re-sync wiring, and DELETE 409 logic.
2026-05-31 19:31:30 -03:00
Diego Rodrigues de Sa e Souza
fa038e069d Merge pull request #2964 from S0yora/feat/trae-solo-provider
feat(oauth): add Trae SOLO provider
2026-05-31 18:06:17 -03:00
diegosouzapw
10fa5e8903 feat(quota): protect quotaShared-* combos from manual edit/delete (system-managed)
Guard PUT and DELETE on /api/combos/[id] to return 409 when the target combo name
starts with QUOTA_MODEL_PREFIX; filter isHidden combos from the Combos page state
so quota-managed combos never appear as editable rows there.
2026-05-31 15:23:41 -03:00
diegosouzapw
8c11acaa33 feat(quota): per-pool usage-log endpoint + card 2026-05-31 11:31:20 -03:00
diegosouzapw
d4045e74b5 fix(models): honor per-model targetFormat for custom models (#2905)
Custom models (added via the UI) on opencode-go / openai-compatible nodes always
routed as OpenAI-compatible because there was no per-model targetFormat: addCustomModel
didn't accept it, the API schema stripped it, and getModelTargetFormat (static-registry
only) never saw it — so a custom model needing the Anthropic Messages shape fell back to
the provider default 'openai'.

Thread an optional targetFormat through addCustomModel / replaceCustomModels /
updateCustomModel + the providerModelMutationSchema + the POST/PUT route, surface it from
getModelInfo (one combined custom-model metadata lookup alongside apiFormat), and use it
in chatCore's targetFormat resolution before the provider default.

Closes #2905
2026-05-31 11:17:52 -03:00
Mcdowell Terence
0e35292e0e perf(proxy): parallelize provider proxy overlay lookups 2026-05-31 12:46:20 +02:00
terence71-glitch
e2ad12d090 fix(proxy): show registry provider proxies in dashboard (#2963)
Integrated into release/v3.8.8
2026-05-30 22:14:53 -03:00
diegosouzapw
4536aabe23 Merge PR 2959 into release/v3.8.8 2026-05-30 22:02:49 -03:00
diegosouzapw
6a14c31280 feat(quota): reconcile key allowedQuotas when pool allocations saved as exclusive (Phase C3) 2026-05-30 21:56:05 -03:00
diegosouzapw
3742afcd64 feat(quota): /v1/models lists only quotaShared-* models for quota-exclusive keys (Phase B3) 2026-05-30 21:41:13 -03:00
diegosouzapw
ba340f18a5 Merge branch 'fix/nextcloud-json-stream-default' into release/v3.8.8 2026-05-30 21:19:50 -03:00
diegosouzapw
e7870132db Merge release/v3.8.8 2026-05-30 21:19:17 -03:00
Diego Rodrigues de Sa e Souza
697946381d fix(auth): prevent Codex multi-account refresh_token family revocation (#2941)
Integrated into release/v3.8.8
2026-05-30 21:18:33 -03:00
Brandon Bennett
8cd77b0f49 feat(notion): add Notion MCP context source with 6 tools, dashboard tab, and 20 tests 2026-05-30 19:11:58 -04:00
Jan Leon
99d673fe5b feat(stream): add per-key JSON stream default mode 2026-05-30 18:33:47 +02:00
diegosouzapw
ac0e9d5272 Merge release/v3.8.8 into refactor/pages-v3-C (Playground + Search Tools Studio — plans 17+18)
Conflicts: migration 076_playground_presets->084; localDb/.env union; REPOSITORY_MAP dedup; package.json keep base (version 3.8.7, coverage --functions 40); .source regenerated (+3 docs); deps cli-table3/wtfnode/@types/bun/uuid (npm install).

i18n pt-BR: 19 collisions — 18 playground keys -> HEAD pt-BR translations (base had untranslated EN: Send->Enviar, Cancel->Cancelar etc), costsSection -> base Custos. Rule: prefer side != en.json (translated).

openapi: --theirs base + 3 playground/search paths + 2 schemas + 1 tag (js-yaml surgical insert; union-blind breaks YAML). No open-sse, typecheck:core 0 errors.
2026-05-30 04:19:49 -03:00
diegosouzapw
dd8f7aa6a1 Merge release/v3.8.8 into refactor/pages-v3-21 (Memory engine redesign — sqlite-vec + RRF + Studio)
Conflicts: migration 073_memory_vec->083; localDb/.env/REPOSITORY_MAP union; request.ts->base; i18n auto-merged; .source regenerated (+3 docs).

openapi: --theirs base + surgically inserted 14 memory paths + 4 schemas + Memory tag via js-yaml extract (union-blind broke YAML structure). +938 lines, base formatting preserved, gen-openapi validates.

deps: @huggingface/transformers + sqlite-vec added (package.json); npm install ran, lock regenerated. chatCore auto-merged (memory + quota hooks coexist, transform OK). typecheck:core 0 errors.
2026-05-30 04:04:20 -03:00
diegosouzapw
db27ae5006 Merge release/v3.8.8 into refactor/pages-v3-15 (Skills pages redesign)
Conflicts: CLAUDE.md base; openapi union + i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +5 docs); openapi.generated regenerated.

open-sse/mcp-server/server.ts: union — registers BOTH agentSkillTools (#2827) AND pluginTools (base plugin system) via two separate forEach loops; tool count sums both; skills handler keeps @ts-expect-error, plugins keeps @ts-ignore. server.ts type-safe (0 TS errors).
2026-05-30 03:29:19 -03:00
diegosouzapw
968addf54f Merge release/v3.8.8 into refactor/pages-v3-14 (CLI pages redesign)
Conflicts: CLAUDE.md base; i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +1 doc); openapi regenerated.

CLIToolsPageClient.tsx: accepted #2839 deletion (redesign replaced cli-tools/ with cli-code/cli-agents/acp-agents; base #2858 only removed obsolete MITM cards; AgentBridge reachable via sidebar; 0 orphan refs). sidebar-visibility test passes (cli items + agent-bridge merged).
2026-05-30 03:10:34 -03:00
diegosouzapw
ef6e6c74a5 Merge release/v3.8.8 into refactor/pages-v3-A (AgentBridge+Inspector) + fix test gaps
Conflicts: migrations 073/074/075->080/081/082; localDb/.env.example/openapi union; i18n deep-merge; request.ts+i18n-fallback->base (deepMergeFallback, drop old getNestedValue); REPOSITORY_MAP dedup; .source regenerated via fumadocs-mdx (+AGENTBRIDGE/TRAFFIC_INSPECTOR docs).

Pre-existing #2858 gaps fixed: sidebar-visibility.test.ts expected list missing agent-bridge/traffic-inspector (code already had them); documented 10 INSPECTOR/AGENTBRIDGE env vars in ENVIRONMENT.md; NODE_TLS_REJECT_UNAUTHORIZED added to env-doc-sync IGNORE_FROM_CODE (instruction snippet, not OmniRoute config).
2026-05-30 02:45:27 -03:00
diegosouzapw
1b0d3c75e9 Merge release/v3.8.8 into refactor/pages-v3-B (Monitoring+Costs+Quota) + fix transform bug
Conflicts: migrations 073/074/075->077/078/079 (collision w/ base 073-076); localDb union (quota + tokenLimits/plugins re-exports); i18n en/pt-BR deep-merge (base translations win over __MISSING__ placeholders; sidebar.costsSection=Custos); CLAUDE.md keeps base coverage rule (>=40%).

Pre-existing #2859 bugs surfaced by validation & fixed: chatCore onStreamComplete 'await import'->'import().then()' (await was outside async fn, broke tsx transform of 17 chat-* test files); documented 5 QUOTA_* env vars in ENVIRONMENT.md to fix env-doc-sync drift.
2026-05-30 02:02:38 -03:00
Diego Rodrigues de Sa e Souza
191009dd23 Release v3.8.7 (#2919)
* feat(plugins): WordPress-style plugin system backend

* fix(plugins): address code review feedback

- Path traversal guard: validate entryPoint stays within plugin dir
- install() now handles direct plugin directories (not just parent dirs)
- Non-null assertion replaced with explicit null check
- require efficiency: allowedModules map moved outside function
- Source wrapper: add newlines to prevent trailing comment issues
- Config validation: validate values against configSchema on save
- Dynamic import comment: clarify Node.js caching behavior

Co-Authored-By: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>

* fix(plugins): replace vm with child_process, add auth to all routes

Addresses all remaining code review feedback:

1. **Loader rewrite**: Replaced Node.js vm module with child_process.fork()
   for proper process-level isolation. Complies with Rule 3 (no eval).
   Each plugin runs in a separate Node.js process with IPC communication.

2. **Auth on all routes**: Added requireManagementAuth to all 6 plugin
   API route files (list, install, scan, details, activate, deactivate, config).

3. **Env filtering**: Only safe env vars passed to plugin processes unless
   "env" permission is granted.

Co-Authored-By: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>

* fix(plugins): security + ESM fixes for loader and manager

loader.ts:
- Fix IPC: use process.send()/process.on("message") instead of worker_threads.parentPort
- Fix ESM: write host script as .mjs (not .js) to force ESM execution
- Add timeout: 10s default on callHook() with Promise.race
- Add SIGKILL escalation: SIGTERM first, then SIGKILL after 3s grace
- Fix env filtering: use allowlist (safeKeys) instead of passing all env vars
- Clear timeout on successful IPC response (no timer leak)

manager.ts:
- Fix path traversal: use fs.realpath() instead of startsWith()
- Fix imports: use registerHook/unregisterHooks from hooks.ts
- Register hooks individually via registerHook(event, name, handler)

hooks.ts:
- Copied from feat/plugin-custom-hooks (canonical registry)

* feat(discovery): add discovery tool stub service

Phase 1 scaffold for automated provider discovery:
- DiscoveryConfig, DiscoveryResult types
- probeEndpoint() for URL availability checking
- scanProvider() stub (Phase 2 will implement real scanning)
- getDiscoveryResults() stub
- Default config: disabled (opt-in)

* chore(plugins): slop cleanup — pino logger, remove redundant sorts

- index.ts: replace console.log/error with pino structured logging
- hooks.ts: remove redundant .sort() in emitHookBlocking/runOnResponse (already sorted on registration)
- manager.ts: add readFile import

* test(plugins): add scanner, loader, manager unit tests

- scanner: 9 tests (discovery, hidden dirs, validation, entry point, multiple)
- loader: 5 tests (type contracts, Plugin/PluginContext/PluginResult interfaces)
- manager: 6 tests (singleton, lifecycle methods, error on unknown)
- Total: 20 tests, all passing

* fix(settings): add missing home page pin keys to updateSettingsSchema

* feat(plugins): add i18n keys to all 42 locales

* fix(settings): add missing security keys to updateSettingsSchema and add tests

* fix(usage): analytics route reads combo_name/requested_model from call_logs only

The 3.8.6 variant of #2904 added SELECTs of combo_name/requested_model
against usage_history, but those columns only exist in call_logs (no
migration adds them to usage_history). This returned HTTP 500 on
/api/usage/analytics. Restore the working query shape from the 3.8.7
variant. Fixes 18 failing usage-analytics-route tests.

* fix(types,test): resolve noImplicitAny in progressiveAging + align semaphore test to #2903 gate pruning

- progressiveAging: type compression results so messages[0].content is
  indexable (was TS7053 against {}); restores typecheck:noimplicit:core gate.
- services-branch-hardening: #2903 (perf-ram) prunes idle rate-limit gates
  on zero; assert no-running/empty-queue without assuming the entry persists.

* fix(analytics): address merged review regressions

* fix(executor): normalize max effort for openai shape providers

* Make zero-latency combo optimizations opt-in

* Address zero-latency combo review feedback

* chore(release): sync v3.8.7 touchpoints + credit contributors

- llm.txt → 3.8.7 (Current version + Key Features header)
- CHANGELOG: add Dmitry Kuznetsov & Nikolay Alafuzov to 3.8.6 Hall of Contributors
- version already 3.8.7 across package.json/open-sse/electron/openapi (from #2909)

* fix(cleanup): restore usage history cutoff boundary

* docs(changelog): rank 3.8.6 contributors in a commits table with their PRs

* fix(dashboard): theme ReactFlow Controls +/- buttons for dark mode

* fix(settings): add missing home page pin keys to updateSettingsSchema

* fix(settings): add missing security keys to updateSettingsSchema and add tests

* fix(executor): normalize max effort for openai shape providers

* Make zero-latency combo optimizations opt-in

* Address zero-latency combo review feedback

* fix(analytics): address merged review regressions

* fix(cleanup): restore usage history cutoff boundary

* feat(plugins): WordPress-style plugin system backend

* fix(plugins): address code review feedback

- Path traversal guard: validate entryPoint stays within plugin dir
- install() now handles direct plugin directories (not just parent dirs)
- Non-null assertion replaced with explicit null check
- require efficiency: allowedModules map moved outside function
- Source wrapper: add newlines to prevent trailing comment issues
- Config validation: validate values against configSchema on save
- Dynamic import comment: clarify Node.js caching behavior

Co-Authored-By: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>

* fix(plugins): replace vm with child_process, add auth to all routes

Addresses all remaining code review feedback:

1. **Loader rewrite**: Replaced Node.js vm module with child_process.fork()
   for proper process-level isolation. Complies with Rule 3 (no eval).
   Each plugin runs in a separate Node.js process with IPC communication.

2. **Auth on all routes**: Added requireManagementAuth to all 6 plugin
   API route files (list, install, scan, details, activate, deactivate, config).

3. **Env filtering**: Only safe env vars passed to plugin processes unless
   "env" permission is granted.

Co-Authored-By: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>

* fix(plugins): security + ESM fixes for loader and manager

loader.ts:
- Fix IPC: use process.send()/process.on("message") instead of worker_threads.parentPort
- Fix ESM: write host script as .mjs (not .js) to force ESM execution
- Add timeout: 10s default on callHook() with Promise.race
- Add SIGKILL escalation: SIGTERM first, then SIGKILL after 3s grace
- Fix env filtering: use allowlist (safeKeys) instead of passing all env vars
- Clear timeout on successful IPC response (no timer leak)

manager.ts:
- Fix path traversal: use fs.realpath() instead of startsWith()
- Fix imports: use registerHook/unregisterHooks from hooks.ts
- Register hooks individually via registerHook(event, name, handler)

hooks.ts:
- Copied from feat/plugin-custom-hooks (canonical registry)

* feat(discovery): add discovery tool stub service

Phase 1 scaffold for automated provider discovery:
- DiscoveryConfig, DiscoveryResult types
- probeEndpoint() for URL availability checking
- scanProvider() stub (Phase 2 will implement real scanning)
- getDiscoveryResults() stub
- Default config: disabled (opt-in)

* chore(plugins): slop cleanup — pino logger, remove redundant sorts

- index.ts: replace console.log/error with pino structured logging
- hooks.ts: remove redundant .sort() in emitHookBlocking/runOnResponse (already sorted on registration)
- manager.ts: add readFile import

* test(plugins): add scanner, loader, manager unit tests

- scanner: 9 tests (discovery, hidden dirs, validation, entry point, multiple)
- loader: 5 tests (type contracts, Plugin/PluginContext/PluginResult interfaces)
- manager: 6 tests (singleton, lifecycle methods, error on unknown)
- Total: 20 tests, all passing

* feat(plugins): add i18n keys to all 42 locales

* chore(plugins): remove duplicate migration 059_create_plugins.sql

* chore(plugins): remove duplicate migration 059_create_plugins.sql (post-merge)

* fix(sse): guard non-string error.code in proxyFetch + harden model parsing (#2463) (#2923)

Integrated into release/v3.8.7

* fix(docker): add runner-web stage with Playwright Chromium (#2832) (#2846)

Integrated into release/v3.8.7

* docs(changelog): document NVIDIA NIM and error code type-crash fix (#2463)

* test: ignore NVIDIA_BASE_URL and NVIDIA_MODEL in env contract check

---------

Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>
Co-authored-by: Apostol Apostolov <theapoapostolov@gmail.com>
Co-authored-by: Halil Tezcan KARABULUT <info@hlltzcnkb.com>
Co-authored-by: R.D. <rogerproself@gmail.com>
2026-05-29 19:54:00 -03:00
Halil Tezcan KARABULUT
efcd062002 Fix analytics history and log token accounting (#2904)
Integrated into release/v3.8.6
2026-05-29 13:18:14 -03:00
guanbear
a15750d968 Add self-service API key usage status (#2908)
Integrated into release/v3.8.6
2026-05-29 13:16:53 -03:00
diegosouzapw
e73a2eaca9 merge: pull request #2837 from gitlawb specialty validators 2026-05-29 09:20:01 -03:00
Diego Rodrigues de Sa e Souza
067e0496cf feat(api,oauth): add agy (Antigravity CLI) standalone provider with CLI token import (#2899)
Add a standalone OAuth provider `agy` (Antigravity CLI) next to gemini-cli/antigravity.
It reuses the antigravity inference backend (identical Google client_id +
daily-cloudcode-pa.googleapis.com endpoint, executor and token-refresh) but ships its own
model catalog — including the Claude models the backend exposes (claude-opus-4-6-thinking,
claude-sonnet-4-6) — its own account pool, and four ways to connect:

- token-file import (paste/upload the agy oauth token JSON)
- auto-detect a local CLI login (~/.gemini/antigravity-cli/antigravity-oauth-token)
- browser OAuth (via the shared OAuthModal Google loopback flow)
- bulk / ZIP import

New routes: POST /api/providers/agy-auth/{import,import-bulk,zip-extract,apply-local}.
Catalog pinned from the live :fetchAvailableModels endpoint. Docs (openapi.yaml,
ENVIRONMENT.md, .env.example, CHANGELOG) updated; new unit tests for registration,
the token parser, and route auth-hardening.
2026-05-29 09:16:15 -03:00
diegosouzapw
1682dcbf87 feat: implement automated skill workflows and update system configuration and validation schemas 2026-05-29 08:58:40 -03:00