/** * Cleo Nexus device logout: `cleo logout nexus [--revoke]` with device * credentials (cleo-nexus device contract §3.5, review M3, T12844). * * A logout never reports success while a credential may still be live: * * 1. Under the lock, the live credentials move into `pendingSignOut` * (`--revoke`: `pendingRevoke`), newest first: `pending`, then `current` * ({@link applyBeginSignOut}, {@link applyBeginRevoke}). From then on they * are used for nothing but that request. The lock is released. * 2. E9 (`POST /v1/devices/self/sign-out`) or E10 (`DELETE /v1/devices/self`) * is sent with each credential in turn, newest first, with one attempt and * a {@link NEXUS_REVOKE_TIMEOUT_MS} timeout. * 3. Done means proved: 200, or a 401 whose reason proves the device state * (`device-signed-out`, `device-revoked`, or `credential-revoked` with * `revokedReason` `signed-out` / `revoked`). A revoke needs proof of a * revoke; a signed-out device is not a revoked one. Any other 401 means * that credential is dead, so the next one is tried. A network error, * timeout, 429, 5xx or a route the server does not have yet stops the run: * the slot is kept and every remaining request is left for the next run * without another call. * 4. The lock is re-taken and the slot is changed only if it still holds the * credential that was answered (compare-and-swap): * - a sign-out (confirmed, or every credential dead) clears * `pendingSignOut` and keeps the device keys for the next login; * - a revoke that ended (confirmed, found the device signed out, or every * credential dead) forgets the device locally ({@link applyForgetDevice}), * so no later login re-activates the id the user asked to burn. The * entry is deleted, or kept stripped while `retired` requests of other * devices remain; the store keeps the file while other entries remain. * Only a confirmed request is reported `confirmed`; the others name the * web remedy. * * Unsettled slots, and the `retired` requests of replaced devices, are * retried by every later logout and, best effort with a shorter timeout, by * `cleo login nexus` and `cleo project link` ({@link retryNexusDeviceEnds}). * Retired requests are sent before the entry's own request. * * No function here logs, and no result or error carries a token. * * @task T12870 * @epic T12323 */ import type { NexusDeviceLogoutResult, NexusDeviceLogoutRow } from '@cleocode/contracts'; import { type FetchLike } from './http.js'; import { type NexusTokenStore } from './nexus-credentials.js'; import { NexusDeviceStore } from './nexus-device.js'; /** * Timeout of each E9/E10 call when a login or a link only retries on the way * ({@link retryNexusDeviceEnds}); an explicit logout uses {@link NEXUS_REVOKE_TIMEOUT_MS}. */ export declare const NEXUS_END_RETRY_TIMEOUT_MS = 2000; /** Options for {@link logoutNexusDevice} and {@link settleNexusDeviceEnds}. */ export interface NexusDeviceLogoutOptions { /** API URL; defaults to `$CLEO_NEXUS_API_URL`, then production. */ apiUrl?: string; /** `fetch` override. */ fetch?: FetchLike; /** The device store; defaults to `/nexus-device.json`. */ deviceStore?: NexusDeviceStore; /** The 9.24 session store (`nexus-credentials.json`). */ store?: NexusTokenStore; /** Clock, for a slot's `requestedAt`. */ now?: () => Date; /** Timeout of each E9 or E10 call; default {@link NEXUS_REVOKE_TIMEOUT_MS}. */ timeoutMs?: number; } /** Options for {@link logoutNexusDevice}. */ export interface NexusDeviceLogoutRunOptions extends NexusDeviceLogoutOptions { /** `--revoke`: hard-revoke the device (E10) instead of signing it out (E9). */ revoke?: boolean; } /** * Retry every unsettled sign-out and revoke on the origin (contract §3.5, * L2): each entry's `pendingSignOut` or `pendingRevoke`, and the `retired` * requests of devices it replaced. Never throws for a server that cannot be * reached; the rows and warnings say what is still open. * * @param opts - API URL, stores and test overrides. * @returns One row per request tried, and the warnings. */ export declare function settleNexusDeviceEnds(opts?: NexusDeviceLogoutOptions & { warnUnreadable?: boolean; }): Promise<{ devices: NexusDeviceLogoutRow[]; warnings: string[]; }>; /** * Best-effort {@link settleNexusDeviceEnds} for flows that only retry on the * way (login, commands that need a credential): a store or network failure * becomes a warning and never fails the caller. * * @param opts - API URL, stores and test overrides. * @param warnings - Receives the warnings. */ export declare function retryNexusDeviceEnds(opts: NexusDeviceLogoutOptions, warnings: string[]): Promise; /** * `cleo logout nexus [--revoke]` with device credentials (contract §3.5, M3). * * Every readable entry on the origin is moved to `pendingSignOut` (or * `pendingRevoke`), then every unsettled request on the origin is sent, * including ones left by earlier runs. A leftover 9.24 session for the origin * is signed out too. The device keys stay after a sign-out, so a later login * reuses the device id; a confirmed revoke removes the entry. * * @param opts - API URL, `revoke`, stores and test overrides. * @returns The per-device outcomes. A row that is not `confirmed` is also * named in `warnings`; the result never claims a sign-out the server did * not confirm. * A device file that cannot be read or locked is reported as a warning, and * the 9.24 session is still signed out. */ export declare function logoutNexusDevice(opts?: NexusDeviceLogoutRunOptions): Promise; //# sourceMappingURL=nexus-logout.d.ts.map