Source of truth:
crates/auth/src/lib.rscrates/auth/src/token_store.rscrates/auth/src/oauth/*crates/cli/src/main.rs(login,logout,whoami)crates/tui/src/app.rs+crates/tui/src/input.rs(/connect)
For interactive use, default to:
qvl->/connect
/connect opens provider selection and then uses:
- OAuth when available
- API key entry as fallback
CLI fallback remains:
qvl login [provider]qvl login status(alias forqvl whoami)
resolve_credential(provider, config_key) resolves in this order:
- provider
api_keyfrom config ([provider.<id>].api_key) - provider env var (
OPENAI_API_KEY, etc.) - stored token/account from local token store
If no credentials are found:
- error includes expected env var name
- OAuth-capable providers include hint to use
/connector runqvl login <provider>
resolve_credential_async follows similar precedence, but can refresh OAuth token via oauth::refresh::refresh_if_needed before fallback to stored token.
qvl login [provider]
qvl login status
qvl logout <provider>
qvl whoamiBehavior:
loginwithout provider shows built-in provider pickerlogin statusis a compatibility alias forwhoami- OAuth is attempted for OAuth-capable providers
- API key prompt is used when OAuth is unavailable or fails
logoutremoves stored token entries for providerwhoamiprints status for built-ins plus custom configured providers
auth_status(provider) returns:
envwhen env var is availableconnectedwhen token/account exists in storenot connectedotherwise
Token storage is JSON-based (auth.json) and supports multi-account per provider.
Important structures:
StoredToken:access_tokenrefresh_tokenexpires_atprovider
AccountEntry:labeltokenactiverate_limited_until
Capabilities:
- active-account selection
- labeled account storage
- account listing/removal
- rate-limit rotation (
rotate_on_rate_limit)
handle_rate_limit(provider) attempts rotation to another account for 60 seconds.
If another account is available:
- active account is marked rate-limited
- next eligible account becomes active
- credential is returned to runtime
If no eligible fallback account exists:
- returns
None
- auth store:
<data_local_dir>/quavil/auth.json- typically
~/.local/share/quavil/auth.json(platform dependent)
- typically
- migration from legacy keyring entries exists for selected providers
Provider env vars are defined in BUILT_IN_PROVIDERS (crates/config/src/lib.rs), including:
OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEYCURSOR_API_KEYGITHUB_COPILOT_TOKENOPENROUTER_API_KEYGROQ_API_KEYTOGETHER_API_KEYDEEPSEEK_API_KEYOLLAMA_API_KEYMOONSHOT_API_KEYMINIMAX_API_KEYZHIPU_API_KEY- provider-specific coding-plan variants
See docs/providers.md for full provider metadata.
qvl logout <provider>clears local stored token entries for that provider.- Do not commit config files containing
api_key. - Prefer environment variables or OAuth token storage for shared repositories.