kilocode renders ASCII logo banner on startup causing false healthcheck_failed
timeouts on cold-start or low-resource environments (VPS, CI, dashboard)
All 3 throw new Error(data.error) replaced with proper extraction:
typeof error === object ? error.message : error
Fixes Cline and other OAuth providers showing [object Object] on connection failure
- cline.ts: add decodeURIComponent before base64 decode to handle URL-encoded codes
- cline.ts: populate name = firstName+lastName || email in mapTokens
- oauth/exchange route: normalize name=email for all providers on exchange/poll/poll-callback
- Fixes: accounts showing Account #ID instead of email in providers dashboard
- Add cliTools.toolDescriptions.opencode, .kiro, guides.opencode, guides.kiro to en.json
- Sync 1111 missing keys across 29 language files (English fallbacks)
- Fix [object Object] in provider batch test modal:
normalize data.error object to string before setTestResults()
and in ProviderTestResultsView rendering
- Bump version to 2.3.6
Endpoints page:
- Add Music Generation section (/v1/music/generations) in Media & Multi-Modal category
- Include music models (type=music) in endpointData and total model count
- Transcription section already shows Deepgram/AssemblyAI via allModels filter
Provider action buttons:
- Remove hover-only behavior from connection action buttons (edit/delete/reauth/proxy)
- Remove hover-only behavior from combo action buttons (test/duplicate/proxy/edit/delete)
- Buttons now always visible for better UX
Provider logos (SVG fallback):
- ProviderCard now tries .svg before showing text initials when .png not found
- Add SVG logos: ElevenLabs, Hyperbolic, AssemblyAI, PlayHT, Inworld, NanoBanana
- Add ollama-cloud.png (official Ollama icon)
Parse [1m] suffix from model name (e.g. claude-sonnet-4-6[1m]) and
propagate extendedContext flag through the request pipeline to append
context-1m-2025-08-07 to the Anthropic-Beta header.
Two strings were hardcoded in Portuguese regardless of the user's language setting:
1. The redirect_uri_mismatch error message (line ~101)
2. The remote access info banner for Google OAuth providers (line ~515)
Both are now in English. The anchor href is updated from
'#oauth-em-servidor-remoto' to '#oauth-on-a-remote-server' to match
the EN README anchor.
getSettings() is declared async so calling it without await left
settings as a Promise<Record<string, unknown>>, causing 4 TS errors
when accessing settings.modelAliases in the alias restore block.
#315: Import and call resolveModelAlias() in chatCore.ts before the
getModelTargetFormat() lookup so that custom aliases configured in
Settings → Model Aliases → Pattern→Target are actually applied during
routing instead of being silently ignored.
#316: Load persisted custom model aliases from settings DB at server
startup (instrumentation.ts). Previously _customAliases started as an
empty object after every restart since setCustomAliases() was only
called by the PUT /api/settings/model-aliases handler — never at init.
Now aliases are restored from settings.modelAliases JSON field on boot.
Resolves root cause of #252 (Electron black screen) and #249 (OAuth fail)
for users running with zero configuration (no .env needed).
New: scripts/bootstrap-env.mjs
- Auto-generates JWT_SECRET (64 bytes), STORAGE_ENCRYPTION_KEY (32 bytes),
API_KEY_SECRET (32 bytes) if missing or empty
- Persists to {DATA_DIR}/server.env — survives restarts, Docker volume
remounts, and upgrades without changing secrets
- Reads .env from CWD (user overrides), then merges process.env (highest prio)
- Logs friendly warnings for missing optional OAuth secrets
Updated: run-standalone.mjs + run-next.mjs
- Call bootstrapEnv() before spawning server — covers npm + Docker paths
Updated: electron/main.js (synchronous inline — CJS cannot await import ESM)
- Reads userData/server.env, generates missing secrets with crypto.randomBytes()
- Persists back to server.env, sets OMNIROUTE_BOOTSTRAPPED=true
New: BootstrapBanner.tsx + page.tsx update
- Dismissable amber banner on dashboard home when running in zero-config mode
- Shows where server.env is located and how to customize secrets
When a manually created OpenAI/Anthropic-compatible provider has 0 connections,
the Add Connection button was hidden behind !isCompatible guard, making it
impossible to add a key. Button now appears in the Connections card header
for compatible providers too, limited to 1 connection (single key per node).
- tests/unit/combo-circuit-breaker: use full model path keys
(combo:groq/llama-3.3-70b) matching combo.ts implementation
- tests/e2e/protocol-visibility: click Protocols tab before asserting
MCP/A2A links (they moved into tab panel, not header nav)
- src/i18n/messages/en.json: add missing header.mcp / header.a2a keys
that caused MISSING_MESSAGE runtime errors during E2E boot
fix(cursor): add zlib inflate/inflateRaw fallback for GZIP_ALT/GZIP_BOTH frames (#250)
- GZIP_ALT (0x02) and GZIP_BOTH (0x03) frames may use zlib deflate instead of gzip
- Now tries gunzipSync → inflateSync → inflateRawSync with verbose error logging
fix(codex): override refreshCredentials to enable automatic token refresh on 401 (#251)
- CodexExecutor was inheriting base class null return, blocking 401 recovery
- Now calls refreshCodexToken() from tokenRefresh.ts on 401 upstream response
- Handles rotating token errors and surfaces re-auth warning clearly
fix(auth): allow dashboard access when no password is set after onboarding skip (#256)
- isAuthRequired() was blocking /dashboard/settings when setupComplete=true but no password
- Removed setupComplete guard: if there's no password, auth cannot be required
- Configure Password button on login page now navigates correctly to security settings
Before this fix, geminiToClaudeResponse() called content_block_start +
content_block_stop on EVERY streaming chunk. Claude Code interprets each
content_block as a separate text element and renders them on separate
lines, making responses unreadable.
Fix: introduce state.openTextBlockIdx to track an open text block across
chunks. The block is opened on the first text chunk and only closed when:
- switching to a different block type (thinking, tool_use)
- the stream finishes (at finishReason)
All other block types (thinking, tool_use) are still opened+closed per
chunk as before since they are naturally atomic events.
Also: add 'Download opencode.json' button to the Agents dashboard.
The button appears when opencode is detected as installed and generates
a ready-to-use opencode.json config with the OmniRoute provider,
base URL and all models fetched from /v1/models.
fix(test): security-fase01.test.mjs imports inputSanitizer.js → .ts
- The file is TypeScript-only (no compiled .js). Node was failing with
ERR_MODULE_NOT_FOUND in CI because the import path pointed to a
non-existent .js file.
fix(acp): add validateBody(jsonObjectSchema) to POST /api/acp/agents
- Satisfies check:route-validation:t06 lint rule that requires all
routes using request.json() to go through validateBody().
- Uses jsonObjectSchema (passthrough) since body shape varies between
the 'refresh' action and the custom agent creation payload.
- Manual field validation below remains unchanged.
- All 139 routes now pass the route-validation lint check.
fix(deploy-vps): add continue-on-error on SSH step + command_timeout
- SSH connection failures (host unreachable / secrets not set) no
longer mark the workflow run as failed.
- The DEPLOY_ENABLED guard still prevents the job from running when
the variable is not set to 'true'.
- New CLI sidebar section: Tools + Agents
- Move Media to Debug section
- Move Health + Logs to System section
- Move CLI Fingerprint card from Settings > Security to Agents page
- Add cliToolsShort i18n key to all 30 languages
- Add Dashboard > Debug > Agents page: grid of 14 built-in CLI agents
with installation status, version detection, protocol badges
- Add custom agent support: users can register any CLI tool via form
- Expand registry from 5 to 14 built-in agents (aider, opencode, cline,
qwen-code, forge, amazon-q, interpreter, cursor-cli, warp)
- Add 60-second detection cache to avoid repeated execSync calls
- API: GET lists all agents, POST adds custom/refreshes, DELETE removes
- Settings schema: add customAgents array field
- Fix missing themeCoral in settings namespace for all 30 languages
- Add agents sidebar key in all 30 languages
- Add agents page i18n namespace (en + pt-BR)
- Add model playground page to dashboard (provider/model/endpoint selectors, Monaco editor, streaming, abort)
- Add CLI fingerprint matching (per-provider header/body ordering to match native CLI binaries)
- Add ACP module (CLI agent discovery, process spawner, session manager, API endpoint)
- Add playground to sidebar debug section with i18n support
- Close#192 and #200 as stale (v1.8.1, no repro info)
- Add last_used_at column to provider_connections CREATE TABLE schema
- Add ensureProviderConnectionsColumns migration for existing databases
- Add last_used_at to INSERT and UPDATE SQL in providers.ts
- Add last_used_at to JSON migration INSERT in core.ts
- Add zod to serverExternalPackages in next.config.mjs (#217)
Fixes#218: Round-robin routing strategy now correctly persists
the lastUsedAt timestamp, allowing rotation between accounts.
Fixes#217: zod module is now properly included in standalone/Docker
builds by declaring it as a server external package.
- Skip tools with defer_loading=true when assigning cache_control
(Anthropic API rejects the combination with 400)
- Delete stale schemas.js that shadowed the .ts source, causing
missing cloudSyncActionSchema export
Fixes#215
- Fix inverted Claude OAuth utilization (remaining, not used)
- Add hasUtilization() guard to prevent false exhaustion from empty responses
- Centralize anthropic-version into CLAUDE_CONFIG.apiVersion
- Add parseDate() for safe date validation in quota cache
- Batch background refresh with MAX_CONCURRENT_REFRESHES=5
- Move setModelUnavailable to after all accounts exhausted, not first 429
- Extract safePercentage() to shared utils (dedup)
- Use isRecord() type guard in usage API route
- Exclude binary files from Tailwind v4 source scanning
- Move setModelUnavailable from per-account loop to all-accounts-exhausted path
- Clear model unavailability on successful fallback
- Add in-memory quota cache with background refresh (5min active, 20min exhausted)
- Integrate quota cache in account selection to skip exhausted accounts
- Mark accounts as exhausted from 429 when no cached quota data exists
- Populate quota cache from dashboard usage endpoint
- Created httpTransport.ts with singleton MCP server and WebStandard
Streamable HTTP transport running inside Next.js process
- Added /api/mcp/sse route (GET+POST) for SSE transport
- Added /api/mcp/stream route (GET+POST+DELETE) for Streamable HTTP
- Added mcpTransport enum to settingsSchemas (stdio|sse|streamable-http)
- Updated /api/mcp/status to report HTTP transport state
- Added TransportSelector UI with mode buttons and connection URL display
- Routes guard against disabled MCP or wrong transport mode
- Created settingsSchemas.ts with updateSettingsSchema to avoid webpack
tree-shaking the schema from the 908-line schemas.ts barrel file
- Updated settings/route.ts import to use new dedicated file
- Fixed focusRingColor lint error in ServiceToggle
- Added mcpEnabled/a2aEnabled boolean fields to updateSettingsSchema
- Rewrote ServiceToggle as clickable on/off switch with status indicator
- Toggle persists state via PATCH /api/settings
- Both services default to disabled (OFF)