import type { NpcSample } from './metrics'; import type { BrowserKey } from '../browser/launch'; export type CaptureNpcOptions = { directory: string; /** Caption (and report) only this NPC id; the roster still lists everyone. */ npc?: string | undefined; /** How many frames across the window (default 6). */ frames?: number | undefined; /** The window the frames are spread over, in seconds (default 6). */ seconds?: number | undefined; settleMs?: number | undefined; timeoutMs?: number | undefined; browser?: BrowserKey | undefined; /** Where the PNGs land (default: a fresh temp dir). */ outDir?: string | undefined; fallbackMounts?: Record | undefined; onProgress?: ((message: string) => void) | undefined; }; export interface NpcFrame { index: number; /** Seconds after the first frame — the schedule the frame was taken on. */ atS: number; file: string; /** One line per NPC at that instant: where it is, what it is doing, what the world says about it. */ caption: string; rows: NpcSample[]; } export interface CaptureNpcResult { directory: string; outDir: string; npc: string | null; frames: NpcFrame[]; /** Every id seen across the strip, in first-seen order. */ roster: string[]; /** Always 'world-view' today — the inspect lane exposes no camera to aim at an NPC. */ cameraFocus: 'world-view'; notes: string[]; } /** Exported for tests: the per-frame caption, which is the whole reason a frame is worth more than a still. */ export declare function captionFor(rows: readonly NpcSample[], filter: string | null): string; export declare function captureNpc(opts: CaptureNpcOptions): Promise;