/** * Generic OAuth 2.0 Device Authorization Grant (RFC 8628) flow runner. * * Implements the two-step device-code protocol: * 1. POST to the device authorization endpoint → receive `device_code`, * `user_code`, `verification_uri`, `expires_in`, `interval`. * 2. Poll the token endpoint every `interval` seconds until the user * approves, the code expires, or a non-recoverable error is returned. * * ## Provider scope * * Device-code OAuth is used by **kimi-code** only. Anthropic uses RFC 7636 * PKCE (see `pkce.ts` and `builtin/anthropic.ts`). The `anthropic` preset * was removed in T9326 — PKCE is the canonical Anthropic OAuth path per T9302. * * @module llm/oauth/device-code * @task T9321 * @epic T9261 T-LLM-CRED-CENTRALIZATION */ /** * Configuration for a device-code OAuth flow. * * All URLs and client credentials are provider-specific; callers can pass * a preset from `getDeviceCodeConfig()` or build a custom config for any * provider that supports RFC 8628. */ export interface DeviceCodeConfig { /** Provider name (used only for logging / error messages). */ provider: 'kimi-code' | string; /** * Device authorization endpoint (RFC 8628 §3.1). * * POST with `client_id` (and optionally `scope`) → returns * `device_code`, `user_code`, `verification_uri`, etc. */ deviceCodeUrl: string; /** * Token polling endpoint. * * POST with `grant_type=urn:ietf:params:oauth:grant-type:device_code`, * `client_id`, and `device_code`. */ tokenUrl: string; /** OAuth client ID registered with the provider. */ clientId: string; /** Space-separated OAuth scopes to request. Optional. */ scope?: string; /** * Additional HTTP headers to include on every request. * * Used to pass provider-specific versioning headers (e.g. Anthropic's * `anthropic-version`). */ defaultHeaders?: Record; } /** * Response from the device authorization endpoint (RFC 8628 §3.2). */ export interface DeviceCodeStartResponse { /** Opaque device code used when polling the token endpoint. */ deviceCode: string; /** * Short, human-readable code the user enters at `verificationUri`. * * Typically 8 characters (e.g. `ABCD-1234`). */ userCode: string; /** URL the user should visit to enter `userCode`. */ verificationUri: string; /** * Complete verification URI with the user code pre-filled. * * Not all providers return this field; falls back to `verificationUri` * when absent. */ verificationUriComplete?: string; /** Seconds until the device code + user code expire. */ expiresIn: number; /** Minimum polling interval in seconds (RFC 8628 §3.2). */ interval: number; } /** * Successful token response from the device-code polling endpoint. */ export interface DeviceCodeTokenResponse { /** Bearer access token. */ accessToken: string; /** * Refresh token (if the provider returns one). * * Not all providers include a refresh token in the device-code flow. * When present, callers SHOULD store it for later token refresh. */ refreshToken?: string; /** Seconds until `accessToken` expires. `undefined` when not provided. */ expiresIn?: number; /** Token type (virtually always `'bearer'`). */ tokenType: string; } /** * Thrown by `pollForToken` when the device code expires before the user * approves the request. */ export declare class DeviceCodeTimeoutError extends Error { readonly provider: string; readonly elapsed: number; constructor(provider: string, elapsed: number); } /** * Thrown by `pollForToken` when the provider returns an unrecoverable error * (anything other than `authorization_pending` or `slow_down`). */ export declare class DeviceCodeAuthError extends Error { readonly provider: string; readonly errorCode: string; constructor(provider: string, errorCode: string, description: string); } /** * Build a `DeviceCodeConfig` for a named provider. * * Currently only `'kimi-code'` is wired. Anthropic uses PKCE, not * device-code — see `pkce.ts` and `builtin/anthropic.ts`. * * @throws {Error} When `provider` is not a known preset. */ export declare function getDeviceCodeConfig(provider: 'kimi-code' | string): DeviceCodeConfig; /** * Build the `DeviceCodeConfig` for Kimi Code (kimi.com/code). * * Authentication endpoints are hosted at `auth.kimi.com` (override via * `KIMI_CODE_OAUTH_HOST` env var). The shared community client ID is reused * by kimi-cli and other integrations — no private registration required. * * Token lifecycle: * - Access token: ~15 minutes * - Refresh token: ~30 days * - Recommended refresh strategy: 50% of lifetime or 300s, whichever is larger * * After OAuth completes, the resulting bearer token targets * `https://api.kimi.com/coding` (Anthropic Messages protocol). The six * mandatory `X-Msh-*` headers — built by {@link getKimiCodeMshHeaders} — MUST * be merged into every chat request alongside the bearer token. * * @returns Device-code configuration for Kimi Code OAuth. * * @task T9321 * @epic T9261 T-LLM-CRED-CENTRALIZATION * @see https://github.com/gsd-build/gsd-2/issues/4642 — design reference * @see MoonshotAI/kimi-cli `src/kimi_cli/auth/oauth.py` — protocol reference */ export declare function getKimiCodeDeviceCodeConfig(): DeviceCodeConfig; /** * Start the device-code OAuth flow. * * POSTs to `cfg.deviceCodeUrl` with the client ID and optional scope. On * success returns the structured response that the CLI prints to the user * (`userCode`, `verificationUri`, etc.) and that `pollForToken` needs to * poll with. * * @throws {Error} On HTTP errors or a response that is missing required fields. */ export declare function startDeviceCodeFlow(cfg: DeviceCodeConfig): Promise; /** * Poll the token endpoint until the user approves, the code expires, or an * unrecoverable error is received (RFC 8628 §3.4). * * Handles the two recoverable error codes: * - `authorization_pending` — user has not yet approved; continue polling. * - `slow_down` — increase the polling interval by 1 second, then continue. * * Network errors are retried up to `MAX_NETWORK_RETRIES` times before being * re-thrown. * * @param cfg - Device-code flow configuration (same object as passed to * `startDeviceCodeFlow`). * @param startResp - The response returned by `startDeviceCodeFlow`. * @param options.onPending - Optional callback invoked on each pending poll * iteration with `(elapsedSeconds, totalExpiresIn)`. Used by the CLI to * print a live progress counter. * @param options.signal - Optional `AbortSignal` for cooperative cancellation. * * @throws {DeviceCodeTimeoutError} When `expiresIn` is reached without approval. * @throws {DeviceCodeAuthError} When the provider returns a non-recoverable error. * @throws {Error} When network retries are exhausted. */ export declare function pollForToken(cfg: DeviceCodeConfig, startResp: DeviceCodeStartResponse, options?: { onPending?: (elapsed: number, expiresIn: number) => void; signal?: AbortSignal; }): Promise; //# sourceMappingURL=device-code.d.ts.map