import type { PygmalionStoryboardEnvironmentManifest, PygmalionStoryboardEnvironmentScanOptions, } from './vite.js'; export type StoryboardCaptureStatus = 'ready' | 'rendered-with-qa-failure' | 'capture-error'; export interface StoryboardCaptureViewport { width: number; height: number; } export interface StoryboardCaptureDiagnostic { stage: string; code: string; selector?: string; label?: string; message?: string; viewport: StoryboardCaptureViewport; } export interface StoryboardCaptureScreenshot { mediaType: 'image/png'; width: number; height: number; bytes: Uint8Array; } export interface StoryboardCaptureResult { id: string; route: string | null; status: StoryboardCaptureStatus; viewport: StoryboardCaptureViewport; snapshot?: string; screenshot?: StoryboardCaptureScreenshot; domTree?: unknown; diagnostics: StoryboardCaptureDiagnostic[]; } export interface StoryboardCaptureHookContext< TScreenCase = Record, > { context: unknown; page: unknown; screenCase: TScreenCase; route: string; signal?: AbortSignal; warm?: boolean; } export interface StoryboardCaptureOptions< TScreenCase extends Record = Record, > { browser: { newContext(options: Record): Promise; }; baseUrl: string | URL; screenCase: TScreenCase; signal?: AbortSignal; /** Immutable source and host-hook identity. Changing hook semantics requires a new revision. */ sourceRevision?: string; hooks?: { beforePreset?( context: StoryboardCaptureHookContext, ): void | Promise; afterPreset?( context: StoryboardCaptureHookContext, ): void | Promise; /** Runs after final interactions, stabilization and assertions, before closing the context. */ afterAssertions?( context: StoryboardCaptureHookContext, ): void | Promise; }; includeDomTree?: boolean; /** Preserve a built recipe's final state after afterPreset verifies readiness. Cannot use a reusable session. */ preservePreparedState?: boolean; includePreviewSnapshot?: boolean; previewBaseToken?: string; contextOptions?: Record; navigationOptions?: Record; screenshotOptions?: Record; /** How long to wait for a still document, and what may keep moving. */ stability?: StoryboardStabilityOptions; /** Optional target-driven replay; final stability and assertions still run. */ /** Capture defaults to target-driven waits; authored preserves every fixed pause. */ interactionRunOptions?: { settlePolicy?: 'authored' | 'target-driven' | 'live'; defaultActionSettleMs?: number }; /** A warm page lane owned by the session pool. Supplied by createStoryboardCaptureSessions. */ session?: StoryboardCaptureSession | null; } /** One booted page plus the group it was booted for. Owned by the session pool. */ export interface StoryboardCaptureSession { key: string; context: unknown; page: unknown; frozen?: boolean; poisoned?: boolean; reusePreparedPages?: boolean; prepared?: boolean; } export interface StoryboardCaptureSessionPool< TScreenCase extends Record = Record, > { capture( screenCase: TScreenCase, context?: { isolated?: boolean; options?: Partial>; [key: string]: unknown }, ): Promise; stats(): { warm: number; cold: number; boots: number; discarded: number; lanes: number; }; /** Discard all retained and active pages; the pool can be used again. */ invalidate(): Promise; close(): Promise; } export interface StoryboardStabilityOptions { /** Samples before giving up. Default 40 at 100ms, so a 4s ceiling. */ attempts?: number; requiredStableSamples?: number; intervalMs?: number; minimumWaitMs?: number; /** * Regions that are expected to keep changing — an elapsed clock, a level * meter, a marquee. Mutations confined to them do not count as churn. */ volatileSelectors?: readonly string[]; } export declare const STORYBOARD_CAPTURE_STATUSES: Readonly<{ ready: 'ready'; qaFailure: 'rendered-with-qa-failure'; captureError: 'capture-error'; }>; export declare class StoryboardCaptureStageError extends Error { readonly stage: string; readonly details: Record; constructor(stage: string, error: unknown, details?: Record); } export declare function captureStoryboardCase< TScreenCase extends Record, >( options: StoryboardCaptureOptions, ): Promise; /** * Captures declared screens on warm pages, and replayed screens on fresh ones. * * Boot is the expensive part of a capture, and a declared state does not need * one per screen. Cases that replay interactions keep the fresh-context path. */ export declare function createStoryboardCaptureSessions< TScreenCase extends Record = Record, >( options: Partial> & { capture?: ( options: StoryboardCaptureOptions, ) => Promise; maximumLanes?: number; idleTimeoutMs?: number; /** Requires sourceRevision and a complete desired-state adapter. Replayed cases still boot fresh pages. */ reusePreparedPages?: boolean; }, ): StoryboardCaptureSessionPool; export declare const STORYBOARD_SESSION_POOL_LIMITS: { readonly maximumLanes: number; readonly idleTimeoutMs: number; }; /** The warm-page group key for a case, or null when the case must boot its own page. */ export declare function storyboardCaptureSessionKey( screenCase: Record, options?: Partial & { reusePreparedPages?: boolean }, ): string | null; export declare function resolveStoryboardCaptureRoute( screenCase: Record, ): unknown; export declare function resolveStoryboardCaptureUrl( baseUrl: string | URL, route: unknown, environment?: Record, ): string; export declare function resolveStoryboardFixedTime( preset: Record | null | undefined, ): string | null; export declare function hashStoryboardCapture( value: string | Uint8Array, ): string; export declare function normalizeStoryboardDomStructure(node: unknown): string; export declare function createStoryboardArtifactRecord(input: { screenCase: { id: string; scenarioIds?: readonly string[]; width?: number; height?: number; }; domTree: unknown; screenshot: string | Uint8Array; route: string | null; }): { id: string; scenarioIds: string[]; route: string | null; viewport: StoryboardCaptureViewport; domStructureHash: string; screenshotHash: string; }; export declare function runStoryboardInteraction( page: unknown, interaction: Record, options?: { settlePolicy?: 'authored' | 'target-driven' | 'live'; defaultActionSettleMs?: number; nextInteraction?: { action: string; selector?: string; text?: string } }, ): Promise; export declare function runStoryboardAssertion( page: unknown, assertion: Record, ): Promise; export declare function assertFinalStoryboardState( page: unknown, assertions: readonly Record[], ): Promise; export declare function waitForStableStoryboardDocument( page: unknown, options?: StoryboardStabilityOptions, ): Promise; export declare function storyboardDocumentStabilitySignature( volatileSelectors?: readonly string[], ): string; export declare function storyboardCaptureCandidateTexts( element: Element, ): string[]; export declare function findUnassertedStoryboardModal( assertions?: readonly Record[], ): { role: string; label: string } | null; export declare function collectStoryboardDomTree(): unknown; export declare function serializeStoryboardPreviewDocument( baseHref?: string, ): string | null; export type StoryboardCaptureSchedulePhase = 'warm-up' | 'primary' | 'isolated-retry'; export interface StoryboardCaptureScheduleContext { phase: StoryboardCaptureSchedulePhase; attempt: number; index: number; total: number; isolated: boolean; requiresFreshContext: true; previousResult?: TResult; signal?: AbortSignal; } export interface StoryboardScheduledCaptureResult { status: StoryboardCaptureStatus; snapshot?: unknown; screenshot?: unknown; domTree?: unknown; diagnostics?: readonly unknown[]; [key: string]: unknown; } export interface StoryboardCaptureScheduleOptions { concurrency?: number; isolatedRetryAttempts?: number; onRetryPass?(pass: { attempt: number; totalAttempts: number; indexes: number[]; }): void; signal?: AbortSignal; } export declare const STORYBOARD_CAPTURE_SCHEDULER_LIMITS: Readonly<{ defaultConcurrency: 8; maximumConcurrency: 16; }>; export declare function scheduleStoryboardCaptures< TItem, TResult extends StoryboardScheduledCaptureResult, >( items: readonly TItem[], capture: ( item: TItem, context: StoryboardCaptureScheduleContext, ) => TResult | Promise, options?: StoryboardCaptureScheduleOptions, ): Promise; export interface RoutePreviewArtifactV3Capture { status: StoryboardCaptureStatus; viewport: StoryboardCaptureViewport; snapshot?: string; screenshot?: { mediaType: 'image/png' | 'image/webp'; width: number; height: number; bytes: Uint8Array; }; diagnostics?: readonly StoryboardCaptureDiagnostic[]; /** What this frame was captured from, compared per frame instead of per bundle. */ fingerprint?: string; } export interface RoutePreviewArtifactBundleV3 { readonly version: 3; readonly namespace: string; readonly sourceRevision?: string; readonly assets: { readonly head: Readonly>; readonly stylesheets: Readonly>; readonly screenshots: Readonly< Record< string, { readonly mediaType: 'image/png' | 'image/webp'; readonly width: number; readonly height: number; readonly data: string; readonly byteLength: number; } > >; }; readonly frames: Readonly>; } export declare const ROUTE_PREVIEW_ARTIFACT_V3_LIMITS: Readonly< Record >; export declare function createRoutePreviewArtifactV3(input: { namespace: string; sourceRevision?: string; captures: Record; }): RoutePreviewArtifactBundleV3; export interface RoutePreviewArtifactFrameRequest { id: string; fingerprint?: string; } export declare function selectRoutePreviewArtifactFrames( bundle: unknown, wanted: readonly (RoutePreviewArtifactFrameRequest | string)[], options?: { includeStale?: boolean; sourceRevision?: string }, ): { bundle: RoutePreviewArtifactBundleV3; missing: string[]; stale: string[]; }; export declare function mergeRoutePreviewArtifactV3( base: unknown, incoming: unknown, ): RoutePreviewArtifactBundleV3; export declare function validateRoutePreviewArtifactV3(bundle: unknown): { valid: boolean; errors: string[]; bytes: number; }; export declare function validateRoutePreviewArtifactBundle(bundle: unknown): { valid: boolean; errors: string[]; bytes: number; }; export declare function reconstructRoutePreviewArtifactSnapshotV3( bundle: RoutePreviewArtifactBundleV3, frameId: string, ): string | null; export declare function reconstructRoutePreviewArtifactSnapshotsV3( bundle: RoutePreviewArtifactBundleV3, ): Record; export declare function reconstructRoutePreviewArtifactScreenshotV3( bundle: RoutePreviewArtifactBundleV3, frameId: string, ): { mediaType: 'image/png' | 'image/webp'; width: number; height: number; bytes: Uint8Array; } | null; export declare const PYGMALION_STORYBOARD_CANONICAL_CONTROL: string; export declare function normalizeStoryboardSnapshot( snapshot: string, ): string | null; export declare function fingerprintStoryboardSnapshot( snapshot: string, ): string | null; export declare function recommendedStoryboardExecutionConcurrency(capabilities?: { parallelism?: number; totalMemoryBytes?: number; }): number; export declare function executeStoryboardCandidates( candidates: readonly Record[], capture: ( candidate: Record, context: { signal: AbortSignal; index: number; total: number }, ) => unknown | Promise, options?: { concurrency?: number; timeoutMs?: number }, ): Promise; export declare function canonicalizeStoryboardExecutions( candidates: readonly Record[], executions: readonly Record[], ): unknown; export declare const PYGMALION_STORYBOARD_ENVIRONMENT_QUERY: string; export declare function scanStoryboardEnvironment( root: string, options?: PygmalionStoryboardEnvironmentScanOptions, ): Promise;