- Add PerGatewayUsage interface and buildPerGatewayUsage() function
- Each gateway's most constrained limit shown independently, sorted by exhaustion
- Per-account rows render BEFORE aggregate summary
- Aggregate cards labeled 'Combined' when multiple gateways exist
- 'Soonest reset' and 'Combined limit' labels replace misleading single-gateway labels
- Filter out gateways with no configured limit to reduce noise
- Add typed limit fields to RuntimeUsageCurrent: output_token_limit,
total_token_limit, message_limit with matching pct and source
- Add total_output_tokens and output_tokens_per_minute to burn rate
- _build_current() now computes each pct from matching units only
- Legacy token_limit backfilled from typed limits for backwards compat
- Frontend aggregateRuntimeUsage() tracks typed limits separately
- limit_kind field on predictions indicates which limit drove time-to-limit
- Add source and confidence fields to RuntimeUsageWindow, ModelUsageEntry,
TopSession, RuntimeUsageCurrent, and ProviderUsageScrapeResult schemas
- _build_window() assigns source based on data origin:
provider_native > provider_api_rate_limit > local_jsonl_estimate
- _build_current() tags token_limit_source and cost_limit_source
- Frontend relabels 'Current session'/'All models' to 'API rate limit'
- Shows source label and confidence in usage strip
- Changes 'did not return active usage windows' to 'did not return
API rate-limit windows for percent + reset diagnostics'
The column was NOT NULL but the ORM create path doesn't populate it
until ensure_main_agent() runs after INSERT. Make it nullable so the
initial create succeeds.
- Switched from Docker named volume to bind mount ./data/postgres
- DB data persists on disk across rebuilds (no more re-inputting keys)
- Added data/ to .gitignore
- Updated docker-test.sh docs to reflect bind mount
- Included uncommitted ai-providers page changes
Local auth was using getLocalAuthToken() which only checks in-memory
and sessionStorage — both unavailable during SSR. The env token
(NEXT_PUBLIC_LOCAL_AUTH_TOKEN) was defined but never called in the
auth flow. Now useAuth, hasLocalAuthToken, and customFetch all fall
back to getEnvToken() so SSR correctly identifies the local user as
signed in and admin.