mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 14:52:09 +03:00
50881c31d00a06e25f304a15bcadddd5b48c8010
4812 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
50881c31d0 |
chore(release): merge-train — batch-validate queued PRs once, --admin with evidence (#6784)
Merges every queued PR into a throwaway detached worktree cut from origin/<base>, runs the fast-gates parity suite ONCE on the final train tip, and prints the evidence line that authorizes gh pr merge --squash --admin per member (merge-gates.md §7). Conflicting PRs are ejected and reported, the train continues. Never pushes, never merges PRs, never stashes. |
||
|
|
1eb218f76a |
ci(quality): TIA impacted-run splits dashboard tests onto the tsx loader (closes #6787) (#6788)
The impacted branch ran every selected file under --import tsx/esm; the canonical test:unit:ci:shard runs tests/unit/dashboard/** under --import tsx (CJS transform, required for @lobehub/icons/es/* deep imports). Any PR whose impact map reached a dashboard component false-redded with 'Unexpected token export' (reproduced on unrelated PRs #6317 and #6335 the same evening). The selection is now split by segment with loader parity. |
||
|
|
15d08a86c6 | ci(quality): shard unit fast-path 2→4 — halves the heaviest job's wall time (#6781) | ||
|
|
1ddb102a90 |
feat(release): changelog.d/ fragments — eliminate the CHANGELOG merge-storm cascade (#6783)
* feat(release): changelog.d/ fragments — kill the CHANGELOG-eat merge-storm cascade
Every PR used to edit the same top lines of CHANGELOG.md (its bullet), so in a
merge-storm each merge conflicted every sibling (CHANGELOG-eat / DIRTY cascade),
forcing a re-sync push + full CI re-run per PR per merge — O(N^2) CI runs.
A PR now adds ONE new file under changelog.d/{features|fixes|maintenance}/ with its
bullet; two PRs never touch the same file. scripts/release/aggregate-changelog.mjs
(npm run changelog:aggregate) folds fragments into the living section and deletes
them at release reconciliation. check:changelog-integrity (already wired in the
merge-integrity CI job — zero workflow change) now also validates fragment
well-formedness. This PR dogfoods the convention: its own entry is a fragment.
* chore(changelog): fragment filename matches PR number (#6783)
|
||
|
|
1bc6da5318 |
feat(cli): add CLI tools for pi, omp, letta, codewhale and jcode (#6318)
* feat(cli): add CLI tools for pi, omp, letta, codewhale and jcode * fix(build): resolve CI build and lint errors * fix(cli): resolve merge conflicts, add tests, align error handling for cli-additions Resolve duplicate codewhale key from base merge, add unit/integration tests for omp/letta settings routes and the omp DB module, and align omp-settings/letta-settings error handling with sanitizeErrorMessage() + the pattern used by sibling jcode/pi/codewhale routes in this PR. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): correct cliRuntime.ts file-size baseline to actual post-merge line count Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore #6318 bullet after release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(merge): restore #6126 clinepass files reverted by release auto-resolve + baseline re-merge The release sync's auto-resolve reverted sibling PR #6126's clinepass work (registry, catalog, oauth constants, clineAuth.ts, token-refresh case, tests) and the file-size baseline — all outside this PR's scope. Restored to the release versions, re-applied only this PR's own baseline entries, restored the #6126 CHANGELOG bullet (re-inserting only this PR's own). Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(db): re-export db/omp from localDb (check:db-rules #2) Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(db): keep localDb.ts at the 800-line cap after the omp re-export Folded the MemoryVecMeta type re-export into the memoryVec named-export block (inline 'type' specifier) so adding the db/omp line stays within the new-file cap. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(cli): reduce #6318 scope to omp + letta (pi/codewhale/jcode already shipped) pi, codewhale, and jcode landed via a separate PR before this one was reconciled — re-adding parallel versions of their catalog entries, routes, dashboard card, and i18n strings would have been a straight regression (duplicate "pi" key silently shadowing the release's own entry, orphaned JcodeToolCard/BaseUrlSelect/ApiKeySelect/cliEndpointMatch UI files with no release-side wiring, and unrelated formatting/refactor drift in codewhale-settings/pi-settings/config-generator/routeGuard picked up along the way). This PR now ships only the two tools that are genuinely new: omp (Oh My Pi) and letta. Both settings routes shell out to `which omp`/`which letta` to detect the local install, so they're loopback-gated in LOCAL_ONLY_API_PREFIXES (Hard Rules #15/#17) in addition to the shared requireCliToolsAuth() guard every cli-tools route requires (tests/unit/cli-tools-auth-hardening.test.ts) — neither route had the guard wired in yet. cli-catalog-counts.test.ts is updated to the real cardinality (8 agent entries / 32 total, since omp+letta are both category "agent"; pi/codewhale/jcode were always category "code" and are unaffected). The integration tests for omp/letta now pass a Request object to GET/DELETE and assert the 401-when-auth-required path, matching the pattern already used by the codewhale/jcode sibling routes. complexity-baseline.json is back to the release's 2053 (the #6318 rebaseline note is gone — dropping the duplicate JcodeToolCard.tsx/BaseUrlSelect.tsx removed the violations it was covering); file-size-baseline.json's cliTools.ts entry shrank 955->915 to match the smaller real file. CHANGELOG bullet rewritten to describe only omp+letta, with a note on why pi/codewhale/jcode aren't part of this PR; also restores the Kiro External IdP bullet that a prior merge auto-resolve had dropped from the living section. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * test(cli-tools): align cli-tools-schema registry count with omp+letta (30→32) Second exact-count guard missed in the scope-reduction pass; same legitimate alignment as cli-catalog-counts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(cli-tools): omp entry needs docsUrl (CliCatalogEntrySchema requires it) https://github.com/can1357/oh-my-pi — verified official repo. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): cliTools.ts frozen 915→916 (+1 omp docsUrl line, own growth) Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(changelog): restore base + re-insert #6318 bullet after release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(sync): merge release tip + restore own CHANGELOG bullet Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: hamsa0x7 <hamsa0x7@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> |
||
|
|
eeec4d9e87 |
feat(chaos): big update - optimize, fix bugs, add features, enhance UX (#6728)
* feat(chaos): add Chaos Mode — multi-model parallel/collaborative execution - New DB column chaos_mode_enabled on api_keys table - API key create/PATCH routes support chaosModeEnabled toggle - Core library src/lib/chaos/chaosConfig.ts for persistent config - API routes: GET/PUT/DELETE /api/chaos/config - Chaos execution POST /api/skills/collect/chaos with key auth - Dashboard page at /dashboard/chaos with full config UI - Sidebar entry in Agentic Features section - Chaos mode toggle in API Key editor permissions panel - i18n keys for chaos config (en.json) * feat(chaos): big update — optimize, fix bugs, add features === Changes === 1. NEW: src/lib/chaos/chaosExecutor.ts — shared execution engine - Removed ~150 lines of duplicate dispatch logic between two API routes - Single executeChaosRun() function used by both endpoints - Added concurrency limit (max 10 parallel requests) - Added proper TypeScript interfaces (ChaosRunInput, ChaosRunResult) - Added error logging throughout 2. FIX: src/app/api/skills/collect/chaos/route.ts - Was MISSING logger import (log.error was undefined at runtime) - Reduced from 388 lines → 142 lines by delegating to shared executor - Added maxTokens support in schema validation 3. REFACTOR: src/app/api/chaos/run/route.ts - Simplified to thin wrapper: auth + validate + delegate to executor - Added maxTokens support 4. ENHANCE: src/lib/chaos/chaosConfig.ts - Added maxTokens config field (256-128k, default 4096) - Persisted per-instance via settings table 5. ENHANCE: UI — ChaosConfigPageClient.tsx - Loads available providers from /api/models for dropdown autocomplete - Added datalist-based provider selector in overrides section - Added Max Tokens configuration input - Added expandable provider list showing all detected providers - Fixed duplicate override detection * fix(chaos): fetch providers from /api/providers instead of /api/keys * fix(chaos): remove dead code isOverrideDuplicate, fix maxTokens fallback to include global config * fix(chaos): resetConfig now shows error on HTTP failure (was silent) * feat(dashboard): Chaos Mode — multi-model parallel/collaborative execution Splits the PR down to only the genuinely new Chaos Mode feature (drops the duplicate Skill Collector/GitHub-discovery portion already shipped via #6186). Replaces the loopback fetch() dispatch (hardcoded to the wrong port) with the established in-process synthetic-Request/route-handler pattern used by src/lib/batches/dispatch.ts, moves settings persistence off raw SQL, and adds unit test coverage for chaosConfig, chaosExecutor and the 3 chaos API routes. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(chaos): fix external Bearer-auth bypass and stale config cache in tests validateApiKey() returns a plain boolean for both the deployment-time env key and a DB-backed key, so branching on `keyInfo === true` in verifyChaosKey() (src/app/api/skills/collect/chaos/route.ts) treated every valid API key as having full env-key access, silently skipping the chaosModeEnabled permission check entirely. Now always resolves through getApiKeyMetadata() and only bypasses the per-key check for the synthesized env-key record (id: "env-key"). Also exports invalidateChaosConfigCache() from chaosConfig.ts and wires it into the route tests' resetStorage() — the in-process config cache was surviving DB resets between tests, causing state to leak across cases. Fixes CHANGELOG-eat from the release merge (re-inserted the Chaos Mode bullet against the base CHANGELOG.md, verified additive via check-changelog-integrity.mjs) and re-syncs against release/v3.8.47 tip. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * docs(changelog): Chaos Mode overhaul bullet referencing #6728 after release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(merge): restore #6126 clinepass files reverted by release auto-resolve + baseline re-merge The release sync's auto-resolve reverted sibling PR #6126's clinepass work (registry, catalog, oauth constants, clineAuth.ts, token-refresh case, tests) and the file-size baseline — all outside this PR's scope. Restored to the release versions, re-applied only this PR's own baseline entries, restored the #6126 CHANGELOG bullet (re-inserting only this PR's own). Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(dashboard): chaos client hook must not import the server Pino logger useChaosConfigData ("use client") pulled @/sse/utils/logger → shared Pino → logRotation/dataPaths → node:fs into the browser bundle, breaking next build (Turbopack: Can't resolve 'fs') — caught by the DAST smoke's isolated build. console.error matches every other dashboard client component. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * test(api-manager): align switch-count invariant with the extracted toggle components The Self-service block now renders 4 inline switches; the #5731 quota-bypass and #6728 chaos-access toggles were extracted into dedicated components. The type="button" invariant is preserved AND extended: the test now also asserts each extracted component's switches declare type="button". Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(sync): merge release tip + restore own CHANGELOG bullet Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Moseyuh333 <Moseyuh333@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
a5c555b0de |
feat(icons): prioritize local SVG icons over LobeHub npm for faster rendering (#6317)
* feat(icons): prioritize local SVG icons over LobeHub npm for faster rendering * docs(changelog): add #6317 local-icons New Features bullet --------- Co-authored-by: hamsa0x7 <hamsa0x7@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
6103fd7239 |
fix: Stabilize live dashboard WebSocket routing (#6335)
* fix(dashboard): allow anonymous WS handshake + public /api/health/ping
The live-dashboard WebSocket descriptor handshake (GET /api/v1/ws?handshake=1)
and the lightweight GET /api/health/ping liveness probe both 401'd for
unauthenticated callers, even though both are metadata-only reads intended
to be public. clientApiPolicy required a bearer/dashboard-session before the
WS route handler could even return its own wsAuth/protocol descriptor, and
/api/health/ping was never added to PUBLIC_READONLY_API_ROUTE_PREFIXES
despite its own docstring documenting it as "No auth required".
clientApiPolicy.evaluate() now allows an anonymous
{kind:"anonymous", id:"ws-handshake"} subject for GET/HEAD/OPTIONS on
/api/v1/ws?handshake=1 — the route handler still performs its own real
wsAuth/dashboard/API-key decision before opening the socket — and
/api/health/ping is now in PUBLIC_READONLY_API_ROUTE_PREFIXES.
Re-scoped from the original PR per review-group-prs analysis: the
overlapping hardcoded /live-ws path-derivation change (useLiveDashboard.ts,
ws/route.ts) is dropped here since it conflicts with #6072's different
(dynamic, env-derived) approach to the same problem; only the
non-overlapping auth-policy win ships in this PR.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* chore(changelog): resync CHANGELOG.md after merging release/v3.8.47
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: JxnLexn <JxnLexn@users.noreply.github.com>
|
||
|
|
3a28b3b5e8 |
feat: add Kiro API key authentication (#6587)
* feat(oauth): add Kiro long-lived API key auth (#6587) New /api/oauth/kiro/api-key route + KiroService.validateApiKey let a Kiro account be linked with a long-lived AWS CodeWhisperer/Kiro API key instead of the interactive OAuth device flow, with live per-account model discovery (ListAvailableModels, 5-minute cache) layered over the existing static registry fallback. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore #6587 bullet after release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(merge): restore #6126 clinepass files reverted by release auto-resolve + baseline re-merge The release sync's auto-resolve reverted sibling PR #6126's clinepass work (registry, catalog, oauth constants, clineAuth.ts, token-refresh case, tests) and the file-size baseline — all outside this PR's scope. Restored to the release versions, re-applied only this PR's own baseline entries, restored the #6126 CHANGELOG bullet (re-inserting only this PR's own). Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): freeze public-creds FP — AWS region default in validateApiKey signature Same class as the existing minimax fn-param FPs: CRED_KEY_RE matches the apiKey: param annotation and captures the region default "us-east-1", which is not a credential. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(kiro): keep hard-failure reject semantics + kill public-creds fn-param FP at the source - getKiroUsage: exhausted non-auth attempts now REJECT with the last HTTP-status failure in the pre-#6587 format (usage-service-hardening relies on it); auth failures keep the soft social-auth message. - validateApiKey: region default moved out of the parameter list (the check-public-creds CRED_KEY_RE matches the apiKey: annotation and flags any literal in the signature); drops the brittle line-keyed allowlist entry. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: strangersp <strangersp@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
ece4bf7b53 |
feat(kiro): support enterprise External IdP (Your organization) logins (#6363)
* feat(kiro): support enterprise External IdP ("Your organization") logins
Kiro's enterprise "Your organization" sign-in federates through the org's own
identity provider (e.g. Microsoft Entra ID) and produces an `external_idp`
token that is fundamentally different from AWS Builder ID / IAM Identity Center
(AWS SSO-OIDC, refresh token starts with `aorAAAAAG`) and the Google/GitHub
social flow. Its `~/.aws/sso/cache/kiro-auth-token.json` carries an org-IdP JWT
access token, an IdP refresh token, a per-tenant `tokenEndpoint`, a public
`clientId` (no secret) and `scopes` (`codewhisperer:conversations …`).
Before this change every import path rejected these tokens (the
`aorAAAAAG` format gate + no client secret), and the runtime/quota calls would
have failed even if imported, so organization accounts could not be used.
This adds full external_idp support:
- New `open-sse/services/kiroExternalIdp.ts`: public-client refresh_token grant
builder (`buildExternalIdpRefreshParams`), a token-endpoint SSRF allowlist
(`validateExternalIdpTokenEndpoint` — Microsoft/Okta/Auth0/OneLogin/Ping/
Google/Cognito, https only), scope normalization, JWT identity extraction
(`preferred_username`/`upn`/`email`), and the `TokenType: EXTERNAL_IDP`
header constants.
- Runtime executor (`open-sse/executors/kiro.ts`): send
`TokenType: EXTERNAL_IDP` for external_idp accounts. CodeWhisperer only binds
the org-IdP bearer to the Amazon Q Developer profile with this header;
without it every call returns `ValidationException: Invalid ARN <clientId>`.
- Runtime + import token refresh (`open-sse/services/tokenRefresh.ts`,
`src/lib/oauth/services/kiro.ts`): refresh external_idp tokens with a
form-encoded public-client `refresh_token` grant against the org IdP's
`tokenEndpoint` instead of AWS OIDC / the Kiro social endpoint.
- Quota (`open-sse/services/usage/kiro.ts`): send the same header on
`GetUsageLimits` so organization quota resolves.
- Import routes: `POST /api/oauth/kiro/import` gains an external_idp branch
(skips the `aorAAAAAG` gate, refreshes via the org IdP, stores
clientId/tokenEndpoint/scope/region/profileArn); `GET /auto-import` now
recognizes external_idp tokens in `~/.aws/sso/cache`, reads the profile ARN
from the Kiro IDE `profile.json` (org tokens can't enumerate it via
`ListAvailableProfiles`), and persists the connection. The profile.json
reader is factored into a shared `readKiroIdeProfileArn()` helper.
- Validation schema (`kiroImportSchema`): accept `tokenEndpoint` + `scopes`.
Tests: new `tests/unit/kiro-external-idp.test.ts` (endpoint allowlist, scope
normalization, identity extraction, public-client refresh body, the org IdP
refresh path, and the `TokenType: EXTERNAL_IDP` header gating). Also hardens
`kiro-windows-auto-import-3363.test.ts` to isolate `USERPROFILE` (Windows
`os.homedir()` reads it, not `HOME`) so the probe never reads a real on-host
Kiro login.
* fix(changelog): restore #6363 bullet after release resync (CHANGELOG-eat guard)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): re-restore #6363 bullet after release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(merge): restore #6126 clinepass files reverted by release auto-resolve + rebaseline own tokenRefresh growth
The release sync's merge auto-resolve silently reverted sibling PR #6126's
clinepass work (registry entry, catalog, oauth constants, clineAuth.ts, the
clinepass token-refresh case, and its tests) — all outside this PR's Kiro
external-IdP scope. Restored every affected file to the release version; the
remaining diff is Kiro-IdP-only. Rebaselined tokenRefresh.ts 2182->2249 (+67,
this PR's own external_idp refresh branch) with justification, and restored
the #6126 CHANGELOG bullet (re-inserting only this PR's own).
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: artickc <artickc@users.noreply.github.com>
|
||
|
|
d3331f8bca |
feat(providers): ClinePass OAuth login — dual-auth on top of #5942 (reconciles #5924) (#6126)
* feat(providers): rebase ClinePass dual-auth (OAuth + BYOK) onto release/v3.8.47
ClinePass now offers both sign-in methods on its dashboard page: OAuth
(reusing the Cline WorkOS flow, primary "Connect" button) or a pasted
BYOK API key ("Manual API key"), instead of only the API-key-only
provider shipped in #5942.
- Registry: authType oauth + oauth urls, alias aligned to "cp" (matches
the OAUTH_PROVIDERS catalog alias so <alias>/<modelId> routing
resolves); keeps the #6165 forceStream:true fix (streaming-only API).
- Executor: new buildClinepassHeaders() (src/shared/utils/clineAuth.ts)
picks buildClineHeaders() for an OAuth accessToken or a plain Bearer +
Cline identification headers for a BYOK key — extracted to a leaf
module to avoid growing the frozen open-sse/executors/default.ts.
- Refresh: dispatch clinepass to the shared refreshClineToken() (was
falling through to the generic refresh and failing silently).
- Catalog: admit the BYOK path through a dedicated
DUAL_AUTH_APIKEY_PROVIDER_IDS gate (src/lib/providers/catalog.ts) so
POST /api/providers accepts an apikey connection without flipping
isOAuth off (which would break the primary Connect->OAuth routing).
- Dashboard: render both "Connect" + "Manual API key" buttons for
clinepass (ConnectionsHeaderToolbar.tsx, EmptyConnectionsPlaceholder.tsx).
- Dedup: removed the now-redundant API-key-only APIKEY_PROVIDERS_GATEWAYS
entry so ClinePass is listed once (OAuth-primary).
- oauth.ts: added the clinepass catalog entry (was reverted by staleness
during rebase); src/lib/oauth/providers/index.ts: clinepass -> cline.
This branch was ~167 commits / weeks behind release/v3.8.47; a real
merge surfaced 61 conflicting files, several of which are already-shipped
fixes (forceStream #6165, zed-hosted, requesty, agentrouter CC-wire-image,
NVIDIA/Mistral/kimi executor fixes, chatCore hardening) that a naive
resolution would have silently reverted. Reconstructed clean on top of
current release/v3.8.47, isolating and re-applying only the clinepass
dual-auth feature and preserving every already-shipped fix untouched.
tokenRefresh.ts's frozen-file cap raised by the irreducible 1-line
`case "clinepass":` switch label (config/quality/file-size-baseline.json,
justified inline); open-sse/executors/default.ts stays under its cap via
the buildClinepassHeaders() extraction.
Regression guard: tests/unit/clinepass-provider.test.ts (15/15, extended
with the dual-auth admission-gate and alias-consistency guards).
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* test(providers): update APIKEY_PROVIDERS spread-merge count 171->170
The ClinePass dual-auth rebase (this PR) removed the now-redundant
API-key-only APIKEY_PROVIDERS_GATEWAYS.clinepass entry (dedup — clinepass
is OAuth-primary now, with its BYOK path admitted through the
DUAL_AUTH_APIKEY_PROVIDER_IDS gate instead of a second catalog entry),
which drops the total APIKEY_PROVIDERS spread-merge count by one.
tests/unit/providers-constants-split.test.ts hardcoded the prior count
(171); updated to 170 to match, confirmed via CI (Unit Tests fast-path
1/2 and 2/2 both failed on the stale count).
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(oauth): register clinepass in PROVIDERS enum to fix Unknown provider error
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* chore(test): rebaseline oauth-providers-config.test.ts frozen size for clinepass entries
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): re-restore #6126 bullet after release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: hajilok <hajilok@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
|
||
|
|
9906dfc1ba |
fix(providers): update web model discovery (#6308)
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
b9d18dd8c4 |
Continue fix bugs and upgrade skill_collector (#6294)
* fix(skills): gate skill-collector CLI detection behind management auth + loopback PR #6294 fork-main bundled genuinely new skill-collector CLI-detection routes (GET /api/skills/collect/detect, POST /api/skills/collect/install) on top of content already shipped via #6186. This reconstructs the PR against the current release tip, keeping only the new detect/install routes and their SKILL.md, and drops the 3 already-merged commits so two post-merge quality fixes on /api/github-skills (Zod validation + sanitizeErrorMessage) are not reverted. - GET /api/skills/collect/detect spawned a child process per CLI_TOOL_IDS entry via getCliRuntimeStatus(), unauthenticated and reachable over any tunnel. All 3 routes (github-skills GET/POST, skills/collect/detect, skills/collect/install) now require requireManagementAuth(), matching every sibling /api/skills/* route. - Classified /api/skills/collect/ in LOCAL_ONLY_API_PREFIXES and SPAWN_CAPABLE_PREFIXES (routeGuard.ts / spawnCapablePrefixes.ts) and added src/app/api/skills/collect to SPAWN_CAPABLE_ROUTE_ROOTS in check-route-guard-membership.ts so the automated gate actually scans it (Hard Rules #15 + #17). - omniroute_github_skills_install MCP tool now reports the honest action: "planned" instead of "installed", matching the REST route. - Dropped docker-compose.drive-d.yml, start.sh, and the unrelated @types/node/settings.ts changes (personal dev-machine / out-of-scope). - Added route-level tests for all 3 routes + the 3 MCP tools (auth-required and no-stack-trace-leak assertions) and a route-guard regression test. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(quality): register new routeGuard covering test in stryker.conf.json check:mutation-test-coverage --strict (Fast Quality Gates) flagged tests/unit/authz/route-guard-skills-collect.test.ts as a covering unit test for src/server/authz/routeGuard.ts that was missing from tap.testFiles, so its mutant kills would silently not count toward the mutation-test baseline. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore: resync CHANGELOG after merging release/v3.8.47 Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: Moseyuh333 <Moseyuh333@users.noreply.github.com> |
||
|
|
2a5a819dbe |
fix: update Dockerfile with --allow-scripts for better-sqlite3 compil… (#6700)
* fix(docker): compile better-sqlite3 via direct node-gyp rebuild in the Dockerfile The `builder` stage installs dependencies with `npm ci --ignore-scripts` (deliberate supply-chain hardening) and then re-enables the native build for the one package that needs it. `npm rebuild better-sqlite3` re-runs that indirectly through the package's own install script, which under npm 11 depends on npm's script-allowlist machinery correctly re-enabling it — some self-hosted build environments (e.g. Dokploy) hit a broken/mismatched native binding through that indirection. Invoke `node-gyp rebuild` directly inside `node_modules/better-sqlite3` instead, bypassing npm's script-running layer entirely, so the compile step is deterministic regardless of npm version or ignore-scripts allowlist behavior. Rebased onto the current release/v3.8.47 tip: dropped this branch's stale electron/package.json + package-lock.json diff (would have reverted the electron 42->43 ABI-148 fix from #6605) and the unconsumed root `allowScripts` package.json field (npm does not read that key; has zero effect). Regression guard: tests/unit/dockerfile-better-sqlite3-node-gyp-6700.test.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): restore CHANGELOG bullets eaten by release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): correct CHANGELOG restoration (previous attempt had a script-path bug) Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore #6700 bullet after #6496 release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: nowhats-br <nowhats-br@users.noreply.github.com> |
||
|
|
889fffddbe |
fix(cloudflare-relay): use Service Worker syntax with body_part metadata (#6416) (#6496)
* fix(providers): Cloudflare relay Worker uses Service Worker syntax + body_part
CONTEXT: #6416/#6618 fixed the multipart Content-Type but the emitted
worker source still used ES-module syntax (`export default { fetch }`)
with `main_module` metadata. Cloudflare's Workers upload API parses a
plain `application/javascript` script part as Service Worker syntax
regardless of `main_module`, and `main_module` requires the script to
actually be an ES module — so the upload was still rejected.
CHANGE: buildCloudflareWorkerScript() now emits Service Worker syntax
(`addEventListener("fetch", ...)`, no top-level `export`) and the
upload metadata uses `body_part` instead of `main_module`.
Also restores the SSRF-guard bracket-stripping regex for bracketed
IPv6 hosts (`[::1]`, `[fd00::1]`) that an earlier revision of this
change accidentally double-escaped, with regression coverage added to
tests/unit/relay-deploy-5128.test.ts. Updates the sibling
tests/unit/proxy-pool-cloudflare-workers-deployer.test.ts assertion
that still expected the old ES-module contract.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): restore CHANGELOG bullets eaten by release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): re-restore CHANGELOG bullet after further release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): re-restore CHANGELOG bullet after further release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): re-restore CHANGELOG bullet after further release sync
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(changelog): correct CHANGELOG restoration (previous attempt had a script-path bug)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: SeaXen <SeaXen@users.noreply.github.com>
|
||
|
|
6557f44bd2 |
feat(settings): 9router-style Routing Strategy card + sticky parity (#6678)
* feat(dashboard): 9router-parity Routing Strategy card + provider/combo sticky override (#6678) Add a Routing Strategy settings card (Settings -> Routing) surfacing account round-robin/sticky-limit knobs plus a new combo-level sticky round-robin (comboStickyRoundRobinLimit), and a per-provider account-routing override (providerStrategies) wired into getProviderCredentials() ahead of the global fallback strategy. Rebased onto release/v3.8.47 (credit-preserving reconstruction: unrelated package.json/electron/proxyDispatcher drift from the PR's stale base was dropped, only the author's own 12 files were re-applied). Split ProviderAccountRoutingCard/RoutingStrategyCard into smaller hook+subcomponent pieces to stay under the frozen complexity/file-size gates; rebaselined ProviderDetailPageClient.tsx/auth.ts's frozen file-size caps for the small additive growth. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): register combo-rr-sticky-9router.test.ts in stryker tap.testFiles (#6678) CI's Fast Quality Gates -> check:mutation-test-coverage --strict flagged the new test as missing from stryker.conf.json's tap.testFiles (it covers the mutated module open-sse/services/combo/rrState.ts). Adds the single entry, alphabetized next to the existing combo-rr-fallback-advance-948.test.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): restore CHANGELOG bullets eaten by release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: SeaXen <SeaXen@users.noreply.github.com> |
||
|
|
d76aa40ee6 |
fix(chatgpt-web): render citations as markdown links (#6635)
* fix(providers): render ChatGPT-web citation markers as Markdown links ChatGPT Web responses leaked raw chatgpt.com UI citation markup (private-use marker tokens like `citeturn0search0`, `entity[...]`) instead of real Markdown links, since these are normally resolved client-side by chatgpt.com's own JS using `message.metadata.content_references`. cleanChatGptText() now resolves content_references (grouped webpages, footnote sources, inline webpage/url mentions) into `[label](url)` Markdown links for the streaming and non-streaming response builders and the GPT-5.5 Pro stream_handoff polled-answer path, falling back to stripping any marker with no resolvable source. The citation parsing/rendering logic was extracted into a new pure sibling module (open-sse/executors/chatgpt-web/citations.ts), decomposed into small per-reference-type helpers, to keep the executor under the frozen file-size cap and the complexity/cognitive-complexity ratchets. Regression tests moved to a dedicated tests/unit/chatgpt-web-citations.test.ts for the same reason. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): restore CHANGELOG bullets eaten by release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: Thinkscape <thinkscape@users.noreply.github.com> |
||
|
|
237bd59173 |
fix(api): sanitize catch-block error.message in middleware/hooks routes (#6645)
* fix(api): sanitize catch-block error.message in middleware/hooks routes POST /api/middleware/hooks and PUT /api/middleware/hooks/[name] returned the raw error?.message in their 500 response bodies (Hard Rule #12), which could leak internal SQLite error text/paths on a DB failure. Both now route through sanitizeErrorMessage() from open-sse/utils/error.ts, matching the pattern already used elsewhere in the codebase. Regression guard: tests/unit/middleware-hooks-error-sanitization.test.ts Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * test(mutation): register middleware-hooks-error-sanitization in stryker tap.testFiles The mutation test-coverage gate (check:mutation-test-coverage --strict) flagged tests/unit/middleware-hooks-error-sanitization.test.ts as covering open-sse/utils/error.ts but missing from stryker.conf.json's tap.testFiles list. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): restore CHANGELOG bullets eaten by release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): re-restore CHANGELOG bullet after further release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
912ff8d1c4 |
fix(vision-bridge): auto-reroute non-vision models to fastest vision model when images detected (#6640)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * fix(vision-bridge): auto-reroute non-vision models to fastest vision model when images detected The VisionBridgeGuardrail was describing images as text via a vision model and sending text to the original (non-vision) model. This defeated the purpose when the final target was already vision-capable (auto/vision, combos with vision targets) and never actually rerouted requests to a vision model. Changes: - Individual non-vision models + images → reroute to the fastest available vision-capable model (via getBestVisionModel), keeping images intact - Auto/ prefix models (auto/vision, auto) → skip guardrail entirely, letting the auto-combo resolver handle vision-capable model selection - Combo mappings with non-vision targets → keep existing describe behavior (fallback path via checkModelHasComboMapping) - chat.ts: sync modelStr from body.model after guardrail execution so downstream routing uses the rerouted model * fix(vision-bridge): use getBestVisionModel auto-routing instead of fixed model Address Gemini review feedback: getBestVisionConfig({}) with empty object bypassed auto-routing by always defaulting to a fixed model. Auto-select the best vision model from available providers instead. * fix: compact modelStr sync to stay under file-size cap (1632) * fix: remove debug log, orphaned brace to keep file under cap * chore: trigger CI re-run with file-size fix and PR evidence * chore: rebaseline chat.ts frozen cap to 1754 (PR #6640 +3 lines) * fix(auto-combo): respect hidden models from dashboard toggle getHiddenModelsByProvider() only queried modelCompatOverrides and customModels namespaces, missing the hiddenModels namespace used by the dashboard hide/unhide toggle. Auto-combo candidates now filter out models the user explicitly hid. * fix(changelog): restore CHANGELOG bullets eaten by release sync Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: herjarsa <herjarsa@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
5e5447a2ba |
fix(sse): count gate/combo-rejected requests in per-api-key usage (#6698)
Requests rejected before handleChatCore — a pipeline-gate rejection (provider circuit breaker OPEN / model cooldown) or a combo whose targets were all exhausted — short-circuited in chat.ts and only wrote a call_logs row (dashboard/logs). They never reached persistFailureUsage, so no usage_history row was created and the per-api-key usage counter (getApiKeyUsageRows reads usage_history) never incremented. An API key whose traffic was entirely gate/breaker-rejected showed zero requests despite real usage. Route both rejection paths through recordRejectedRequestUsage(), which writes the call_logs row (unchanged visibility) AND a usage_history row attributed to the api key with success:false, mirroring persistFailureUsage. Regression guard: tests/unit/rejected-request-usage.test.ts. |
||
|
|
0d20205f92 |
fix(sse): preserve server-tool literal names in message history and tool_choice (#6586)
* fix(sse): preserve server-tool literal names in message history and tool_choice The v3.8.36 guard (isAnthropicServerToolType, #2943) protects Anthropic server tools (web_search_20250305, bash_20250124, ...) from the tool-name cloak only in the tools[] array. The same reserved literal names were still rewritten in message-history tool_use blocks and in tool_choice, and remapToolNamesInRequest had no guard at all (bash -> Bash). The resulting asymmetry — tools[] keeps 'web_search' while the history reference becomes 'WebSearch' — makes Anthropic reject every follow-up turn of a native web-search conversation: [400] Tool 'WebSearch' not found in provided tools Collect the declared server-tool names once per request and skip them in every rewrite path of both remapToolNamesInRequest and cloakThirdPartyToolNames (tools[], message history, tool_choice). Plain custom tools with the same names (no server type) remain remapped/cloaked exactly as before, symmetrically in all sections. Surfaced on Claude Code 2.1.x native WebSearch; same class as CLIProxyAPI #1094/#1179. TDD: 5 failing repro tests -> guard -> 7/7 green (92/92 across the remapper suite), typecheck:core clean. * fix(sse): skip null entries in tools[] before server-tool type check Review follow-up (gemini-code-assist): a null element in tools[] made the new isAnthropicServerToolType(tool.type) check throw. The crash path is pre-existing (String(tool.name) on the next line threw identically), but the guard is cheap and mirrors the null checks already used in cloakThirdPartyToolNames. Adds a regression test (8/8 green). |
||
|
|
edae0cf33f |
Expose per-combo reasoning token buffer toggle (#6702)
* fix(combos): default reasoning token buffer off
* feat(combos): expose reasoning token buffer toggle
* fix(combos): keep reasoning-token buffer default enabled, opt-out toggle
#6702 shipped bundled with #6536's own commit (identical SHA
|
||
|
|
abfced8b28 |
feat(sandbox): native Apple Container, WSL, OrbStack, Podman runtime support (#6611)
* feat(sandbox): native Apple Container, WSL, OrbStack, Podman runtime support
* fix(skills): align sandbox fallback kill container-name convention
sandbox.ts's docker-fallback kill path (used only when cachedProvider is
unexpectedly null) still targeted the pre-PR omniroute-sandbox-${id}
container name, while containerProvider.ts's SANDBOX_NAME now produces
omniroute-${id}. Align the fallback naming so it matches the provider
convention, with a regression test covering kill()/killAll() before a
provider has ever been resolved.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(docs): document SKILLS_SANDBOX_RUNTIME and drop unrelated env leftovers
Two fixes surfaced by CI's env/docs contract gate:
- Add the SKILLS_SANDBOX_RUNTIME row to docs/reference/ENVIRONMENT.md so
the new container-runtime override introduced by this PR is documented,
matching .env.example.
- Remove the Substrate/Bifrost/OTEL .env.example blocks that leaked in
from this branch's stale main-based history during the release-branch
sync merge — none of that belongs to this PR (native container
runtimes for the skill sandbox) and none of it exists on
release/v3.8.47 yet.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
|
||
|
|
e697670046 |
fix(cli): detect WinGet Claude Code on Windows (#6647)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * fix(cli): detect WinGet Claude Code on Windows * chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR) Restores electron/package-lock.json, electron/package.json, package-lock.json, package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content. The PR fork branched from a state of main that already includes #6620 (proxy CONNECT tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way merge would otherwise silently carry that unrelated content into this doc-only PR. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): rebaseline cliRuntime.ts file-size freeze for #6647 (1100->1110) The file was already exactly at the frozen 1100-line cap on release/v3.8.47. PR #6647's WinGet Claude Code detection path adds 10 lines (irreducible — the 62-char package folder name forces Prettier's 100-char width to break the path.join call across the same multi-line form used by every other long path in this function), tripping the Fast Quality Gates check:file-size job. Bumping the frozen cap to the file's real new size per the documented allowlist-with-justification policy (this is a pass/fail policy gate, not the ratchet metrics system). Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: quanturbo <faralechko@gmail.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
2b33c6c635 |
docs(routing): reconcile 17 vs 18 public-strategy count in AUTO-COMBO (#6646)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * docs(routing): reconcile 17 vs 18 public-strategy count in AUTO-COMBO * chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR) Restores electron/package-lock.json, electron/package.json, package-lock.json, package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content. The PR fork branched from a state of main that already includes #6620 (proxy CONNECT tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way merge would otherwise silently carry that unrelated content into this doc-only PR. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
484abed8c1 |
docs: sync routing-strategy count to 18 across README + AGENTS.md (#6644)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * docs: sync routing-strategy count to 18 across README + AGENTS.md * chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR) Restores electron/package-lock.json, electron/package.json, package-lock.json, package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content. The PR fork branched from a state of main that already includes #6620 (proxy CONNECT tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way merge would otherwise silently carry that unrelated content into this doc-only PR. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
6e16ae7b32 |
docs(claude): fix p2c casing to match ROUTING_STRATEGY_VALUES (#6643)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * docs(claude): fix p2c casing to match ROUTING_STRATEGY_VALUES * chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR) Restores electron/package-lock.json, electron/package.json, package-lock.json, package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content. The PR fork branched from a state of main that already includes #6620 (proxy CONNECT tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way merge would otherwise silently carry that unrelated content into this doc-only PR. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
1291e9bf26 |
fix(providers): web-cookie fallback validation reports unsupported instead of a false valid (#6309)
validateWebCookieProvider() previously required a providerRegistry.ts entry and
returned "Provider not found in registry" for web-cookie-only providers like
lmarena, gemini-business, poe-web, venice-web and v0-vercel-web. A fallback to
WEB_COOKIE_PROVIDERS[provider].website was proposed, but live verification showed
probing `${website}/models` does not reliably signal session validity for these
(redirects/SPA 200s regardless of cookie validity) — it would report an expired
or garbage cookie as valid, which is worse than an honest "not supported". Until
each provider has a verified, side-effect-free auth probe against its real API
host, the fallback now returns `unsupported: true` with no network call. Also
reverts the probe transport from validationRead back to directHttpsRequest,
which fixes a globalThis.fetch mock/patch-timing mismatch that made the
pre-existing tests/unit/provider-validation-web-cookie-auth007.test.ts hit the
live network in CI, and adds the missing Cookie header to the probe request.
Regression guard: tests/unit/web-cookie-validation-fallback.test.ts.
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
|
||
|
|
aba98fd227 |
fix(cli): per-agent DNS, startup guards, and batched Windows hosts writes (#6338)
DNS toggle in AgentBridge was broken for 8 of 9 agents: addDNSEntry/ removeDNSEntry always resolved the legacy Antigravity default hosts regardless of which agent's dns_enabled flag was flipped. Both now accept an optional agentId and resolve hosts via ALL_TARGETS; the [id]/dns route passes id through and returns 404 for an unknown agent instead of silently falling back to the defaults. startMitmInternal() now wraps generateCert(), the provisionDnsEntries() call, and the PID-file write in try/catch so a mid-startup failure can't orphan the already-spawned MITM child process. On Windows, addDNSEntries/removeDNSEntries batch every missing/present entry into a single elevated PowerShell invocation instead of one UAC prompt per host line. Scope note: this PR originally bundled an unrelated SkillOpt feature (DB migration, 6 API routes, dashboard UI) and a checks-free CI build workflow alongside this DNS/startup fix. Both were dropped here as out-of-scope per review-group-prs analysis (2-implementing plan); only the DNS/startup-guard delta (dnsConfig.ts, manager.ts, the [id]/dns route, and their tests) is applied. Co-authored-by: hamsa0x7 <hamsa0x7@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> |
||
|
|
606d1cbbd3 |
fix: move tier-flow SVG images to public directory (#6538)
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
0e4145d257 |
fix(providers): remove obsolete providers (glhf, kluster, cablyai, inclusionai) (#6675)
Drop dead catalog/registry entries, keep Synthetic as the GLHF replacement path, regenerate provider reference/docs counts, and lock APIKEY family-split + file-size gates so CI stays green. Ignore prettier on freeModelCatalog.data.ts so dense one-line budget rows are not expanded past the 800-line new-file cap. |
||
|
|
f4fb0d310b | docs(readme): update star badges and star history chart links | ||
|
|
902e66805c |
chore(vscode): update search exclude patterns and add documentation
Add several directories to the search exclude list to improve search performance and add a comment explaining why certain directories are not being hidden from the file explorer. |
||
|
|
f4643a2476 | docs(changelog): add v3.8.47 Contributors section (32 contributors) | ||
|
|
5144712ab6 |
ci(vps): honor VPS_ALWAYS_ON — release teardown is a no-op on the dedicated 24/7 host (#6693)
The .113 VM is now a dedicated, always-on CI host so day-to-day quality.yml PRs (PR→release/**) use the 32-core VPS, not just release CI. release-runner-down.sh must not flip USE_VPS_RUNNER=false / shut the VM down when VPS_ALWAYS_ON=true, or every PR after a release would fall back to ubuntu-latest. Legacy on-demand teardown still applies when the var is unset/false. |
||
|
|
632d304939 |
ci(quality): route the 3 heavy fast-path jobs to the self-hosted VPS pool when USE_VPS_RUNNER is on (#6691)
Extends the same dynamic-runner gate ci.yml already uses (build/test-unit/test-vitest) to quality.yml's fast-gates/fast-vitest/fast-unit — the ~9min-on-ubuntu jobs that run on every PR→release/**. Inert until USE_VPS_RUNNER flips to true (falls back to ubuntu-latest when the var is unset/false OR the PR is a fork — own-origin branches only, never the LAN runner for fork code). lint-guard/merge-integrity stay on ubuntu-latest (trivial; keeps VPS concurrency low). No behavior change today. |
||
|
|
a6ea6074cb |
fix(cli): compression REST fallback uses canonical defaultMode + JSON object cells (#6571) (#6682)
* fix(cli): compression REST fallback uses canonical defaultMode + JSON object cells (#6571) * test(cli): align existing compression-command tests to the #6571 canonical field contract (engine→strategy/defaultMode) |
||
|
|
1188847f0f |
feat: add setting for provider/model-specific parameters (#6649)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * feat(db): add provider param filter config store (key_value namespace) Add paramFilters.ts module for CRUD against provider_param_filters namespace in the key_value table, with in-memory cache + generation counter invalidation. Supports denylist/allowlist per provider and per model, plus auto-learn flag. Migration 118 documents the namespace (no schema change). Issue: #6625 * feat(proxy): add detectUnsupportedParam regex for auto-learning Add UNSUPPORTED_PARAM_RE and detectUnsupportedParam() to extract the offending parameter name from upstream 400 error messages like 'Unsupported parameter(s): thinking'. Issue: #6625 * feat(proxy): extend stripUnsupportedParams with config-driven denylist/allowlist Add applyConfigFilters() called after hardcoded STRIP_RULES in stripUnsupportedParams(). Config-driven rules (DB-backed via paramFilters.ts) support provider-level and model-level: 1. Provider denylist (delete body[key]) 2. Model denylist (delete body[key]) 3. Provider allowlist (restore from pre-strip snapshot) 4. Model allowlist (restore from pre-strip snapshot) Allowlist only restores keys the client actually sent — never introduces new params. Issue: #6625 * feat(proxy): wire auto-learn of unsupported params into 400-downgrade loop When a provider returns 400 with 'Unsupported parameter: X' and the provider config has autoLearn enabled, auto-detect the param name via detectUnsupportedParam(), persist it to the provider's block list via addParamToBlocklist(), then strip and retry. Issue: #6625 * test: add tests for provider param filter denylist/allowlist/auto-learn Three new test files: - param-filters-apply.test.ts — hardcoded rules regression + direct applyConfigFilters tests (no DB dependency) - param-filters-db.test.ts — CRUD against key_value, cache invalidation, full filter pipeline (DB-backed config → stripUnsupportedParams), 16 tests in isolated temp DB - param-filters-auto-learn.test.ts — UNSUPPORTED_PARAM_RE regex matching and detectUnsupportedParam edge cases All existing tests unchanged and passing. Issue: #6625 * feat(proxy): add global auto-learn flag for unsupported params Add isAutoLearnGloballyEnabled() and setGlobalAutoLearnEnabled() to paramFilters.ts. The global flag (stored as key __global__ in the provider_param_filters namespace) acts as a master switch: when enabled, ALL providers auto-learn unsupported params from 400 errors. In base.ts, the auto-learn check now evaluates: shouldAutoLearn = isAutoLearnGloballyEnabled() || perProviderConfig?.autoLearn Global flag defaults to false (opt-in). Tests cover enable/disable/ default/no-interference-with-per-provider-config. Issue: #6625 * fix: apply PR#6649 review feedback — model-scoped auto-learn and precedence order Fixes from gemini-code-assist[bot] review: - HIGH: Auto-learn now scoped to the specific model that triggered the 400 (addParamToBlocklist(this.provider, autoLearned, model)) instead of adding to the provider-level blocklist globally - HIGH: Reordered applyConfigFilters so model-level operations run AFTER provider-level operations (model denylist → model allowlist override provider allowlist → provider denylist) - MEDIUM: Include model name in auto-learn log message Adds regression test verifying model-level denylist beats provider-level allowlist. Issue: #6625 PR: #6649 * feat(ui): add provider-level param filter section to detail page Add ProviderParamFilterSection component rendered on each provider detail page, backed by GET|PUT|DELETE /api/providers/[id]/param-filters. UI allows operators to configure: - Blocked params (comma-separated, stripped from outgoing requests) - Allowed params (comma-separated, re-added after denylist stripping) - Auto-learn toggle (per-provider, enables auto-learning from 400 errors) Wired into ProviderDetailPageClient.tsx between the Playground panel and the Modals section. Issue: #6625 PR: #6649 * feat(ui): add model-level param filter fields in compat popover Extend ModelCompatPopover with Blocked params and Allowed params text inputs for model-level denylist/allowlist overrides. Model-specific block/allow data is persisted via the param-filters API endpoint (PUT /api/providers/:id/param-filters) with the model scope under the models key. Both ModelRow and PassthroughModelRow now pass providerId and modelId to the popover. Issue: #6625 PR: #6649 * chore: gitignore .claude-flow/ * fix(param-filters): review follow-ups — auth gate, error sanitization, Zod body validation, typecheck, file-size, i18n keys Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(param-filters): drop unrelated main-drift from the fork branch (deps/electron/proxy files belong to #6620/#6605/#6588, not this PR) * refactor(param-filters): split oversized functions — keep complexity gate at baseline Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * refactor(param-filters): decompose config parser helpers — keep cognitive-complexity gate at baseline Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(changelog): restore sibling #6648 bullet eaten by merge auto-resolve + re-insert #6649 entry Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
2d9f85d587 |
fix(mimocode): handle 400 with cooldown + account rotation (#6648)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605) fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148). Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148). Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.) * deps: bump the development group across 1 directory with 6 updates (#6588) deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605). * fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620) fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump. undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green. Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.) * fix(mimocode): handle 400 with cooldown + account rotation Treat HTTP 400 responses the same as 429: mark the account on cooldown and continue to the next fingerprint/proxy. Previously, 400 fell through to markSuccess and returned immediately, so only 1 of N accounts was ever tried per request. Refs: #5925 * chore(mimocode): drop unrelated dependency/electron drift from PR #6648's stale fork package.json/package-lock.json (bun/eslint-config-next/cyclonedx bumps), electron/package.json, electron/package-lock.json, open-sse/utils/proxyDispatcher.ts, prepare-electron-standalone.mjs and tests/unit/proxy-dispatcher-family.test.ts were already present in the contributor's single commit but are unrelated to the mimocode 400-handling fix — restored to release/v3.8.47's versions so the PR stays scoped to open-sse/executors/mimocode.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(mimocode): classify 400 body before rotating — rate-limit-text 400s rotate, malformed 400s fail fast (#2101/#4976 guard) Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * refactor(mimocode): extract auth-retry + 429/400 gating helpers — keep execute() under the cognitive-complexity gate Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: pizzav-xyz <pizzav-xyz@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> |
||
|
|
d0c775564a | docs(claude): atualiza nomes da família de skills review/triage/implement (Hard Rule #21) (#6663) | ||
|
|
a14bbccf17 |
chore(deps): bump omniglyph to ^1.0.2 (security: ReDoS fixes) (#6661)
The lockfile pinned omniglyph@1.0.0, which carries the polynomial-ReDoS regex paths fixed in 1.0.1/1.0.2 (all upstream CodeQL alerts resolved). Bump the range to ^1.0.2 and refresh the lock so `npm ci` installs 1.0.2. No change to the omniglyph engine behavior — 1.0.1/1.0.2 touched only regex hot paths and docs; the dependency tree is unchanged (gpt-tokenizer ^3.4.0). Co-authored-by: diegosouzapw <souzamiriamrodrigues790@gmail.com> |
||
|
|
fd7e4c10e5 |
feat(compression): omniglyph engine (context-as-image, Fable 5 direct) — stack + single mode (#6556)
* feat(compression): dependência omniglyph (file:) + smoke de import * feat(compression): engine omniglyph — contexto-como-imagem com gates fail-closed * fix(compression): omniglyph adapter fail-open no transform (try/catch) * feat(compression): registra omniglyph no registry e catálogo (single mode, stackPriority 90) * feat(compression): modo único omniglyph (async), selecionar o modo é o enable * feat(compression): plumbing supportsVision + providerTransport até os engines * feat(compression): estimador de tokens image-aware — modo stacked mantém a saída do omniglyph * docs(compression): corrige comentário do prefixo base64 no decode PNG (64 chars) * feat(compression): registra omniglyph nas listas de modo/engine (db, combo, deriveDefaultPlan, mcp) * feat(dashboard): dedicated OmniGlyph engine screen (context-as-image) Adds a per-engine detail page at /dashboard/context/omniglyph, alongside the other compression engines in the sidebar. Four sections: the economics (measured savings), a REAL before→after (dense text vs the rendered PNG page, not a mockup), the fail-closed gate flow, and the enable control wired to /api/settings/compression (preview engine, off by default). Sidebar entry + i18n label across all locales. * chore(compression): consume published omniglyph@^1.0.0 from the npm registry Replaces the local file: dependency used during the preview phase — npm ci now resolves omniglyph from the registry with integrity, unblocking CI. * fix(compression): satisfy v3.8.47 quality gates for the omniglyph engine - dependency-allowlist: approve omniglyph (own package, published from diegosouzapw/OmniGlyph; supply-chain review done by the maintainer) - ladder maps (#6533 guard): rank omniglyph 80 (stackPriority 90, runs after every text engine) with expectedReductionFactor 0.35 (measured 0.23-0.33) - drop the two explicit any casts in omniglyph tests (no-explicit-any is error-level in tests since #6218) * chore(compression): rebaseline strategySelector for the omniglyph mode dispatch +18 lines of cohesive dispatch/type wiring at the existing mode chokepoints (sync no-op + async single-mode branch + providerTransport on the options types) — not extractable without hiding the dispatch boundary, mirroring the prior compression rebaselines. Also drops an unused eslint-disable directive in image-aware-tokens.test.ts (warning-level red under --max-warnings 0). * chore(quality): register inherited base tests in stryker tap.testFiles masked-200-exhaustion-fallback-6427 and headroom-codex-quota-snapshot-6379 arrived via the base merge without their stryker registration — check:mutation-test-coverage --strict requires covering tests to be listed. * refactor(compression): keep omniglyph wiring under the complexity gate - extract the async single-mode resolution to engines/omniglyphSingleMode.ts (runCompressionAsync was at complexity 17 after the mode branch; back <=15) - split OmniglyphContextPageClient into section components (was 161 lines in one function; every function now under the 80-line cap) - complexity baseline 2052->2053: the +1 is inherited base drift (the ratchet does not run on fast-path merges — same pattern as the v3.8.44/46 rebaselines); this PR's own code is measured complexity-net-zero * chore(quality): register 3 more inherited base tests in stryker tap.testFiles route-guard-middleware-local-only, combo-diagnostics-trace and idempotency-fusion-collision arrived via the latest base merge without their stryker registration (fast-path merges skip check:mutation-test-coverage). * chore(quality): cognitive-complexity baseline 883->884 (inherited base drift) check:cognitive-complexity measures 884 identically on the pristine origin/release/v3.8.47 tip and on this HEAD — the PR itself is cognitive-net-zero (single-mode resolution extracted to its own module, page client split into section components). Same inherited-drift pattern as the v3.8.4x release rebaselines. --------- Co-authored-by: diegosouzapw <diegosouzapw@devbox.local> |
||
|
|
95e4bf72d4 |
fix(playground): accept a dashboard session for presets under REQUIRE_API_KEY (#6554)
Merged — thank you, @developerjillur! Accept a valid dashboard session for /api/playground/presets under REQUIRE_API_KEY (the Playground page authenticates via cookie, not an API key). Integrated into release/v3.8.47. |
||
|
|
ed0b9c73de |
perf(health): short-TTL cache for GET /api/monitoring/health (#6553)
Merged — thank you, @developerjillur! Short-TTL (1s) cache for the frequently-polled GET /api/monitoring/health, invalidated on DELETE (circuit-breaker reset). Integrated into release/v3.8.47. |
||
|
|
63d15bcb93 |
feat(combo): sanitized diagnostic trace on auto-combo terminal failure (#6545)
Merged — thank you, @developerjillur! Sanitized diagnostic trace on an auto-combo terminal failure (ids/reason-codes only, capped), plus an actionable reasoning-budget-exhausted message. Integrated into release/v3.8.47. |
||
|
|
8d59e1f660 |
fix(security): fail-closed CORS for cloud-agent management routes (#6543)
Merged — thank you, @developerjillur! Fail-closed CORS for the cookie/session-authed cloud-agent management routes (allowlist echo, credentials only for an explicitly allowlisted origin). Integrated into release/v3.8.47. |
||
|
|
899c40da67 |
fix(security): SSRF-guard provider validation probes (block cloud metadata) (#6542)
Merged — thank you, @developerjillur! SSRF-guards the provider-validation probes (block-metadata + no redirect) so a caller-controllable baseUrl can't relay to cloud metadata. Integrated into release/v3.8.47. |
||
|
|
2c42599e33 |
fix(security): loopback-gate /api/middleware/* (arbitrary JS via vm.Script) (#6541)
Merged — thank you, @developerjillur! Loopback-gates /api/middleware/* (arbitrary JS via vm.Script) for RCE parity with /api/plugins/*. Integrated into release/v3.8.47. |
||
|
|
db0830e60a |
fix(fusion): judge replayed a panel answer via idempotency-key collision (#6558)
Merged — thank you, @developerjillur! Namespaces the idempotency key by target provider/model + a messages digest so fusion panel/judge sub-requests can't collide on a shared client Idempotency-Key. Existing chatCore extracted-module tests were aligned to the composed-key contract. Integrated into release/v3.8.47. |
||
|
|
639eedb1da | fix(api): accept valid Codex connection edits instead of rejecting as Invalid request (#6562) (#6626) |