M1/F1: Kimi Code OAuth device-code flow

Replace the xAI OAuth stack with the Kimi device authorization grant:
- kimi_oauth.rs wire layer (device_authorization + token poll + refresh
  against kigi_env::oauth_host(); client_id per PRD; retryable statuses
  429/5xx with backoff; expired_token restarts authorization)
- X-Msh-Device-{Name,Model,Id} headers; device_id minted uuid4-hex at
  ~/.kigi/device_id (0600)
- Storage: system keyring service `kigi`, entry `oauth/kimi-code`
  (macOS/Windows native backends), atomic-file fallback under ~/.kigi;
  official client's keyring/~/.kimi never touched
- Refresh manager: 60s tick, threshold max(300, expires_in*0.5),
  401-tombstone keyed by rejected refresh token with 300s cooldown and
  rotation auto-clear, cross-process lock with sibling-adoption
  triple-check, sleep/wake forced refresh
- Deleted xAI machinery: enterprise OIDC (PKCE/JWKS/teams), devbox login,
  external auth provider, JWT tier gating + subscription paywall stack,
  X-XAI-Token-Auth marker headers, ZDR gates, /user enrichment
- kigi login / TUI /login both drive the device flow; login-host display
  now derives from kigi_env::oauth_host()
- 264 auth unit/wiremock tests; live contract probe of
  auth.kimi.com/api/oauth/device_authorization matches the wire shapes

Gates: check/clippy --all-targets clean, fmt, deny ok, kigi-shell lib
5131 tests green.
This commit is contained in:
2026-07-17 07:37:29 -04:00
parent d6c20fc13f
commit 021b82443d
117 changed files with 4052 additions and 19900 deletions
+4 -4
View File
@@ -350,16 +350,16 @@ pub async fn run(
let startup_start = std::time::Instant::now();
let raw_config = kigi_shell::config::load_effective_config()
.map_err(|e| anyhow::anyhow!("Failed to load config: {e}"))?;
let grok_com_config = match kigi_shell::agent::config::Config::new_from_toml_cfg(&raw_config) {
Ok(c) => c.grok_com_config,
let kimi_code_config = match kigi_shell::agent::config::Config::new_from_toml_cfg(&raw_config) {
Ok(c) => c.kimi_code_config,
Err(e) => {
tracing::warn!(
error = % e, "failed to parse config for auth refresh, using defaults"
);
kigi_shell::auth::GrokComConfig::default()
kigi_shell::auth::KimiCodeConfig::default()
}
};
let refreshed_auth = kigi_shell::auth::try_ensure_fresh_auth(&grok_com_config).await;
let refreshed_auth = kigi_shell::auth::try_ensure_fresh_auth(&kimi_code_config).await;
let early_prefetch = kigi_shell::agent::models::start_early_prefetch_with_auth(refreshed_auth);
kigi_shell::agent::mvp_agent::warm_async_http_client();
tokio::task::spawn_blocking(|| {});