/** * Checking an account's login BEFORE starting a session on it. * * Without this, ccx will happily copy a login that expired hours ago into a new * session and launch, and the first thing you see is Claude saying you are * logged out. That happened for real: an account's stored login had been dead * for five and a half hours, ccx started a session on it and said nothing. * * Two things are wrong with that, and both are fixed here. A login that is * merely expired can usually be renewed, and renewing is SAFE at this exact * moment because we are about to start using the account and nothing else holds * it yet. A login that cannot be renewed is genuinely finished, and the only * useful thing ccx can do is say so, by name, with the command that fixes it, * instead of letting Claude present it as a mysterious sign-out. */ export type LoginReadiness = { state: 'ready'; } | { state: 'renewed'; } | { state: 'needs-login'; detail: string; } | { state: 'unknown'; detail: string; }; export interface PreflightDeps { /** True when the account has a credential with real token material. */ hasLogin: () => boolean; /** True when the stored login is expired, or close enough to be renewed now. */ renewalDue: () => boolean; /** Renew the stored login. Only called when one is present and due. */ renew: () => Promise<{ status: string; detail?: string; }>; } /** * Make sure the account's login is usable, renewing it if that is all it needs. * * Never throws and never blocks a launch: an unknown result still starts the * session, because being unable to check (offline, say) is not evidence that the * login is bad, and refusing to start would be worse than letting Claude try. */ export declare function ensureLoginUsable(deps: PreflightDeps): Promise; /** * What to tell the operator, or null when there is nothing worth saying. * * Deliberately quiet on the ordinary paths: a renewal that worked is normal * housekeeping, and announcing it every time would train people to ignore the * line that actually matters. */ export declare function readinessMessage(account: string, readiness: LoginReadiness): string | null; /** * Can a mid-session switch to this account be done in place? * * Swapping the credential under a running Claude is only safe when the target's * login is usable RIGHT NOW: the swap is synchronous (it happens on the session's * poll) so there is no opportunity to renew anything, and swapping in an expired * login lands the running session on a dead token, which is the same "suddenly * logged out" the pre-flight exists to prevent. * * When the login needs work, the answer is 'restart': ending the child and * relaunching with a resume keeps the same conversation and routes the switch * through the start path, which CAN renew first. */ export declare function swapMode(deps: { hasLogin: () => boolean; renewalDue: () => boolean; }): 'in-place' | 'restart';