- getSettings() auto-sets setupComplete=true when INITIAL_PASSWORD env is set
- proxy.js middleware enforces login when INITIAL_PASSWORD exists (even without DB hash)
- Settings API reports hasPassword=true when INITIAL_PASSWORD is configured
- Login page hides '123456' default hint when a custom password is set
Fixes fresh Docker/VM deployments getting stuck on onboarding wizard
and being accessible without authentication.
- Create shared CliStatusBadge component with support for configured,
not_configured, not_installed, other, and unknown statuses
- Replace inline status badge markup in ClaudeToolCard and ClineToolCard
with the new reusable component
- Add colored status dot indicator alongside badge text
- Support batch status fallback so badges render even when cards are collapsed
- Refactor model/provider selection logic in tool card configuration
- Add GET handler to /api/sync/cloud for real-time status polling
- Rewrite CloudSyncStatus: clickable, event-driven updates, clearer labels
- Add inline status toast with auto-dismiss after enable/disable
- Show success animation in modal before auto-closing
- Dispatch cloud-status-changed event for instant sidebar updates
Add dedicated Costs page combining Budget and Pricing tabs with a
sidebar navigation layout. Improve Health page provider section with
status legend (Healthy/Recovering/Down) and import AI_PROVIDERS
constants for richer provider display.
- Fetch and display request metrics (success rate, latency, total requests) on provider overview cards
- Create /api/provider-metrics endpoint to aggregate stats from request logs
- Add /api/providers/[id]/import-models endpoint to import models from provider's /models API
- Add "Import from /models" button on passthrough provider detail pages
- Include proper PropTypes for new metrics and alias fields
Replace text-based "9" favicon with a network/router node graph design
across all icon sizes. Add apple-touch-icon and icon-192 SVG assets.
Update brand gradient from orange (#f97815) to red (#E54D5E).
Introduce built-in eval system for testing LLM response quality against
golden sets. Includes eval runner with 4 match strategies (exact,
contains, regex, custom), a pre-loaded 10-case golden set, REST API
endpoints for managing and running suites, and a dashboard UI under
Analytics → Evals with real-time progress tracking and pass rate
summaries. Also adds OpenAPI tags for Audio, Moderations, and Rerank.
Extend combo routing with 3 new model selection strategies beyond the
existing priority, weighted, and round-robin options:
- random: Fisher-Yates shuffle for uniform distribution
- least-used: sorts models by request count via comboMetrics
- cost-optimized: sorts models by pricing (cheapest first)
Also enhance the dashboard provider cards with model counts and
clickable detail views for selected providers.
- Add compact ModelAvailabilityBadge with popover for model status
monitoring, cooldown clearing, and auto-refresh polling
- Retheme landing page from warm orange tones to cool blue-grey palette
across FlowAnimation, Footer, and related components
- Update accent color from orange (#f97815) to rose (#E54D5E)
Introduce reusable shared components (Button, Card, Modal, Table,
StatusBadge, EmptyState) and refactor dashboard pages to use them.
Extract client components from server pages, centralize provider
constants, and update CI Node.js matrix from 18 to 20.
initTranslators() is a no-op stub (translators self-register via static
imports). Wrapping the call with Promise.resolve() ensures .then() works
even when the function returns undefined instead of a Promise.
Batch 2 — API Routes:
- /api/cache/stats — GET cache stats, DELETE flush
- /api/models/availability — GET availability report, POST clear cooldown
- /api/telemetry/summary — GET p50/p95/p99 latency metrics
- /api/usage/budget — GET cost summary, POST set budget per key
- /api/fallback/chains — GET/POST/DELETE fallback chain management
- /api/compliance/audit-log — GET filterable audit log
- /api/evals — GET list suites, POST run suite
- /api/evals/[suiteId] — GET suite details
- /api/policies — GET circuit breaker + lockout status, POST force-unlock
Build verified: exit code 0
Only attempt token refresh on 401/403 during connection tests when
the token is actually expired (isTokenExpired). Previously, any 401/403
triggered an aggressive refresh that could overwrite valid tokens when
the upstream returned transient errors (rate-limiting, etc.).
Fixes Cline, Qwen, and iFlow losing authentication after tests.
- Set package.json version to 0.0.1 (initial OmniRoute release)
- Set open-sse/package.json version to 0.0.1
- Restore 'Import from /models' button for standard providers (openai, gemini, deepseek, etc.)
- Add handleImportModels function to ProviderDetailPage
This project is inspired by and originally forked from 9router by decolua
(https://github.com/decolua/9router).
Full rebrand: 9router → OmniRoute across all source code, configuration,
Docker, documentation, and assets.