/** * Codex / "Sign in with ChatGPT" — the OAuth wire protocol, in one place. * * This existed three times: the CLI terminal flow * (`packages/cli/src/auth-menu/openai-codex-oauth.ts`), the headless WebUI * flow (`./chatgpt.ts`), and the runtime provider's refresh path * (`../openai-codex.ts`, whose header said in as many words "mirror packages/cli * auth-menu/openai-codex-oauth"). Three copies of the same client id, token * endpoint, request bodies, and response validation. * * That is not a style problem. The abort-listener leak fixed in 2026-08 was * present in two of the three copies and absent from the one that had already * been corrected — the copies drift silently because nothing makes them agree. * A rotated client id or a changed token-endpoint contract would have to be * found and applied three times, and being wrong in one of them means one * surface silently stops authenticating. * * Placement: `oauth/` rather than beside the provider, and deliberately free of * any import from `../openai-codex.js`. `openai-codex-account.ts` was already * split out so the OAuth entry could derive an account id "without bundling the * whole Codex provider"; this module keeps that direction — the provider * imports the protocol, never the reverse. Model discovery lives separately in * `./codex-models.ts` so the provider does not pull the models catalog in just * to refresh a token. * * @module oauth/codex-protocol */ export declare const CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"; export declare const CODEX_AUTH_BASE_URL = "https://auth.openai.com"; export declare const CODEX_AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize"; export declare const CODEX_TOKEN_URL = "https://auth.openai.com/oauth/token"; export declare const CODEX_REDIRECT_PORT = 1455; export declare const CODEX_FALLBACK_REDIRECT_PORT = 1457; export declare const CODEX_REDIRECT_HOST = "127.0.0.1"; export declare const CODEX_REDIRECT_PATH = "/auth/callback"; export declare const CODEX_SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke"; /** Telemetry/branding tag sent to authorize + as a request header. Free-form. */ export declare const CODEX_ORIGINATOR = "wrongstack"; /** Canonical provider id under which ChatGPT-login credentials are stored. */ export declare const CODEX_PROVIDER_ID = "openai-codex"; /** Default ChatGPT backend base. The wire family appends `/codex/responses`. */ export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api"; export declare function codexRedirectUri(port: number): string; /** Build the full authorize URL with all Codex-required query params. */ export declare function buildCodexAuthorizeUrl(challenge: string, state: string, port?: number): string; export interface CodexTokens { access: string; refresh: string; /** Absolute expiry in epoch milliseconds. */ expires: number; idToken?: string | undefined; } /** * Validate a token-endpoint response into {@link CodexTokens}. * * The real status is preserved on the thrown {@link FetchError}: `recoverable` * is derived from it (429/5xx → true), so collapsing a transient 503 into a * fixed 401 made callers drop the credential and force a re-login instead of * retrying. The provider's own copy of this had already learned that; the * shared version keeps the lesson. */ export declare function readCodexTokenResponse(res: Response, op: string): Promise; /** Exchange an authorization code (+ PKCE verifier) for tokens. */ export declare function exchangeCodexAuthorizationCode(code: string, verifier: string, signal?: AbortSignal, port?: number): Promise; /** * Refresh an expired access token using the stored refresh token. Codex * rotates the refresh token on every refresh, so the caller must persist the * returned `refresh` value, not the one it passed in. */ export declare function refreshCodexTokens(refreshToken: string, signal?: AbortSignal): Promise; //# sourceMappingURL=codex-protocol.d.ts.map