Match both slash styles when removing build-machine paths from the
staged standalone bundle so the sanitization step works on Windows
and POSIX builds.
While touching the helper, replace the custom basename logic with
Node's built-in `path.basename` for clarity.
Prepare a dedicated `.next/electron-standalone` bundle before
running electron-builder so desktop packaging operates on a stable,
Electron-specific server payload.
This also adds a preflight that rejects standalone bundles whose
top-level `node_modules` is a symlink, because electron-builder
preserves `extraResources` symlinks and would otherwise ship an app
that depends on the build machine at runtime.
- eslint.config.mjs: add missing ignores for vscode-extension/,
electron/, docs/, app/.next/, clipr/ — ESLint was OOMing because
it scanned huge VS Code binary blobs and build artifacts
- tests: remove stale ALTER TABLE 'group' statements — column is now
part of the base schema in core.ts; tests were failing with
SQLITE_ERROR: duplicate column name
- .husky/pre-commit: add npm run test:unit to block broken tests
from reaching CI
Stabilize the bootstrap metadata test by clearing
INITIAL_PASSWORD before each run and add focused coverage
for env-backed and stored-password states.
Log settings lookup failures before returning the
bootstrap-safe fallback payload so operational errors are
still visible on the server side.
Normalize numeric pino levels correctly in the console log API so the logger transport fix does not misclassify info, warn, and error entries in file-backed logs.
Add a targeted regression test for numeric log entries.
Keep the existing level formatter for direct logger paths, but drop
that formatter from transport-backed configs because pino rejects it
when transport.targets is used.
This restores the intended stdout+file transport path and avoids the
startup fallback warning on every boot.
Add localhost and 127.0.0.1 to allowedDevOrigins so local dev
sessions opened on loopback addresses do not have their Next.js HMR
websocket blocked as cross-origin.
Point the login page at the existing public bootstrap endpoint
instead of the protected /api/settings route.
Also extend the public bootstrap response with hasPassword and
setupComplete so unauthenticated users get the correct first-run
or password-setup flow without triggering a 401.
Thanks @kfiramar! 🎉 Critical security fix — different startup paths were generating different `STORAGE_ENCRYPTION_KEY` values over the same SQLite database, causing `Unsupported state or unable to authenticate data` for all stored tokens.
Improvements added on top:
- Normalized `overridePath?.trim()` in `electron/main.js` to match `bootstrap-env.mjs` (addresses kilo-code-bot warning #1)
- Added explanatory comment documenting the `preferredEnv` merge order intent in Electron startup (addresses kilo-code-bot warning #3)
4 commits + 113-line test file. The fail-closed behaviour (refusing to mint a new key when encrypted rows exist) is an excellent safeguard. Merged!
Thanks @kfiramar! 🎉 Critical fix — stale error metadata on recovered provider accounts was preventing valid accounts from being selected properly after recovery.
Improvement added on top: documented the two valid success-check patterns (`result.success` for open-sse handlers vs `response?.ok` for fetch-based handlers) to address the kilo-code-bot review warning — both patterns are correct by design, now explicitly documented.
5 commits total, 2 test files (+168 lines of coverage). Merged!
Thanks @kfiramar! Perfect minimal fix — `t("deleteConnection")` was requesting a non-existent key across all 30 locales, causing `MISSING_MESSAGE: providers.deleteConnection` runtime errors on every provider detail page load. Reusing the existing `providers.delete` key is the correct fix. Merged!
Thanks @kfiramar! 🎉 Critical schema fix — the `group` column was used in all provider_connections queries but missing from the base schema and backfill migration. Databases upgraded from older versions were silently failing on group-related queries. Clean fix with regression test. Merged!
Tighten the helper signatures added for recovered provider cleanup.
This removes the new any-typed recovery parameters called out in
review without broadening the PR into unrelated auth typing work.
Clear recovered provider error metadata after successful
credentialed requests in non-chat API routes as well.
Add route-level regression tests covering a Response-based
success path and a result-object success path.
Refine the recovered-account regression test to match the real
observed state: an account can remain active while still carrying
stale refresh-failure metadata.
This verifies that getProviderCredentials surfaces those fields
and that clearAccountError clears them through the real runtime
path.
Pass errorCode, lastErrorType, and lastErrorSource through the
runtime credentials object so clearAccountError can clear stale
provider error metadata after a real successful request.
Also update the regression test to use getProviderCredentials,
matching the production call path.
Add the missing provider_connections.group column to both the
base schema and the runtime column backfill path.
Also add a regression test covering upgrade from an older
database that does not yet have the column.
Clear errorCode, lastErrorType, and lastErrorSource when an
account recovers so provider state returns to a fully clean
active status.
Add a focused regression test for recovered-account cleanup.
Keep getPreferredEnvFilePath consistent with its env parameter by
passing that env through resolveDataDir in both bootstrap and Electron.
This avoids silently falling back to process.env when a custom env map
is supplied.
Treat empty or whitespace-only dataDirOverride values as unset so
bootstrapEnv keeps using the normal DATA_DIR and .env lookup path.
Adds a focused regression test for the whitespace override case.
Propagate database inspection failures instead of treating them as
missing encrypted credentials.
This keeps startup from generating a fresh encryption key when an
existing database cannot be inspected and adds a regression test for
that path.
Align the app bootstrap paths with the documented CLI env lookup.
The CLI wrapper already loads DATA_DIR/.env, ~/.omniroute/.env, or ./.env,
but run-next, run-standalone, and Electron were bypassing that behavior.
On machines with encrypted credentials, that could generate a fresh
STORAGE_ENCRYPTION_KEY in server.env and make existing tokens unreadable.
This change:
- uses the same preferred .env lookup in bootstrapEnv and Electron
- keeps Electron secrets rooted in DATA_DIR and passes DATA_DIR to the child
- refuses to mint a new encryption key over an existing encrypted database
- adds a focused regression test for env precedence and key safety
Thanks @rexname (Maulana Hasanudin)! 🎉
Codex account quota policy (5h/weekly) with auto-rotation is now merged. Highlights:
- Per-account policy toggles (5h + weekly ON/OFF) in the Provider dashboard
- Accounts automatically skipped when enabled quota window reaches 90% threshold
- Auto re-eligibility when resetAt timestamp passes (no manual intervention needed)
- Side-effect free `getQuotaWindowStatus` getter design
- Safe partial merge of `codexLimitPolicy` on provider updates
Merged on top of main (v2.5.0) with no conflicts. Analytics label fix (#356) included. Thanks for the excellent quality and the 2-commit cleanup round! 🙏
Add a default-off dashboard setting that injects Codex fast service tier only when the request did not already specify one.
Also preserve service_tier through OpenAI-to-Responses translation and restore the setting at startup.
PR #363 added allowedConnections as 3rd arg in chat.ts calls to
getProviderCredentials(), but the function signature in auth.ts
only declared 2 params. Adding the optional 3rd param and applying
the connection filter when provided.
- add user-facing success/error notifications for Codex limit toggle API calls
- deduplicate Codex policy default normalization in providers page
- make getQuotaWindowStatus side-effect free (no cache mutation in getter)
- avoid stale threshold blocking after resetAt has passed
- extract named Codex quota threshold constant
- extract helper for earliest future reset date selection
Add gpt-5.4 to the Codex model registry so OmniRoute exposes cx/gpt-5.4 and codex/gpt-5.4 in its model catalog.
Includes a focused regression test for model resolution.
- add quota window status helper for Codex session (5h) and weekly windows
- enforce policy-based account filtering when enabled windows reach threshold
- return all-rate-limited metadata when no Codex account is eligible
- add per-account dashboard toggles for 5h and weekly policy controls
- merge codexLimitPolicy safely on provider updates to preserve partial settings
- document purpose and usage scenarios in README (EN + ID + i18n note)