diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57ce635..443913c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,16 @@
---
+## [v0.50.7] OAuth provider onboarding path — Codex/Copilot no longer blocks setup (PR #331, fixes #329 bug 2)
+
+- **OAuth providers now have a proper onboarding path** (closes bug 2): Users with `openai-codex`, `copilot`, `qwen-oauth`, or any other OAuth-authenticated provider now see a clear confirmation card instead of an unusable API key input form.
+ - If already authenticated (`chat_ready: true`): blue "Provider already authenticated" card with a direct Continue button — no key entry required.
+ - If not yet authenticated: amber card explaining how to run `hermes auth` or `hermes model` in a terminal to complete setup.
+ - Either state includes a collapsible "switch provider" section for users who want to move to an API-key provider instead.
+ - `_build_setup_catalog` now includes `current_is_oauth` boolean; fixed a latent `KeyError` crash when looking up `default_model` for OAuth providers.
+ - 5 new i18n keys in English and Spanish (`onboarding_oauth_*`).
+ - 15 new tests in `tests/test_sprint40.py`; 791 tests total (up from 776)
+
## [v0.50.6] Skip-onboarding env var + synchronous API key reload (PR #330, fixes #329 bugs 1+3)
- **`HERMES_WEBUI_SKIP_ONBOARDING=1`** (closes bug 1): Hosting providers can set this env var to bypass the first-run wizard entirely. Only takes effect when `chat_ready` is also true — a misconfigured deployment still shows the wizard. Accepts `1`, `true`, or `yes`.
diff --git a/api/onboarding.py b/api/onboarding.py
index caabbb8..ae8ae8d 100644
--- a/api/onboarding.py
+++ b/api/onboarding.py
@@ -362,13 +362,23 @@ def _build_setup_catalog(cfg: dict) -> dict:
}
)
+ # Flag whether the currently-configured provider is OAuth-based (not in the
+ # API-key flow). The frontend uses this to show a confirmation card instead
+ # of a key input when the user has already authenticated via 'hermes auth'.
+ current_is_oauth = current_provider not in _SUPPORTED_PROVIDER_SETUPS and bool(
+ current_provider
+ )
+
return {
"providers": providers,
"unsupported_note": _UNSUPPORTED_PROVIDER_NOTE,
+ "current_is_oauth": current_is_oauth,
"current": {
"provider": current_provider,
"model": current_model
- or _SUPPORTED_PROVIDER_SETUPS[current_provider]["default_model"],
+ or _SUPPORTED_PROVIDER_SETUPS.get(current_provider, {}).get(
+ "default_model", ""
+ ),
"base_url": current_base_url,
},
}
diff --git a/static/i18n.js b/static/i18n.js
index 62a140c..57e8a6c 100644
--- a/static/i18n.js
+++ b/static/i18n.js
@@ -237,6 +237,11 @@ const LOCALES = {
onboarding_missing_imports: 'Missing imports:',
onboarding_notice_setup_required: 'Choose a simple provider path here. Advanced OAuth flows still belong in the Hermes CLI for now.',
onboarding_notice_setup_already_ready: 'A working Hermes provider setup is already detected. You can keep it or replace it here.',
+ onboarding_oauth_provider_ready_title: 'Provider already authenticated',
+ onboarding_oauth_provider_ready_body: 'This instance is configured to use an OAuth provider ({provider}) that was set up via the Hermes CLI. No API key is needed here — click Continue to finish setup.',
+ onboarding_oauth_provider_not_ready_title: 'OAuth provider not yet authenticated',
+ onboarding_oauth_provider_not_ready_body: 'This instance is configured to use {provider}, which uses OAuth rather than an API key. Run hermes auth or hermes model in a terminal to authenticate, then reload the Web UI.',
+ onboarding_oauth_switch_hint: 'Or choose a different provider below to switch to an API-key setup:',
onboarding_notice_workspace: 'These values reuse the same settings APIs as the normal app.',
onboarding_workspace_label: 'Workspace',
onboarding_workspace_or_path: 'Or enter a workspace path',
@@ -497,6 +502,11 @@ const LOCALES = {
onboarding_missing_imports: 'Importaciones faltantes:',
onboarding_notice_setup_required: 'Elige aquí una ruta simple de proveedor. Los flujos OAuth avanzados siguen siendo del CLI de Hermes por ahora.',
onboarding_notice_setup_already_ready: 'Ya se detectó una configuración funcional del proveedor de Hermes. Puedes conservarla o reemplazarla aquí.',
+ onboarding_oauth_provider_ready_title: 'Proveedor ya autenticado',
+ onboarding_oauth_provider_ready_body: 'Esta instancia está configurada para usar un proveedor OAuth ({provider}) configurado mediante la CLI de Hermes. No se necesita clave API aquí — haz clic en Continuar para finalizar la configuración.',
+ onboarding_oauth_provider_not_ready_title: 'Proveedor OAuth no autenticado aún',
+ onboarding_oauth_provider_not_ready_body: 'Esta instancia está configurada para usar {provider}, que utiliza OAuth en lugar de una clave API. Ejecuta hermes auth o hermes model en una terminal para autenticarte y recarga la interfaz web.',
+ onboarding_oauth_switch_hint: 'O elige un proveedor diferente a continuación para cambiar a la configuración con clave API:',
onboarding_notice_workspace: 'Estos valores reutilizan las mismas APIs de configuración que la app normal.',
onboarding_workspace_label: 'Espacio de trabajo',
onboarding_workspace_or_path: 'O introduce la ruta de un espacio de trabajo',
diff --git a/static/index.html b/static/index.html
index 4890cd2..b399d5a 100644
--- a/static/index.html
+++ b/static/index.html
@@ -526,7 +526,7 @@