// driver / runner abstraction for rnx. browser sims run in an isolated // playwright-owned profile. electron remains the native desktop surface. export type DriverId = 'electron' | 'playwright' // broad category for grouping / filtering. "native" is the electron host; // "automation" is the isolated playwright browser. export type DriverKind = 'native' | 'automation' export interface DriverAvailability { // true when the driver can attempt a launch on this machine. a driver is // allowed to be available but still fail at runtime (network issues, // permission denied, ...). false when there's a hard precondition missing // (binary not installed, package not resolvable). available: boolean // short free-text explaining why a driver is unavailable. null when // `available` is true, or when no reason is known. reason: string | null // optional human-readable detail shown in verbose listings — e.g. the // resolved binary path, version string, or install location. detail?: string } export interface DriverLaunchOptions { // shell URL to load in the launched process. optional because the electron // driver can launch the companion app with // no URL (it picks its last window). other drivers return launched:false // with a helpful message when url is missing. url?: string // run in headless mode where the driver supports it. ignored by electron. headless?: boolean // initial device model seed forwarded to the rnx shell. the electron // driver forwards it via argv (--device=); browser drivers receive // it already stamped on the URL (?device=) by runOpenCommand. device?: string // page viewport for browser-based drivers. runOpenCommand sizes this from // the device profile (device pt size + frame chrome) so the sim isn't // letterboxed inside playwright's 1280x720 default. viewport?: { width: number; height: number } // let the caller override the port used in availability / attach // heuristics. most drivers don't need this. port?: number // when true, the launch is detached from the parent process and the // CLI returns immediately. default true. detached?: boolean // named persistent storage profile. honored by drivers that own their // browser context (electron, playwright). plain browser tabs reject it. profileId?: string // unnamed temporary storage. honored by electron/playwright. ephemeralProfile?: boolean // stable pid for the session that owns a CLI-opened host. electron closes // only that session's windows when the owner exits; playwright requires it // so a detached browser can never outlive its session. omitted only for the // persistent `rnx desktop` app lifecycle. ownerPid?: number // expose Chrome's remote-debugging endpoint on this port so a // bridge-driven sim can also be cpu-profiled. only the playwright driver // honors it (launches Chromium with --remote-debugging-port). cdpPort?: number // maximum time the detached host should wait for the launched sim to // register with the bridge before it tears itself down. connectTimeoutMs?: number // the rnx WS bridge port the launched sim page should register with, // injected as window.__sootsimBridgePort. load-bearing when the dev bridge // drifted off the shell-port-implied default (e.g. :7668 taken at the shell's // boot -> bridge on :7669 while the shell kept :5173): the page's own // shell-port heuristic would compute the stale :7668 and never connect. bridgePort?: number } export interface DriverLaunchResult { // true when the process was successfully spawned. launched: boolean // free-text describing what happened, used for CLI output and skill docs. message: string // optional handle details — currently free-shaped so each driver can // expose what makes sense for its environment. pid for spawned processes, // `target` for an install path, `attachUrl` for automation drivers. pid?: number target?: string attachUrl?: string connectAckFile?: string diagnosticLogPath?: string } export interface Driver { id: DriverId // short human name shown in `rnx list --drivers`. name: string // one-line description. keep under 80 chars so the list command reads // nicely at default terminal width. description: string kind: DriverKind // probe the host environment for this driver. cheap and synchronous — // anything expensive belongs in `launch`. availability(): DriverAvailability // start the driver pointed at `opts.url`. may be async because some // drivers (electron, playwright) do real I/O. must never throw on a // benign "not installed" condition — return { launched: false } with a // helpful message instead. launch(opts: DriverLaunchOptions): Promise }