import type { BrowserContext, Page, CDPSession } from "playwright-core"; import type { WebSocket } from "ws"; import { detectInstalledBrowsers, type BrowserFamily } from "./browser-detect.js"; export interface PortalViewport { width: number; height: number; } export interface PortalSession { id: string; /** Stable identifier — also the filesystem-safe basename for the user-data-dir. */ persistKey: string; context: BrowserContext; page: Page; cdp: CDPSession; viewport: PortalViewport; /** Cached URL — updated on every page.url() change. */ currentUrl: string; /** Pushed to every connected screencast WS. Empty = no clients listening. */ screencastClients: Set; /** Single input client — extra connections are rejected to avoid races. */ inputClient: WebSocket | null; createdAt: number; lastActivityAt: number; browserId: string; browserName: string; browserPath: string; browserFamily: BrowserFamily; /** * Best-effort version string captured from ` --version` at probe * time, e.g. "Google Chrome 147.0.7727.103". Undefined if the binary * didn't expose a version (Safari, missing perms, etc.). */ browserVersion?: string; /** Filesystem path of the Chromium user-data-dir backing this session. */ userDataDir: string; /** Was the underlying Chrome launched headless? false = window minimized in Dock. */ isHeadless: boolean; } export interface CreateSessionOptions { url: string; /** Stable id — used as both the lookup key AND the user-data-dir name. */ persistKey?: string | null; /** Pin a specific browser id (chrome, brave, msedge, …). Defaults to first chromium found. */ browserId?: string; viewport?: PortalViewport; } export declare function createPortalSession(opts: CreateSessionOptions): Promise; export declare function getPortalSession(id: string): PortalSession | undefined; /** Find a session by either its session id or its persistKey. */ export declare function findPortalSession(idOrKey: string): PortalSession | undefined; export declare function listPortalSessions(): Array<{ id: string; url: string; persistKey: string; viewport: PortalViewport; screencastClients: number; hasInput: boolean; createdAt: number; lastActivityAt: number; browserId: string; browserName: string; browserVersion?: string; isHeadless: boolean; }>; export declare function navigatePortalSession(id: string, url: string): Promise; export interface PortalSnapshot { sessionId: string; url: string; title: string; text: string; truncated: boolean; } export declare function getPortalSnapshot(idOrKey: string): Promise; export declare function closePortalSession(id: string): Promise; export declare function closeAllPortalSessions(): Promise; /** * Permanently delete the user-data-dir for a persistKey. Use when the canvas * node is deleted or when the user clicks "Reset login on this node". * * If a session is currently using this persistKey, it's closed first. * Returns the absolute path that was deleted, or null if nothing existed. */ export declare function deletePortalProfile(persistKey: string): Promise; /** List every persisted profile on disk, including ones with no live session. */ export declare function listPortalProfiles(): Promise>; /** * Returns the channel of the first session, or "unknown" if no session is * live. Kept to avoid breaking the existing /portal/sessions response shape. * Per-session info is now the source of truth — see listPortalSessions(). */ export declare function getActiveBrowserChannel(): "chrome" | "msedge" | "chromium" | "unknown"; /** Same backward-compat affordance as getActiveBrowserChannel. */ export declare function getActiveBrowserHeadless(): boolean; export { detectInstalledBrowsers };