/**
 * Playwright Chromium bootstrap for server deploys.
 *
 * `inspect_artifact` and the artifact PDF/PNG export render through Playwright's
 * Chromium. A bare Node host (e.g. the Railway `node:20` image) ships neither the
 * Chromium browser nor the OS libraries it needs, so those tools fail with
 * "Install the Playwright Chromium runtime with: npx playwright install chromium".
 *
 * This ensures the runtime is present WITHOUT blocking server startup:
 *   - Opt-in via `STUDIOGRAPH_INSTALL_PLAYWRIGHT=1` (the deploy sets it; local
 *     `studiograph serve` stays lean and never downloads ~150MB unprompted).
 *   - PROBE-FIRST: boot runs a real `chromium.launch()` probe. When the browser
 *     binary AND its OS libraries are already present (persistent
 *     `PLAYWRIGHT_BROWSERS_PATH` volume + an image with the deps baked in, e.g.
 *     `mcr.microsoft.com/playwright`), the install is skipped entirely — no apt
 *     churn, no downloads, ready in seconds. The probe is the only honest check
 *     for the OS deps: they live in the ephemeral rootfs, so "did the install
 *     run before" stamps can't be trusted across restarts.
 *   - The install runs through the BUNDLED playwright CLI
 *     (`node node_modules/playwright/cli.js`), not `npx playwright` — npx
 *     re-downloaded the standalone playwright package on every boot and could
 *     drift to a different version (and browser build) than the one
 *     `import('playwright')` resolves. npx remains as a fallback only.
 *   - Runs in the background after the server is already listening, at reduced
 *     CPU priority (best-effort `os.setPriority`) so apt/dpkg churn can't
 *     starve the event loop of live requests.
 *   - Readiness is observable via {@link playwrightReadiness}: render entry
 *     points return a clear "still installing" state instead of racing the
 *     background install on fresh rollouts.
 *   - Set `STUDIOGRAPH_PLAYWRIGHT_BROWSER_ONLY=1` to drop `--with-deps` when
 *     the OS libs are baked into the image. Point `PLAYWRIGHT_BROWSERS_PATH`
 *     at a persistent volume so the browser downloads once, not per boot.
 *
 * Best-effort throughout: any failure is logged and swallowed — the worst case is
 * the pre-existing "inspect unavailable" behavior, never a crashed boot.
 */
export type PlaywrightReadinessState = 'idle' | 'checking' | 'installing' | 'ready' | 'failed';
export interface PlaywrightReadiness {
    /** `idle` = bootstrap not requested (local serve, tests) — render paths
     *  proceed and surface their own errors. `checking`/`installing` = the
     *  background pass is in flight. `ready` = launch probe passed. `failed` =
     *  install or post-install probe failed; `detail` carries why. */
    state: PlaywrightReadinessState;
    /** Why the install started (probe failure) or why the pass failed. */
    detail?: string;
    /** Epoch ms when the current checking/installing pass began. */
    startedAt?: number;
}
export declare function playwrightReadiness(): PlaywrightReadiness;
export declare function __resetPlaywrightBootstrapForTests(): void;
/** ONE set of headless-launch options shared by the boot probe and the render
 *  path (artifact-render-export's launchChromium) — they must agree, or the
 *  probe could pass while renders fail (or vice versa). */
export declare const CHROMIUM_LAUNCH_OPTIONS: {
    headless: boolean;
    args: string[];
};
/** Launch failures that mean "the playwright-managed browser isn't usable
 *  here" (vs a transient/other error). Shared by the probe and the render
 *  path's launchChromium: both fall back to the system `chrome` channel on
 *  exactly this predicate, so the probe's verdict matches what a render
 *  would actually do. */
export declare function isMissingBrowserError(err: unknown): boolean;
export declare function ensurePlaywrightChromium(log?: (message: string) => void): void;
