/**
 * @module _shared/scene-render
 *
 * Render a VibeFrame scene project to MP4/WebM/MOV using the Hyperframes
 * producer directly. Unlike the FFmpeg-bridge backend in
 * `pipeline/renderers/hyperframes.ts` which has to convert a `TimelineState`
 * into a temp Hyperframes project, scene projects already ARE Hyperframes
 * projects — so we hand the producer the user's project dir and entry file
 * verbatim.
 *
 * `executeSceneRender()` is decoupled from CLI flags so that the C6 agent
 * tool and the C5 `--format scenes` pipeline can call it the same way. It
 * returns a structured result instead of throwing or exiting.
 */
import { type RenderConfig } from "@hyperframes/producer";
import { type SceneAspect } from "./scene-project.js";
export type RenderFps = 24 | 30 | 60;
export type RenderQuality = "draft" | "standard" | "high";
export type RenderFormat = "mp4" | "webm" | "mov";
export type RenderOpenAction = "open" | "reveal";
export interface SceneRenderOptions {
    /** Project directory (defaults to cwd). */
    projectDir?: string;
    /** Root composition file relative to projectDir (default: "index.html"). */
    root?: string;
    /** Render only one storyboard beat by synthesizing a temporary root. */
    beatId?: string;
    /** Output file. When relative, resolved against projectDir. Default:
     *  `renders/<projectName>-<isoStamp>.<format>`. */
    output?: string;
    fps?: RenderFps;
    quality?: RenderQuality;
    format?: RenderFormat;
    /** Hyperframes capture worker count. Default 1 (the existing backend's
     *  default — auto-worker mode times out on small comps). */
    workers?: number;
    /** Open the rendered media in the OS default app after a successful render. */
    openAfterRender?: boolean;
    /** Reveal the rendered media in Finder/file manager after a successful render. */
    revealInFinder?: boolean;
    signal?: AbortSignal;
    onProgress?: (pct: number, stage: string) => void;
}
export interface SceneRenderResult {
    success: boolean;
    kind?: "render";
    beat?: string | null;
    root?: string;
    outputPath?: string;
    absoluteOutputPath?: string;
    openCommand?: string;
    revealCommand?: string;
    opened?: boolean;
    revealed?: boolean;
    openError?: string;
    revealError?: string;
    durationMs?: number;
    framesRendered?: number;
    totalFrames?: number;
    fps?: RenderFps;
    quality?: RenderQuality;
    format?: RenderFormat;
    /** Number of `<audio>` elements muxed into the final file. 0 = silent project. */
    audioCount?: number;
    /** True when ffmpeg was invoked to overlay audio on the producer's video. */
    audioMuxApplied?: boolean;
    /** Non-fatal warning from the audio mux pass — caller may surface to the user. */
    audioMuxWarning?: string;
    reportPath?: string;
    code?: string;
    error?: string;
    retryWith?: string[];
}
export interface MediaOpenCommand {
    command: string;
    args: string[];
    display: string;
}
/** Map a quality preset to an x264 CRF (lower = higher quality). */
export declare function qualityToCrf(quality?: RenderQuality): number;
/**
 * Compute the default output path for a render. Pure — does no I/O. Returns
 * an absolute path under `<projectDir>/renders/`.
 *
 * `now` is injectable so tests get deterministic output.
 */
export declare function defaultOutputPath(opts: {
    projectDir: string;
    projectName?: string;
    format?: RenderFormat;
    beatId?: string;
    now?: Date;
}): string;
/**
 * Build the producer's `RenderConfig` from caller options. Pure — useful for
 * unit tests that want to assert defaults without touching Chrome.
 */
export declare function buildRenderConfig(opts: {
    fps?: RenderFps;
    quality?: RenderQuality;
    format?: RenderFormat;
    workers?: number;
    entryFile?: string;
}): RenderConfig;
export declare function buildMediaOpenCommand(action: RenderOpenAction, filePath: string, platform?: NodeJS.Platform): MediaOpenCommand;
/**
 * Render a scene project. Mirrors the contract of the existing Hyperframes
 * backend (preflight → execute → structured result), but skips the
 * `TimelineState` → temp project conversion because the user's project is
 * already a valid Hyperframes project.
 */
export declare function executeSceneRender(opts?: SceneRenderOptions): Promise<SceneRenderResult>;
export interface BeatRenderRootResult {
    success: boolean;
    root: string;
    durationSec?: number;
    compositionPath?: string;
    narrationPath?: string;
    code?: "BEAT_NOT_FOUND" | "BEAT_RENDER_NOT_READY";
    error?: string;
    retryWith?: string[];
}
export declare function prepareBeatRenderRoot(opts: {
    projectDir: string;
    beatId: string;
    aspect: SceneAspect;
}): Promise<BeatRenderRootResult>;
