/** * CLI Authentication Module * * Browser-based poll approval flow (see login() below): * 1. POST ${CP}/auth/cli-request → { requestId, pollSecret } * 2. Open browser to ${LANDING_URL}/cli?request= * 3. User signs in via Better Auth + picks a pod → browser POSTs the approval * 4. CLI polls GET ${CP}/auth/cli-request/ with the pollSecret until * the credential payload (session token + pod) comes back * 5. CLI stores it in ~/.synap/credentials.json * * (waitForPodCallback below still uses a localhost server — that's the separate * managed-pod provisioning path, not login.) */ export interface StoredCredentials { token: string; expiresAt: string; userId: string; email: string; /** ID of the pod the user chose during the web auth flow (optional). */ podId?: string; /** URL of the pod the user chose during the web auth flow (optional). */ podUrl?: string; } export declare function getStoredToken(): StoredCredentials | null; /** True if local expiry timestamp has passed (does NOT call the server). */ export declare function isTokenLocallyExpired(creds: StoredCredentials): boolean; export declare function logout(): void; export declare function isLoggedIn(): Promise<{ valid: boolean; email?: string; userId?: string; }>; /** * Store a manually provided API token (Better Auth session token). * Validates against the CP before saving. * * Usage: synap login --token * Get a token from: https://synap.live/account/tokens */ export declare function loginWithToken(token: string): Promise; /** * Browser login via the CP poll-based approval flow. * * 1. POST /auth/cli-request → { requestId, pollSecret }. * 2. Open the browser at `${LANDING_URL}/cli?request=` — the user signs in * and picks a pod, which POSTs the approval to the CP. * 3. Poll GET /auth/cli-request/ with the pollSecret until the CP returns * the credential payload (session token + chosen pod). * * No localhost server, no https→http redirect: the three fragile hops of the * old flow are gone. Returns null on timeout/denied/failure (callers surface * their own message), preserving the previous contract. * * The BROWSER host is a CLI concern, owned by `LANDING_URL` (default * synap.live, env-overridable) — NOT the CP's `approveUrl`. The CP builds that * from its own FRONTEND_URL, which is the ADMIN dashboard (dashboard.synap.live), * the wrong place to send a user. We take only the `requestId` from the CP and * build the landing URL ourselves, exactly as the old flow owned LANDING_URL. */ export declare function login(): Promise; export interface PodCallbackResult { podUrl: string; workspaceId?: string; } export declare function waitForPodCallback(timeoutMs?: number): Promise; export declare function getCpUrl(): string; export interface Pod { id: string; subdomain: string; customDomain: string | null; status: string; region: string; url: string; } export declare function listPods(token: string): Promise; /** * Get the remote OpenClaw provisioning status from the CP. * Returns null if not provisioned or on network error. */ export declare function getOpenClawRemoteStatus(cpToken: string, podId: string): Promise<{ status: "not_provisioned" | "provisioning" | "running" | "error"; url: string | null; } | null>;