/**
 * PendingLoginStore — durable record of in-flight subscription logins (P2.1 of
 * the Subscription & Auth Standard, the mobile-first enrollment wizard).
 *
 * When the operator enrolls an account from their phone, the login is a
 * short-lived artifact: a device-code (Codex: `auth.openai.com/codex/device` +
 * a 9-char code, ~15min TTL) or a URL+paste-back-code flow (Claude). The pi
 * live-test exposed the gap this closes: the first code expired before the
 * operator got to it, the provider's error was opaque, and re-issuing required a
 * manual round-trip. This store makes pending logins durable + TTL-aware so the
 * wizard can:
 *   - surface a code/URL IMMEDIATELY with its TTL visible,
 *   - detect expiry and re-issue a fresh one WITHOUT the operator asking,
 *   - present a "Pending Logins" surface where a fresh code is one tap away.
 *
 * It stores NO credential — only the public device-code / auth URL the provider
 * shows, which the operator types into the provider's own page. The actual login
 * happens against the provider, never through instar (Secret-Drop discipline).
 *
 * File-backed JSON (atomic tmp+rename), mirrors the SubscriptionPool durable-
 * registry pattern. The re-issue mechanism (re-driving the framework login) is
 * the wizard's concern + injected, so this store stays pure + hermetically
 * testable (no spawning, no network).
 */
export type LoginFlowKind = 'device-code' | 'url-code-paste';
export type LoginProvider = 'openai' | 'anthropic' | 'github-copilot' | 'google';
/**
 * Pending-login lifecycle:
 *   pending   — code/URL issued, awaiting the operator's approval at the provider
 *   expired   — TTL elapsed before approval (eligible for auto-reissue)
 *   completed — the operator approved + the account enrolled
 *   abandoned — operator/admin cancelled, or superseded by a re-issue
 */
export type PendingLoginStatus = 'pending' | 'expired' | 'completed' | 'abandoned';
export interface PendingLogin {
    /** Stable id, charset ^[a-z0-9-]+$. */
    id: string;
    /** Operator-facing label / intended account nickname. */
    label: string;
    provider: LoginProvider;
    framework: 'claude-code' | 'codex-cli' | 'gemini-cli' | 'pi-cli';
    kind: LoginFlowKind;
    /** The new account's CLAUDE_CONFIG_DIR (a filesystem path, never a secret) —
     *  recorded so an auto-reissue re-drives the login under the SAME slot. */
    configHome?: string;
    /** The public verification URL the operator opens (never a secret). */
    verificationUrl: string;
    /** Device-code (e.g. "7DAU-W4XJA") for device-code flows; absent for url-code-paste. */
    userCode?: string;
    /** Operator-facing heads-up about this flow's quirks (never a secret) — e.g. the
     *  Claude two-code sequence (email-verification code first, then the sign-in code).
     *  Surfaced on the pending-login so the operator knows what to expect. */
    notice?: string;
    /** WS5.2 §5.3/S7 — the account email the operator EXPECTED to enroll (the mandate's
     *  account). On a follow-me completion the freshly-minted login's email is validated
     *  against this before the account becomes selectable; a surprise email is held, not
     *  auto-used. Absent for a plain (non-follow-me) enrollment. Never a secret. */
    expectedEmail?: string;
    /** ISO timestamp the code/URL expires. */
    ttlExpiresAt: string;
    status: PendingLoginStatus;
    /** How many times this login has been re-issued after expiry. */
    reissueCount: number;
    createdAt: string;
    updatedAt: string;
    /** Monotonic version for optimistic CAS. */
    version: number;
}
export interface PendingLoginStoreConfig {
    stateDir: string;
    /** Injectable clock (ms epoch) for deterministic TTL tests. */
    now?: () => number;
}
export interface IssueLoginInput {
    id: string;
    label: string;
    provider: LoginProvider;
    framework: PendingLogin['framework'];
    kind: LoginFlowKind;
    configHome?: string;
    verificationUrl: string;
    userCode?: string;
    /** Operator-facing flow heads-up (e.g. the Claude two-code sequence). */
    notice?: string;
    /** WS5.2 §5.3/S7 — the operator-expected account email (a follow-me login carries it
     *  so completion can validate the minted account against operator expectation). */
    expectedEmail?: string;
    /** TTL in ms from now (default 15 min — the observed Codex device-code TTL). */
    ttlMs?: number;
}
export declare class ValidationError extends Error {
    constructor(message: string);
}
export declare class PendingLoginStore {
    private storePath;
    private store;
    private readonly now;
    constructor(config: PendingLoginStoreConfig);
    /** All pending logins, with live status (expiry computed against the clock). */
    list(): PendingLogin[];
    get(id: string): PendingLogin | null;
    /** Logins that are expired (TTL elapsed) but not completed/abandoned — the
     *  auto-reissue work-list. */
    expired(): PendingLogin[];
    /** Active (still-valid, awaiting-approval) logins — the "Pending Logins" surface. */
    active(): PendingLogin[];
    size(): number;
    /** Issue a new pending login. Stores the public URL/code only — never a token. */
    issue(input: IssueLoginInput, rawExtra?: Record<string, unknown>): PendingLogin;
    /**
     * Re-issue an expired (or pending) login with a fresh URL/code + TTL — the
     * auto-reissue path. Bumps reissueCount, resets status to pending. Returns null
     * if not found.
     */
    reissue(id: string, fresh: {
        verificationUrl: string;
        userCode?: string;
        ttlMs?: number;
    }): PendingLogin | null;
    /** Mark a login completed (the operator approved + the account enrolled). */
    complete(id: string): PendingLogin | null;
    /** Cancel a login (operator/admin). */
    abandon(id: string): PendingLogin | null;
    private transition;
    /** Computes live `expired` status from the TTL without mutating the store
     *  (pending → expired when past TTL; completed/abandoned are terminal). */
    private withLiveStatus;
    private assertNoCredentialFields;
    private load;
    private save;
}
//# sourceMappingURL=PendingLoginStore.d.ts.map