/** * Login orchestration (design: docs/designs/clustly-cli.md §4 "the terminal contract"; * build-plan 3.3). Lazy: `ensureLogin` returns stored credentials or runs the flow. The * fallback ladder is the design's: browser auto-open → printed URL (same machine only) → * device flow (any browser anywhere), with the device switch offered as a live race while * the loopback waits. All effects (browser, fetch, sleep, the [d] signal) are injected — * the sequencing is unit-testable. */ import { type Credentials } from "./credentials"; export interface LoginIO { say(message: string): void; } /** What the user types (then Enter) to switch to the device flow mid-wait. One name, one truth. */ export declare const DEVICE_SWITCH_INPUT = "d"; /** API base (…/v1) + web origin for the authorize/device pages, from CLUSTLY_BASE_URL. */ export declare function resolveBases(env?: NodeJS.ProcessEnv): { apiBase: string; webOrigin: string; }; export interface LoginDeps { home: string; /** API base ending in /v1 (e.g. https://clustly.ai/v1). */ apiBase: string; /** Web origin for the authorize/device pages (apiBase minus /v1). */ webOrigin: string; /** Attempt to open the URL in a browser on THIS machine; false = couldn't. */ openBrowser: (url: string) => Promise; /** Resolves when the user asks for the device flow (the [d] hotkey). */ deviceSwitch?: Promise; forceDevice?: boolean; fetchFn?: typeof fetch; sleep?: (ms: number) => Promise; timeoutMs?: number; } export declare function ensureLogin(deps: LoginDeps, io: LoginIO): Promise; export declare function login(deps: LoginDeps, io: LoginIO): Promise;