v1.55.3
[1.55.3] — 2026-05-19
feat(onboarding): on-screen 4-provider OR status — cold-start banner + active-provider chip (UX-2, HIGH).
✨ Features
- New read-only endpoint
GET /api/status/providers→{ activeProvider, activeModel, keysConfigured }.keysConfigureduses the same effective-env view as thellm.mjsgate sites (process.env ∨ parent.env, viahasAnthropicKey/hasGeminiKey/hasOpenAIKey/hasQwenKey);activeProvideris what the OR-router would actually pick —selectActiveProvider(), a new pure helper inenv-config.mjsthat walksproviderOrder()(so anLLM_PROVIDERpin with no matching key correctly yieldsnull). No secrets are returned — only provider names + the model id. - The SPA shell now renders a global onboarding region (
#onboarding-banner, populated byapp.jsfrom that endpoint, CSP-safe DOM only): 0 keys → a red banner "No LLM key set — '⚡ Run live' is in manual-prompt mode…" with a CTA deep-linking to#/config?tab=api-keys; ≥1 key → a subtle chip naming the active provider + model (e.g. Live eval: OpenAI (gpt-5-codex)). It re-evaluates on locale change and when the user navigates away from the config tab (keys may have just been saved). This makes the product's headline differentiator — "one of Anthropic / Gemini / OpenAI / Qwen works, auto-ordered" — discoverable on screen instead of learned by trial. - New i18n keys
onboarding.noKey.title,onboarding.noKey.cta,onboarding.activeProvideracross all 8 locales; new.onboarding-warn/.onboarding-okCSS (token-based, mirrors.conn-banner).
🧪 Tests
test: tests/onboarding-key-banner.test.mjs(new, 9 cases, CI-isolated):selectActiveProviderauto-order / none /LLM_PROVIDER-pin semantics;GET /api/status/providersin-process (ephemeral port + tempCAREER_OPS_ROOT.envso the real parent key is never read — CLAUDE.md #2/#8) for 0-key, 1-key+model, and Anthropic-over-Gemini auto order; static SPA wiring (banner host, endpoint fetch,#/config?tab=api-keysCTA) +onboarding.*×8 locale coverage. 764 → 773.