@kadj-amoah/showrunner 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/cli.js +63 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts","../src/pipeline/run.ts","../src/util/logger.ts","../src/util/runId.ts","../src/stages/comprehension.ts","../src/stages/script.ts","../src/productModel/io.ts","../src/productModel/schema.ts","../src/manifest/io.ts","../src/manifest/schema.ts","../src/manifest/playwrightCodegen.ts","../src/manifest/voScript.ts","../src/providers/llm/withRetry.ts","../src/providers/llm/types.ts","../src/scriptGen/prompts.ts","../src/scriptGen/validateSelectors.ts","../src/scriptGen/generate.ts","../src/scriptGen/domPreflight.ts","../src/recording/selectorHeuristic.ts","../src/providers/llm/anthropic.ts","../src/providers/llm/openai.ts","../src/providers/llm/agentBridge.ts","../src/recording/lifecycle.ts","../src/providers/llm/custom.ts","../src/providers/llm/factory.ts","../src/providers/llm/resolveFromContext.ts","../src/stages/record.ts","../src/recording/record.ts","../src/manifest/alignment.ts","../src/recording/auth.ts","../src/recording/actions.ts","../src/recording/cursorOverlay.ts","../src/recording/selector.ts","../src/util/resources.ts","../src/stages/voiceover.ts","../src/voiceover/ffmpeg.ts","../src/voiceover/fullVo.ts","../src/providers/tts/types.ts","../src/voiceover/elevenlabs.ts","../src/providers/tts/elevenlabs.ts","../src/providers/tts/openai.ts","../src/providers/tts/custom.ts","../src/providers/tts/factory.ts","../src/providers/tts/resolveFromContext.ts","../src/stages/mux.ts","../src/mux/quality.ts","../src/mux/normalize.ts","../src/mux/slice.ts","../src/mux/segmentMux.ts","../src/mux/concat.ts","../src/mux/branding.ts","../src/mux/captions.ts","../src/pipeline/types.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { resolve, dirname, isAbsolute } from 'node:path';\nimport yaml from 'js-yaml';\nimport { z } from 'zod';\nimport { showrunnerConfigSchema, type ShowrunnerConfig } from './schema.js';\n\nexport class ConfigError extends Error {\n override readonly name = 'ConfigError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n readonly configPath?: string,\n ) {\n super(message);\n }\n}\n\nexport interface LoadedConfig {\n config: ShowrunnerConfig;\n configPath: string;\n configDir: string;\n}\n\nexport async function loadConfig(configPath: string): Promise<LoadedConfig> {\n const absPath = isAbsolute(configPath) ? configPath : resolve(process.cwd(), configPath);\n let raw: string;\n try {\n raw = await readFile(absPath, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ConfigError(`Failed to read config at ${absPath}: ${cause}`, undefined, absPath);\n }\n\n let parsed: unknown;\n try {\n parsed = yaml.load(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ConfigError(`Invalid YAML in ${absPath}: ${cause}`, undefined, absPath);\n }\n\n return validateConfig(parsed, absPath);\n}\n\nexport function validateConfig(input: unknown, configPath?: string): LoadedConfig {\n const normalized = normalizeLegacyConfig(input);\n const result = showrunnerConfigSchema.safeParse(normalized);\n if (!result.success) {\n throw new ConfigError(\n formatZodError(result.error),\n result.error.issues,\n configPath,\n );\n }\n return {\n config: result.data,\n configPath: configPath ?? '',\n configDir: configPath ? dirname(configPath) : process.cwd(),\n };\n}\n\nconst ELEVENLABS_FIELD_KEYS = [\n 'voice_id',\n 'model',\n 'stability',\n 'similarity_boost',\n 'style',\n 'use_speaker_boost',\n 'speed',\n 'api_key_env',\n 'endpoint',\n] as const;\n\n/**\n * Reshape pre-v1.1 configs into the discriminated-union shape introduced in B3.\n *\n * Pre-v1.1:\n * voiceover:\n * provider: elevenlabs # string\n * voice_id: ... # flat ElevenLabs fields\n * api_key_env: ...\n *\n * Post-v1.1:\n * voiceover:\n * provider:\n * name: elevenlabs\n * voice_id: ...\n * api_key_env: ...\n *\n * Triggered when `voiceover.provider` is missing (defaulted to elevenlabs) OR\n * a string equal to 'elevenlabs'. Modern configs whose `voiceover.provider`\n * is already an object pass through untouched.\n */\nexport function normalizeLegacyConfig(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input;\n const cfg = { ...(input as Record<string, unknown>) };\n const vo = cfg.voiceover as Record<string, unknown> | undefined;\n if (!vo) return cfg;\n\n const provider = vo.provider;\n const isLegacy =\n provider === undefined ||\n provider === 'elevenlabs' ||\n (typeof provider === 'string' && provider === 'elevenlabs');\n if (!isLegacy) return cfg;\n\n const elevenSpec: Record<string, unknown> = { name: 'elevenlabs' };\n for (const key of ELEVENLABS_FIELD_KEYS) {\n if (vo[key] !== undefined) elevenSpec[key] = vo[key];\n }\n\n const cleaned: Record<string, unknown> = { ...vo };\n for (const key of ELEVENLABS_FIELD_KEYS) delete cleaned[key];\n cleaned.provider = elevenSpec;\n\n cfg.voiceover = cleaned;\n return cfg;\n}\n\nfunction formatZodError(error: z.ZodError): string {\n const lines = error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';\n return ` ${path}: ${issue.message}`;\n });\n return `Config validation failed:\\n${lines.join('\\n')}`;\n}\n","import { z } from 'zod';\n\nconst projectSchema = z.object({\n name: z.string().min(1),\n product_model: z.string().optional(),\n});\n\nconst comprehensionSourceSchema = z.object({\n type: z.enum(['prd', 'readme', 'codebase', 'openapi', 'changelog', 'custom']),\n path: z.string(),\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n});\n\nconst comprehensionSchema = z.object({\n mode: z.enum(['documents', 'interactive']).default('documents'),\n sources: z.array(comprehensionSourceSchema).default([]),\n});\n\nconst scriptSchema = z.object({\n style: z.string().default('matter-of-fact'),\n duration_target_seconds: z.number().int().positive().default(90),\n highlight_features: z.array(z.string()).default([]),\n vo_review_gate: z.boolean().default(false),\n});\n\nconst viewportSchema = z.object({\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nconst stateSchema = z\n .object({\n seed_script: z.string().optional(),\n reset_script: z.string().optional(),\n teardown_script: z.string().optional(),\n })\n .default({});\n\nconst authSetupScriptSchema = z.object({\n type: z.literal('setup_script'),\n path: z.string(),\n});\n\nconst authSessionSchema = z.object({\n type: z.literal('session'),\n cookies_file: z.string(),\n local_storage_file: z.string().optional(),\n});\n\nconst authFormFieldSchema = z.object({\n selector: z.string(),\n env: z.string(),\n});\n\nconst authFormSchema = z.object({\n type: z.literal('form'),\n login_url: z.string(),\n fields: z.object({\n email: authFormFieldSchema,\n password: authFormFieldSchema,\n }),\n submit_selector: z.string(),\n success_url_pattern: z.string(),\n timeout_ms: z.number().int().positive().default(5000),\n});\n\nconst authSchema = z.discriminatedUnion('type', [\n authSetupScriptSchema,\n authSessionSchema,\n authFormSchema,\n]);\n\nconst recordingSchema = z.object({\n target_url: z.string().url(),\n viewport: viewportSchema.default({ width: 1920, height: 1080 }),\n browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),\n headless: z.boolean().default(false),\n output_dir: z.string().default('./segments/video'),\n trace_dir: z.string().default('./segments/traces'),\n cursor_highlight: z.boolean().default(true),\n cursor_min_motion_ms: z.number().int().nonnegative().default(180),\n cursor_max_motion_ms: z.number().int().nonnegative().default(700),\n cursor_post_arrival_ms: z.number().int().nonnegative().default(100),\n cursor_speed_factor: z.number().positive().default(1.0),\n cursor_chain_mode: z.enum(['strict', 'smart']).default('strict'),\n segment_buffer_ms: z.number().int().nonnegative().default(200),\n preflight: z.boolean().default(true),\n state: stateSchema,\n auth: authSchema.optional(),\n});\n\nconst postProcessSchema = z\n .object({\n debreath: z.boolean().default(true),\n })\n .default({ debreath: true });\n\nconst pausePlacementSchema = z\n .object({\n strategy: z.enum(['action_boundaries', 'trailing']).default('trailing'),\n min_silence_ms: z.number().int().nonnegative().default(250),\n snap_window_ms: z.number().int().nonnegative().default(1200),\n })\n .default({});\n\nconst elevenLabsTTSSchema = z.object({\n name: z.literal('elevenlabs'),\n voice_id: z.string().min(1),\n model: z.string().default('eleven_multilingual_v2'),\n api_key_env: z.string().default('ELEVENLABS_API_KEY'),\n endpoint: z.enum(['with_timestamps', 'basic']).default('with_timestamps'),\n stability: z.number().min(0).max(1).default(0.55),\n similarity_boost: z.number().min(0).max(1).default(0.75),\n style: z.number().min(0).max(1).default(0.0),\n use_speaker_boost: z.boolean().default(true),\n speed: z.number().min(0.85).max(1.15).default(1.0),\n});\n\nconst openaiTTSSchema = z.object({\n name: z.literal('openai'),\n voice: z.string().default('alloy'),\n model: z.string().default('tts-1-hd'),\n api_key_env: z.string().default('OPENAI_API_KEY'),\n base_url: z.string().optional(),\n});\n\nconst customTTSSchema = z.object({\n name: z.literal('custom'),\n module_path: z.string(),\n options: z.record(z.unknown()).optional(),\n});\n\nconst ttsProviderSchema = z.discriminatedUnion('name', [\n elevenLabsTTSSchema,\n openaiTTSSchema,\n customTTSSchema,\n]);\n\nconst voiceoverSchema = z.object({\n provider: ttsProviderSchema,\n alignment_strategy: z.enum(['required', 'best_effort']).default('required'),\n output_dir: z.string().default('./segments/audio'),\n alignment_dir: z.string().default('./segments/alignment'),\n duration_drift_threshold_pct: z.number().nonnegative().default(15),\n drift_strategy: z.enum(['adjust_timing', 'resynthesize']).default('adjust_timing'),\n tail_padding_ms: z.number().int().nonnegative().default(500),\n post_process: postProcessSchema,\n pause_placement: pausePlacementSchema,\n});\n\nconst anthropicLLMSchema = z.object({\n provider: z.literal('anthropic'),\n model: z.string().default('claude-opus-4-7'),\n api_key_env: z.string().default('ANTHROPIC_API_KEY'),\n max_tokens: z.number().int().positive().optional(),\n});\n\nconst openaiLLMSchema = z.object({\n provider: z.literal('openai'),\n model: z.string().default('gpt-4o'),\n api_key_env: z.string().default('OPENAI_API_KEY'),\n max_tokens: z.number().int().positive().optional(),\n base_url: z.string().optional(),\n});\n\nconst agentBridgeLLMSchema = z.object({\n provider: z.literal('agent_bridge'),\n bridge: z.object({\n mode: z.enum(['spawn', 'file_poll']).default('spawn'),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n request_dir: z.string().optional(),\n poll_interval_ms: z.number().int().positive().optional(),\n timeout_ms: z.number().int().positive().optional(),\n }),\n});\n\nconst customLLMSchema = z.object({\n provider: z.literal('custom'),\n module_path: z.string(),\n options: z.record(z.unknown()).optional(),\n});\n\nconst llmProviderConfigSchema = z.discriminatedUnion('provider', [\n anthropicLLMSchema,\n openaiLLMSchema,\n agentBridgeLLMSchema,\n customLLMSchema,\n]);\n\nconst llmSchema = z\n .object({\n default: llmProviderConfigSchema.default({\n provider: 'anthropic',\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n }),\n overrides: z\n .object({\n comprehension: llmProviderConfigSchema.optional(),\n script: llmProviderConfigSchema.optional(),\n instrument: llmProviderConfigSchema.optional(),\n })\n .optional(),\n })\n .default({\n default: {\n provider: 'anthropic',\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n },\n });\n\nconst titleCardSchema = z.object({\n enabled: z.boolean().default(true),\n text: z.string(),\n duration_seconds: z.number().positive().default(2),\n font: z.string().optional(),\n font_size: z.number().int().positive().default(48),\n text_color: z.string().default('#FFFFFF'),\n background_color: z.string().default('#0F172A'),\n logo: z.string().optional(),\n logo_position: z.enum(['top_left', 'top_center', 'top_right']).default('top_center'),\n});\n\nconst outroCardSchema = z.object({\n enabled: z.boolean().default(true),\n text: z.string(),\n duration_seconds: z.number().positive().default(2),\n});\n\nconst brandingSchema = z\n .object({\n title_card: titleCardSchema.optional(),\n outro_card: outroCardSchema.optional(),\n })\n .default({});\n\nconst backgroundMusicSchema = z.object({\n path: z.string(),\n volume_db: z.number().default(-22),\n});\n\nconst captionsSchema = z\n .object({\n enabled: z.boolean().default(false),\n format: z.enum(['srt', 'vtt', 'both']).default('srt'),\n })\n .default({});\n\nconst outputSchema = z.object({\n format: z.literal('mp4').default('mp4'),\n resolution: z\n .string()\n .regex(/^\\d+x\\d+$/, 'Expected WIDTHxHEIGHT (e.g. 1920x1080)')\n .default('1920x1080'),\n fps: z.number().int().positive().default(30),\n codec_video: z.string().default('h264'),\n codec_audio: z.string().default('aac'),\n quality: z.enum(['draft', 'standard', 'high']).default('standard'),\n branding: brandingSchema,\n background_music: backgroundMusicSchema.optional(),\n captions: captionsSchema,\n output_path: z.string().default('./output/demo_final.mp4'),\n});\n\nexport const showrunnerConfigSchema = z.object({\n project: projectSchema,\n comprehension: comprehensionSchema.default({ mode: 'documents', sources: [] }),\n script: scriptSchema.default({}),\n recording: recordingSchema,\n voiceover: voiceoverSchema,\n llm: llmSchema,\n output: outputSchema.default({}),\n});\n\nexport type ShowrunnerConfig = z.infer<typeof showrunnerConfigSchema>;\nexport type ComprehensionConfig = z.infer<typeof comprehensionSchema>;\nexport type ScriptConfig = z.infer<typeof scriptSchema>;\nexport type RecordingConfig = z.infer<typeof recordingSchema>;\nexport type VoiceoverConfig = z.infer<typeof voiceoverSchema>;\nexport type OutputConfig = z.infer<typeof outputSchema>;\nexport type AuthConfig = z.infer<typeof authSchema>;\nexport type TTSProviderConfig = z.infer<typeof ttsProviderSchema>;\nexport type ElevenLabsTTSConfig = z.infer<typeof elevenLabsTTSSchema>;\nexport type OpenAITTSConfig = z.infer<typeof openaiTTSSchema>;\nexport type LLMConfig = z.infer<typeof llmSchema>;\nexport type LLMProviderConfig = z.infer<typeof llmProviderConfigSchema>;\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport type { LoadedConfig } from '../config/loader.js';\nimport { logger } from '../util/logger.js';\nimport { generateRunId } from '../util/runId.js';\nimport { comprehensionStage } from '../stages/comprehension.js';\nimport { scriptStage } from '../stages/script.js';\nimport { recordStage } from '../stages/record.js';\nimport { voiceoverStage } from '../stages/voiceover.js';\nimport { muxStage } from '../stages/mux.js';\nimport {\n STAGE_NAMES,\n type PipelineContext,\n type PipelineOptions,\n type PipelineResult,\n type Stage,\n type StageName,\n type StageResult,\n} from './types.js';\n\nexport class PipelineStageError extends Error {\n override readonly name = 'PipelineStageError';\n constructor(\n readonly stage: StageName,\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n\nconst STAGES_BY_NAME: Record<StageName, Stage> = {\n comprehension: comprehensionStage,\n script: scriptStage,\n record: recordStage,\n voiceover: voiceoverStage,\n mux: muxStage,\n};\n\nexport async function run(\n loaded: LoadedConfig,\n options: PipelineOptions = {},\n): Promise<PipelineResult> {\n const runId = generateRunId();\n const interactive = options.interactive ?? true;\n const forced = new Set<StageName>(options.force ?? []);\n const enabled = resolveEnabledStages(options.stages);\n\n const ctx: PipelineContext = {\n config: loaded.config,\n configPath: loaded.configPath,\n configDir: loaded.configDir,\n runId,\n interactive,\n forced,\n overrides: options.overrides ?? {},\n };\n\n logger.event({ stage: 'pipeline', status: 'start', runId, stages: [...enabled] });\n\n const results: StageResult[] = [];\n for (const name of STAGE_NAMES) {\n if (!enabled.has(name)) {\n logger.event({ stage: name, status: 'disabled' });\n continue;\n }\n if (options.dryRun && (name === 'record' || name === 'voiceover' || name === 'mux')) {\n logger.event({ stage: name, status: 'dry-run' });\n results.push({\n stage: name,\n skipped: true,\n reason: 'dry-run',\n durationMs: 0,\n });\n continue;\n }\n const stage = STAGES_BY_NAME[name];\n let result: StageResult;\n try {\n result = await stage.run(ctx);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logger.event({ stage: name, status: 'failed', error: message });\n throw new PipelineStageError(name, message, err);\n }\n results.push(result);\n logger.event({\n stage: name,\n status: result.skipped ? 'skipped' : 'complete',\n durationMs: result.durationMs,\n reason: result.reason,\n });\n if (result.halt) {\n logger.event({\n stage: 'pipeline',\n status: 'halted',\n runId,\n by: name,\n reason: result.reason,\n });\n break;\n }\n }\n\n const outputPath = resolve(ctx.configDir, ctx.config.output.output_path);\n const buildManifestPath = resolve(dirname(outputPath), 'build_manifest.json');\n await writeBuildManifest(buildManifestPath, {\n runId,\n outputPath,\n results,\n config: loaded,\n });\n\n logger.event({ stage: 'pipeline', status: 'done', runId, buildManifest: buildManifestPath });\n\n return {\n runId,\n outputPath,\n stages: results,\n buildManifestPath,\n };\n}\n\nfunction resolveEnabledStages(filter: StageName[] | undefined): Set<StageName> {\n if (!filter || filter.length === 0) return new Set(STAGE_NAMES);\n return new Set(filter);\n}\n\ninterface BuildManifestPayload {\n runId: string;\n outputPath: string;\n results: StageResult[];\n config: LoadedConfig;\n}\n\nasync function writeBuildManifest(path: string, payload: BuildManifestPayload): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const stages: Record<string, unknown> = {};\n for (const r of payload.results) {\n stages[r.stage] = {\n skipped: r.skipped,\n reason: r.reason,\n duration_ms: r.durationMs,\n warnings: r.warnings,\n };\n }\n const manifest = {\n run_id: payload.runId,\n generated_at: new Date().toISOString(),\n output_file: payload.outputPath,\n inputs: {\n config: payload.config.configPath,\n },\n stages,\n warnings: payload.results.flatMap((r) => r.warnings ?? []),\n };\n await writeFile(path, JSON.stringify(manifest, null, 2) + '\\n', 'utf8');\n}\n","type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\ninterface LoggerState {\n level: LogLevel;\n json: boolean;\n}\n\nconst state: LoggerState = {\n level: (process.env['SHOWRUNNER_LOG_LEVEL'] as LogLevel) ?? 'info',\n json: false,\n};\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[state.level];\n}\n\nfunction emit(level: LogLevel, message: string, fields?: Record<string, unknown>): void {\n if (!shouldLog(level)) return;\n if (state.json) {\n const payload = { level, msg: message, ts: new Date().toISOString(), ...fields };\n process.stdout.write(JSON.stringify(payload) + '\\n');\n } else {\n const prefix = `[showrunner] `;\n const suffix = fields ? ' ' + JSON.stringify(fields) : '';\n const stream = level === 'error' || level === 'warn' ? process.stderr : process.stdout;\n stream.write(prefix + message + suffix + '\\n');\n }\n}\n\nexport const logger = {\n setLevel(level: LogLevel): void {\n state.level = level;\n },\n setJson(json: boolean): void {\n state.json = json;\n },\n isJson(): boolean {\n return state.json;\n },\n debug(message: string, fields?: Record<string, unknown>): void {\n emit('debug', message, fields);\n },\n info(message: string, fields?: Record<string, unknown>): void {\n emit('info', message, fields);\n },\n warn(message: string, fields?: Record<string, unknown>): void {\n emit('warn', message, fields);\n },\n error(message: string, fields?: Record<string, unknown>): void {\n emit('error', message, fields);\n },\n event(payload: Record<string, unknown>): void {\n if (state.json) {\n process.stdout.write(JSON.stringify({ ...payload, ts: new Date().toISOString() }) + '\\n');\n } else if (shouldLog('info')) {\n const { stage, status, ...rest } = payload as { stage?: string; status?: string } & Record<\n string,\n unknown\n >;\n const head = `[${stage ?? '?'}/${status ?? '?'}]`;\n const tail = Object.keys(rest).length > 0 ? ' ' + JSON.stringify(rest) : '';\n process.stdout.write(head + tail + '\\n');\n }\n },\n};\n","import { randomBytes } from 'node:crypto';\n\nexport function generateRunId(date: Date = new Date()): string {\n const y = date.getUTCFullYear();\n const m = String(date.getUTCMonth() + 1).padStart(2, '0');\n const d = String(date.getUTCDate()).padStart(2, '0');\n const suffix = randomBytes(3).toString('hex');\n return `sr-${y}${m}${d}-${suffix}`;\n}\n","import { stat } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\n\nexport const comprehensionStage: Stage = {\n name: 'comprehension',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const modelPath = resolve(\n ctx.configDir,\n ctx.config.project.product_model ?? './product_model.json',\n );\n\n const exists = await fileExists(modelPath);\n const forced = ctx.forced.has('comprehension');\n\n if (exists && !forced) {\n logger.event({\n stage: 'comprehension',\n status: 'skipped',\n reason: 'product_model.json already present',\n path: modelPath,\n });\n return {\n stage: 'comprehension',\n skipped: true,\n reason: 'product_model.json already present',\n durationMs: Date.now() - start,\n artifacts: { product_model: modelPath },\n };\n }\n\n logger.event({ stage: 'comprehension', status: 'pending' });\n logger.warn('Comprehension stage is not yet implemented — placeholder run.');\n\n return {\n stage: 'comprehension',\n skipped: true,\n reason: 'not yet implemented',\n durationMs: Date.now() - start,\n warnings: ['comprehension stage is a stub'],\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { stat, writeFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readProductModel, ProductModelError } from '../productModel/io.js';\nimport { readManifest, writeManifest } from '../manifest/io.js';\nimport { writePlaywrightSpec, writePlaywrightPreviewSpec } from '../manifest/playwrightCodegen.js';\nimport { writeVoScript } from '../manifest/voScript.js';\nimport { generateManifest, ManifestGenerationError } from '../scriptGen/generate.js';\nimport { scrapeSelectorInventory, type SelectorInventoryItem } from '../scriptGen/domPreflight.js';\nimport { resolveLLMProviderForStage } from '../providers/llm/resolveFromContext.js';\n\nconst LOCK_FILENAME = '.showrunner-lock';\n\nexport const scriptStage: Stage = {\n name: 'script',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const specPath = resolve(ctx.configDir, './scripts/playwright_demo.ts');\n const previewSpecPath = resolve(ctx.configDir, './scripts/playwright_demo.spec.ts');\n const voScriptPath = resolve(ctx.configDir, './scripts/vo_script.txt');\n const lockPath = resolve(ctx.configDir, LOCK_FILENAME);\n const productModelPath = resolve(\n ctx.configDir,\n ctx.config.project.product_model ?? './product_model.json',\n );\n\n const manifestExists = await fileExists(manifestPath);\n const forced = ctx.forced.has('script');\n\n let manifest;\n if (manifestExists && !forced) {\n logger.event({\n stage: 'script',\n status: 'reusing',\n reason: 'manifest.json present',\n path: manifestPath,\n });\n manifest = await readManifest(manifestPath);\n } else {\n if (!(await fileExists(productModelPath))) {\n return {\n stage: 'script',\n skipped: true,\n reason: `product_model.json not found at ${productModelPath} — run \\`showrunner understand\\` or restore the file`,\n durationMs: Date.now() - start,\n };\n }\n\n let productModel;\n try {\n productModel = await readProductModel(productModelPath);\n } catch (err) {\n if (err instanceof ProductModelError) {\n throw new Error(`script stage: ${err.message}`);\n }\n throw err;\n }\n\n // DOM preflight — scrape the live target so the LLM can't hallucinate selectors.\n // Failure is non-fatal; degrade gracefully to LLM-only generation.\n let selectorInventory: SelectorInventoryItem[] | undefined;\n try {\n logger.event({\n stage: 'script',\n status: 'dom_preflight',\n target_url: ctx.config.recording.target_url,\n });\n selectorInventory = await scrapeSelectorInventory({\n targetUrl: ctx.config.recording.target_url,\n recording: ctx.config.recording,\n });\n logger.event({\n stage: 'script',\n status: 'dom_preflight_done',\n inventory_size: selectorInventory.length,\n });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n warnings.push(`DOM preflight failed: ${cause} — falling back to LLM-only selector generation`);\n logger.warn(`DOM preflight failed: ${cause}`);\n }\n\n logger.event({ stage: 'script', status: 'generating', source: productModelPath });\n try {\n const provider = resolveLLMProviderForStage(ctx, 'script');\n manifest = await generateManifest({\n productModel,\n scriptConfig: ctx.config.script,\n provider,\n selectorInventory,\n });\n } catch (err) {\n if (err instanceof ManifestGenerationError) {\n throw new Error(`script stage: ${err.message}`);\n }\n throw err;\n }\n await writeManifest(manifestPath, manifest);\n logger.event({\n stage: 'script',\n status: 'manifest_written',\n path: manifestPath,\n segments: manifest.segments.length,\n });\n }\n\n const codegenInputs = {\n manifest,\n recording: ctx.config.recording,\n targetUrl: ctx.config.recording.target_url,\n videoDir: resolve(ctx.configDir, ctx.config.recording.output_dir),\n traceDir: resolve(ctx.configDir, ctx.config.recording.trace_dir),\n };\n await writePlaywrightSpec(specPath, codegenInputs);\n await writePlaywrightPreviewSpec(previewSpecPath, codegenInputs);\n await writeVoScript(voScriptPath, manifest, { projectName: ctx.config.project.name });\n logger.event({ stage: 'script', status: 'spec_written', path: specPath });\n logger.event({ stage: 'script', status: 'preview_spec_written', path: previewSpecPath });\n logger.event({ stage: 'script', status: 'vo_script_written', path: voScriptPath });\n\n if (ctx.config.script.vo_review_gate && ctx.interactive) {\n await writeFile(\n lockPath,\n JSON.stringify(\n {\n run_id: ctx.runId,\n stage: 'script',\n reason: 'vo_review_gate',\n vo_script_path: voScriptPath,\n created_at: new Date().toISOString(),\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n logger.warn(\n `VO review gate engaged. Edit ${voScriptPath}, then run \\`showrunner approve-vo --config ${ctx.configPath}\\` to resume.`,\n );\n return {\n stage: 'script',\n skipped: false,\n reason: 'paused for vo_review_gate',\n durationMs: Date.now() - start,\n artifacts: {\n manifest: manifestPath,\n playwright_spec: specPath,\n playwright_preview_spec: previewSpecPath,\n vo_script: voScriptPath,\n lock: lockPath,\n },\n warnings,\n meta: { gate: 'vo_review_gate', segments: manifest.segments.length },\n halt: true,\n };\n }\n\n if (ctx.config.script.vo_review_gate && !ctx.interactive) {\n warnings.push('vo_review_gate is true in config but --no-interactive disabled it');\n }\n\n return {\n stage: 'script',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: {\n manifest: manifestPath,\n playwright_spec: specPath,\n playwright_preview_spec: previewSpecPath,\n vo_script: voScriptPath,\n },\n warnings,\n meta: { segments: manifest.segments.length },\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { productModelSchema, type ProductModel } from './schema.js';\n\nexport class ProductModelError extends Error {\n override readonly name = 'ProductModelError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n ) {\n super(message);\n }\n}\n\nexport async function readProductModel(path: string): Promise<ProductModel> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ProductModelError(`Failed to read product model at ${path}: ${cause}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ProductModelError(`Invalid JSON in ${path}: ${cause}`);\n }\n const result = productModelSchema.safeParse(parsed);\n if (!result.success) {\n const lines = result.error.issues.map((i) => {\n const p = i.path.length > 0 ? i.path.join('.') : '<root>';\n return ` ${p}: ${i.message}`;\n });\n throw new ProductModelError(\n `Product model failed validation:\\n${lines.join('\\n')}`,\n result.error.issues,\n );\n }\n return result.data;\n}\n","import { z } from 'zod';\n\nconst coreFlowSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n steps: z.array(z.string()).default([]),\n entry_url: z.string().optional(),\n});\n\nconst demoRecommendationSchema = z.object({\n suggested_flows: z.array(z.string()).default([]),\n suggested_duration_seconds: z.number().int().positive().default(90),\n});\n\nexport const productModelSchema = z.object({\n product_name: z.string().min(1),\n tagline: z.string().default(''),\n primary_user: z.string().default(''),\n confidence: z.enum(['high', 'medium', 'low']).default('medium'),\n source: z.enum(['documents', 'interactive']).default('documents'),\n generated_at: z.string().default(() => new Date().toISOString()),\n core_flows: z.array(coreFlowSchema).default([]),\n key_features: z.array(z.string()).default([]),\n demo_recommendation: demoRecommendationSchema.default({\n suggested_flows: [],\n suggested_duration_seconds: 90,\n }),\n});\n\nexport type ProductModel = z.infer<typeof productModelSchema>;\nexport type CoreFlow = z.infer<typeof coreFlowSchema>;\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { z } from 'zod';\nimport { manifestSchema, type Manifest } from './schema.js';\n\nexport class ManifestError extends Error {\n override readonly name = 'ManifestError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n ) {\n super(message);\n }\n}\n\nexport async function readManifest(path: string): Promise<Manifest> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ManifestError(`Failed to read manifest at ${path}: ${cause}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ManifestError(`Invalid JSON in manifest ${path}: ${cause}`);\n }\n return parseManifest(parsed);\n}\n\nexport function parseManifest(input: unknown): Manifest {\n const result = manifestSchema.safeParse(input);\n if (!result.success) {\n const lines = result.error.issues.map((i) => {\n const path = i.path.length > 0 ? i.path.join('.') : '<root>';\n return ` ${path}: ${i.message}`;\n });\n throw new ManifestError(`Manifest failed validation:\\n${lines.join('\\n')}`, result.error.issues);\n }\n return result.data;\n}\n\nexport async function writeManifest(path: string, manifest: Manifest): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(manifest, null, 2) + '\\n', 'utf8');\n}\n","import { z } from 'zod';\n\nconst atField = {\n at: z.number().nonnegative().optional(),\n at_word: z.string().min(1).optional(),\n at_occurrence: z.number().int().positive().optional(),\n};\n\nconst selectorField = z.union([z.string().min(1), z.array(z.string().min(1)).nonempty()]);\nexport type SelectorSpec = z.infer<typeof selectorField>;\n\nconst idleAction = z.object({ type: z.literal('idle'), ...atField });\nconst clickAction = z.object({ type: z.literal('click'), selector: selectorField, ...atField });\nconst fillAction = z.object({\n type: z.literal('fill'),\n selector: selectorField,\n value: z.string(),\n ...atField,\n});\nconst typeAction = z.object({\n type: z.literal('type'),\n selector: selectorField,\n value: z.string(),\n ...atField,\n});\nconst hoverAction = z.object({ type: z.literal('hover'), selector: selectorField, ...atField });\nconst scrollAction = z.object({\n type: z.literal('scroll'),\n selector: selectorField,\n direction: z.enum(['up', 'down']),\n ...atField,\n});\nconst navigateAction = z.object({ type: z.literal('navigate'), url: z.string(), ...atField });\nconst waitForAction = z.object({ type: z.literal('wait_for'), selector: selectorField, ...atField });\nconst waitForUrlAction = z.object({\n type: z.literal('wait_for_url'),\n pattern: z.string(),\n ...atField,\n});\nconst waitAction = z.object({\n type: z.literal('wait'),\n ms: z.number().int().nonnegative(),\n ...atField,\n});\nconst assertVisibleAction = z.object({\n type: z.literal('assert_visible'),\n selector: selectorField,\n ...atField,\n});\nconst pressAction = z.object({\n type: z.literal('press'),\n key: z.string(),\n selector: selectorField.optional(),\n ...atField,\n});\nconst customAction = z.object({ type: z.literal('custom'), js: z.string(), ...atField });\n\nexport const actionSchema = z.discriminatedUnion('type', [\n idleAction,\n clickAction,\n fillAction,\n typeAction,\n hoverAction,\n scrollAction,\n navigateAction,\n waitForAction,\n waitForUrlAction,\n waitAction,\n assertVisibleAction,\n pressAction,\n customAction,\n]);\n\nconst transitionSchema = z\n .enum(['cut', 'fade', 'fade_in', 'fade_out', 'dissolve'])\n .default('cut');\n\nexport const segmentSchema = z\n .object({\n id: z.string().min(1),\n label: z.string().min(1),\n start: z.number().nonnegative(),\n end: z.number().positive(),\n vo_line: z.string(),\n actions: z.array(actionSchema).default([{ type: 'idle' }]),\n transition: transitionSchema,\n })\n .refine((s) => s.end > s.start, {\n message: 'segment.end must be greater than segment.start',\n path: ['end'],\n });\n\nexport const manifestSchema = z\n .object({\n total_duration_seconds: z.number().positive(),\n generated_from: z.string().default('product_model.json'),\n segments: z.array(segmentSchema).min(1),\n })\n .superRefine((m, ctx) => {\n for (let i = 1; i < m.segments.length; i++) {\n const prev = m.segments[i - 1]!;\n const cur = m.segments[i]!;\n if (cur.start < prev.end - 1e-6) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['segments', i, 'start'],\n message: `segment \"${cur.id}\" starts before previous segment \"${prev.id}\" ends`,\n });\n }\n }\n const lastEnd = m.segments[m.segments.length - 1]!.end;\n if (Math.abs(lastEnd - m.total_duration_seconds) > 0.5) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['total_duration_seconds'],\n message: `total_duration_seconds (${m.total_duration_seconds}) does not match last segment end (${lastEnd})`,\n });\n }\n });\n\nexport type Manifest = z.infer<typeof manifestSchema>;\nexport type Segment = z.infer<typeof segmentSchema>;\nexport type Action = z.infer<typeof actionSchema>;\nexport type Transition = z.infer<typeof transitionSchema>;\n\nexport const ACTION_TYPES = [\n 'idle',\n 'click',\n 'fill',\n 'type',\n 'hover',\n 'scroll',\n 'navigate',\n 'wait_for',\n 'wait_for_url',\n 'wait',\n 'assert_visible',\n 'press',\n 'custom',\n] as const;\nexport type ActionType = (typeof ACTION_TYPES)[number];\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { Action, Manifest, Segment, SelectorSpec } from './schema.js';\nimport type { RecordingConfig } from '../config/schema.js';\n\nexport interface CodegenInputs {\n manifest: Manifest;\n recording: RecordingConfig;\n targetUrl: string;\n videoDir: string;\n traceDir: string;\n}\n\nconst HEADER = `// scripts/playwright_demo.ts\n// GENERATED FILE — DO NOT EDIT DIRECTLY.\n// Regenerated from scripts/manifest.json on every \\`showrunner run\\`.\n// Edit the manifest instead, then re-run the script stage.\n`;\n\nexport function renderPlaywrightSpec(inputs: CodegenInputs): string {\n const { manifest, recording, targetUrl, videoDir, traceDir } = inputs;\n\n const launchLines = [\n `import { chromium, firefox, webkit, type BrowserContext } from 'playwright-core';`,\n `import { mkdirSync } from 'node:fs';`,\n ``,\n `const VIDEO_DIR = ${JSON.stringify(videoDir)};`,\n `const TRACE_DIR = ${JSON.stringify(traceDir)};`,\n `const TARGET_URL = ${JSON.stringify(targetUrl)};`,\n `const STORAGE_STATE = process.env['SHOWRUNNER_STORAGE_STATE'] ?? undefined;`,\n ``,\n `mkdirSync(VIDEO_DIR, { recursive: true });`,\n `mkdirSync(TRACE_DIR, { recursive: true });`,\n ``,\n `const browserMap = { chromium, firefox, webkit } as const;`,\n `const browser = await browserMap[${JSON.stringify(recording.browser)}].launch({ headless: ${recording.headless} });`,\n `const context = await browser.newContext({`,\n ` viewport: { width: ${recording.viewport.width}, height: ${recording.viewport.height} },`,\n ` recordVideo: { dir: VIDEO_DIR, size: { width: ${recording.viewport.width}, height: ${recording.viewport.height} } },`,\n ` storageState: STORAGE_STATE,`,\n `});`,\n ``,\n `await context.tracing.start({ screenshots: true, snapshots: true, sources: true });`,\n ``,\n `const page = await context.newPage();`,\n `await page.goto(TARGET_URL);`,\n ``,\n `function logMarker(kind: 'start' | 'end', segment: string, t: number): void {`,\n ` process.stdout.write(JSON.stringify({ event: 'segment_' + kind, segment, t, wall_ms: Date.now() }) + '\\\\n');`,\n `}`,\n ``,\n `async function runSegment(ctx: BrowserContext, id: string, runner: () => Promise<void>): Promise<void> {`,\n ` await ctx.tracing.startChunk({ title: id });`,\n ` const t0 = performance.now();`,\n ` logMarker('start', id, t0);`,\n ` try {`,\n ` await runner();`,\n ` } finally {`,\n ` logMarker('end', id, performance.now());`,\n ` await ctx.tracing.stopChunk({ path: \\`\\${TRACE_DIR}/\\${id}.zip\\` });`,\n ` }`,\n `}`,\n ];\n\n const segmentBlocks = manifest.segments.map((s) => renderSegmentBlock(s)).join('\\n');\n\n const tail = [\n `await context.close();`,\n `await browser.close();`,\n `process.stdout.write(JSON.stringify({ event: 'recording_complete' }) + '\\\\n');`,\n ];\n\n return [HEADER, launchLines.join('\\n'), '', segmentBlocks, tail.join('\\n'), ''].join('\\n');\n}\n\nfunction renderSegmentBlock(seg: Segment): string {\n const head = `// segment: ${seg.id} (${formatRange(seg.start, seg.end)}) — ${seg.label}`;\n const actionLines = seg.actions.map((a) => ` ${renderAction(a)}`).join('\\n');\n return [\n head,\n `await runSegment(context, ${JSON.stringify(seg.id)}, async () => {`,\n actionLines || ' // no actions',\n `});`,\n ``,\n ].join('\\n');\n}\n\nfunction flattenSelector(sel: SelectorSpec): string {\n return Array.isArray(sel) ? sel.join(', ') : sel;\n}\n\nfunction renderAction(action: Action): string {\n switch (action.type) {\n case 'idle':\n return '/* idle — camera holds */';\n case 'click':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().click();`;\n case 'fill':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().fill(${JSON.stringify(action.value)});`;\n case 'type':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().pressSequentially(${JSON.stringify(action.value)});`;\n case 'hover':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().hover();`;\n case 'scroll': {\n const dy = action.direction === 'down' ? 'el.scrollHeight' : '-el.scrollHeight';\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().evaluate((el) => { el.scrollTop = ${dy}; });`;\n }\n case 'navigate':\n return `await page.goto(${JSON.stringify(action.url)});`;\n case 'wait_for':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().waitFor({ state: 'attached' });`;\n case 'wait_for_url':\n return `await page.waitForURL(${JSON.stringify(action.pattern)});`;\n case 'wait':\n return `await page.waitForTimeout(${action.ms});`;\n case 'assert_visible':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().waitFor({ state: 'visible' });`;\n case 'press':\n return action.selector\n ? `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().press(${JSON.stringify(action.key)});`\n : `await page.keyboard.press(${JSON.stringify(action.key)});`;\n case 'custom':\n return `await page.evaluate(async () => { ${action.js} });`;\n }\n}\n\nfunction formatRange(start: number, end: number): string {\n return `${start.toFixed(2)}s – ${end.toFixed(2)}s`;\n}\n\nexport async function writePlaywrightSpec(path: string, inputs: CodegenInputs): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderPlaywrightSpec(inputs), 'utf8');\n}\n\nconst PREVIEW_HEADER = `// scripts/playwright_demo.spec.ts\n// GENERATED FILE — DO NOT EDIT DIRECTLY.\n// Lightweight @playwright/test wrapper used by \\`showrunner preview\\` (UI Mode).\n// Mirrors playwright_demo.ts but inside test() so Playwright's runner can drive it.\n`;\n\nexport function renderPlaywrightPreviewSpec(inputs: CodegenInputs): string {\n const { manifest, recording, targetUrl } = inputs;\n const segmentBlocks = manifest.segments\n .map((s) => {\n const head = ` // segment: ${s.id} (${formatRange(s.start, s.end)}) — ${s.label}`;\n const lines = s.actions.map((a) => ` ${renderAction(a)}`).join('\\n');\n return [head, lines || ' // no actions', ''].join('\\n');\n })\n .join('\\n');\n\n const usesExpect = manifest.segments.some((s) =>\n s.actions.some((a) => a.type === 'assert_visible'),\n );\n const playwrightImport = usesExpect\n ? `import { test, expect } from '@playwright/test';`\n : `import { test } from '@playwright/test';`;\n\n const body = [\n playwrightImport,\n ``,\n `test('preview', async ({ page }) => {`,\n ` test.setTimeout(120_000);`,\n ` await page.setViewportSize({ width: ${recording.viewport.width}, height: ${recording.viewport.height} });`,\n ` await page.goto(${JSON.stringify(targetUrl)});`,\n ``,\n segmentBlocks,\n `});`,\n ``,\n ];\n\n return [PREVIEW_HEADER, body.join('\\n')].join('\\n');\n}\n\nexport async function writePlaywrightPreviewSpec(\n path: string,\n inputs: CodegenInputs,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderPlaywrightPreviewSpec(inputs), 'utf8');\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { Manifest } from './schema.js';\n\nexport interface VoScriptOptions {\n projectName: string;\n generatedAt?: Date;\n}\n\nexport function renderVoScript(manifest: Manifest, opts: VoScriptOptions): string {\n const date = (opts.generatedAt ?? new Date()).toISOString().slice(0, 10);\n const lines: string[] = [\n `# Showrunner VO Script — ${opts.projectName}`,\n `# Total duration: ${formatDuration(manifest.total_duration_seconds)}`,\n `# Generated: ${date}`,\n ``,\n `# Edit the VO text below. Do not change the [m:ss] timestamps or line order.`,\n `# Re-run \\`showrunner approve-vo\\` to merge your edits back into the manifest.`,\n ``,\n ];\n for (const seg of manifest.segments) {\n lines.push(`[${formatTimestamp(seg.start)}] ${seg.vo_line}`);\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport async function writeVoScript(\n path: string,\n manifest: Manifest,\n opts: VoScriptOptions,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderVoScript(manifest, opts), 'utf8');\n}\n\nexport class VoScriptMergeError extends Error {\n override readonly name = 'VoScriptMergeError';\n}\n\ninterface ParsedLine {\n start: number;\n text: string;\n raw: string;\n lineNumber: number;\n}\n\nconst LINE_PATTERN = /^\\[(\\d+):(\\d{1,2})\\]\\s?(.*)$/;\n\nexport function parseVoScript(content: string): ParsedLine[] {\n const out: ParsedLine[] = [];\n const rawLines = content.split(/\\r?\\n/);\n for (let i = 0; i < rawLines.length; i++) {\n const raw = rawLines[i]!;\n const trimmed = raw.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n const match = LINE_PATTERN.exec(trimmed);\n if (!match) {\n throw new VoScriptMergeError(\n `Line ${i + 1} doesn't match \\`[m:ss] text\\` format: ${JSON.stringify(raw)}`,\n );\n }\n const minutes = Number(match[1]);\n const seconds = Number(match[2]);\n if (seconds >= 60) {\n throw new VoScriptMergeError(`Line ${i + 1}: seconds must be < 60`);\n }\n out.push({\n start: minutes * 60 + seconds,\n text: (match[3] ?? '').trim(),\n raw,\n lineNumber: i + 1,\n });\n }\n return out;\n}\n\nexport function mergeVoScript(manifest: Manifest, content: string): Manifest {\n const parsed = parseVoScript(content);\n if (parsed.length !== manifest.segments.length) {\n throw new VoScriptMergeError(\n `VO script has ${parsed.length} line(s); manifest has ${manifest.segments.length} segment(s). ` +\n `Adding or removing lines is not supported — regenerate the script via \\`showrunner run --force script\\`.`,\n );\n }\n const merged: Manifest = {\n ...manifest,\n segments: manifest.segments.map((seg, i) => {\n const line = parsed[i]!;\n if (Math.abs(line.start - seg.start) > 0.5) {\n throw new VoScriptMergeError(\n `Line ${line.lineNumber} timestamp [${formatTimestamp(line.start)}] does not match ` +\n `segment \"${seg.id}\" start (${formatTimestamp(seg.start)}). ` +\n `Did you reorder or retime lines? Regenerate via \\`showrunner run --force script\\`.`,\n );\n }\n return { ...seg, vo_line: line.text };\n }),\n };\n return merged;\n}\n\nexport async function readAndMergeVoScript(path: string, manifest: Manifest): Promise<Manifest> {\n const content = await readFile(path, 'utf8');\n return mergeVoScript(manifest, content);\n}\n\nfunction formatTimestamp(totalSeconds: number): string {\n const m = Math.floor(totalSeconds / 60);\n const s = Math.floor(totalSeconds - m * 60);\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n return formatTimestamp(totalSeconds);\n}\n","import { z, type ZodTypeAny } from 'zod';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface WithRetryOptions<S extends ZodTypeAny> extends GenerateStructuredOptions<S> {\n /**\n * Build the follow-up user prompt when the first attempt fails to validate\n * or parse. Receives the prior error text so the model can correct itself.\n * If undefined, no retry happens.\n */\n retryRenderer?: (errorText: string, previousUserPrompt: string) => string;\n}\n\n/**\n * Two-attempt structured generation. Provider does single-shot; this helper\n * captures schema-validation failures and re-prompts with the error context.\n * Most call sites that benefit from this are the manifest + product-model\n * generators (the ones whose schemas are complex enough that first-pass output\n * occasionally drifts). Single-shot call sites (like `instrument`) skip this\n * helper and call provider.generateStructured directly.\n */\nexport async function generateWithRetry<S extends ZodTypeAny>(\n provider: LLMProvider,\n opts: WithRetryOptions<S>,\n): Promise<z.infer<S>> {\n try {\n return await provider.generateStructured(opts);\n } catch (err) {\n const errText = formatErrorText(err);\n if (!opts.retryRenderer) {\n throw err;\n }\n logger.warn('Structured generation failed on first attempt; retrying with error feedback', {\n error: errText.slice(0, 200),\n });\n const retryPrompt = opts.retryRenderer(errText, opts.userPrompt);\n try {\n return await provider.generateStructured({ ...opts, userPrompt: retryPrompt });\n } catch (secondErr) {\n const secondErrText = formatErrorText(secondErr);\n throw new LLMProviderError(\n `Structured generation failed after one retry. Last error:\\n${secondErrText.slice(0, 2000)}`,\n 'unknown',\n secondErr,\n );\n }\n }\n}\n\nfunction formatErrorText(err: unknown): string {\n if (err instanceof z.ZodError) return err.message;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n","import type { z, ZodTypeAny } from 'zod';\n\nexport interface GenerateStructuredOptions<S extends ZodTypeAny> {\n systemPrompt: string;\n userPrompt: string;\n schema: S;\n /**\n * Hint for providers that need a schema name (OpenAI's json_schema format\n * requires one). Defaults to \"output\" if a provider needs one and none given.\n */\n schemaName?: string;\n /** Soft ceiling on output tokens; provider may interpret loosely. */\n maxTokens?: number;\n}\n\nexport interface LLMProvider {\n /** Single-shot structured generation. Retry/feedback lives at the call layer. */\n generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>>;\n}\n\nexport class LLMProviderError extends Error {\n override readonly name = 'LLMProviderError';\n constructor(\n message: string,\n readonly providerName: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n","import type { ProductModel } from '../productModel/schema.js';\nimport type { ScriptConfig } from '../config/schema.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\n\nexport const MANIFEST_GENERATOR_SYSTEM_PROMPT = `You are Showrunner's manifest generator. You produce a JSON manifest that drives an automated product-demo recording pipeline. The manifest you emit is the single source of truth for timing, on-screen actions, and voiceover lines.\n\n# What you produce\n\nA JSON object matching this shape:\n\n- \\`total_duration_seconds\\`: number, total demo length\n- \\`generated_from\\`: string, set to \"product_model.json\"\n- \\`segments\\`: an ordered, contiguous array of segment objects\n\nEach segment has:\n- \\`id\\`: kebab-case identifier (e.g. \"navigate-tests\")\n- \\`label\\`: human-readable title\n- \\`start\\`, \\`end\\`: seconds from demo start. Segments are contiguous (next.start === prev.end).\n- \\`vo_line\\`: spoken voiceover for this segment. Write it like a person would say it.\n- \\`actions\\`: array of UI actions to perform. See the table below.\n- \\`transition\\`: one of \"cut\", \"fade\", \"fade_in\", \"fade_out\", \"dissolve\". Use \"fade_in\" on the first segment.\n\n# Supported action types (use only these)\n\n| type | required fields | meaning |\n|---|---|---|\n| idle | — | no interaction; camera holds |\n| click | selector | click an element |\n| fill | selector, value | clear and type into an input |\n| type | selector, value | type without clearing (appends) |\n| hover | selector | hover over an element |\n| scroll | selector, direction (\"up\" or \"down\") | scroll inside an element |\n| navigate | url | full navigation to a URL |\n| wait_for | selector | wait until the element is visible |\n| wait_for_url | pattern | wait until URL matches a glob pattern |\n| wait | ms | explicit pause |\n| assert_visible | selector | assert element exists, fail segment if not |\n| custom | js | inline JavaScript executed in page context (fallback only) |\n\n# Selector hierarchy (most → least resilient)\n\n1. \\`[data-testid=\"...\"]\\` attributes — prefer these whenever the product model mentions them\n2. ARIA role + accessible name — use Playwright-style selectors like \\`role=button[name=\"Save\"]\\`\n3. Text content — \\`text=Save changes\\`\n4. CSS selectors — only as a last resort\n\nIf a \"Live DOM selector inventory\" section is provided, treat it as ground truth:\n- Every \\`selector\\` you emit for click/fill/type/hover/scroll/wait_for/assert_visible MUST appear **verbatim** in that list. Copy the \\`selector\\` string character-for-character — don't paraphrase, don't translate to a different selector format, don't merge or split.\n- For \\`:has-text(\"...\")\\` selectors specifically, the text inside the quotes must be the inventory entry's \\`visibleText\\` field **exactly**, including punctuation, arrows (→), and capitalization.\n- If the inventory can't satisfy a step (e.g. the page lacks a \"Pricing\" link), prefer dropping the action, using \\`wait\\`, or picking a related inventory entry — never invent a selector from product-model wording.\n\n**CSS class-name rules (when you do use a CSS path):** Do not include class names with bracketed values like \\`.max-w-[1280px]\\`, \\`.bg-[#abc]\\`, \\`.text-[20px]\\` — these are Tailwind shorthand, not legal CSS. Playwright will reject them with a SyntaxError. If a class is unstable or bracket-laden, walk up to the parent or use a different selector family entirely.\n\nIf no inventory is provided AND the product model does not specify selectors, infer plausible \\`data-testid\\` values from the flow step language (e.g. step \"Click New Test\" → \\`[data-testid='btn-new-test']\\`). Mark these as inferred in your reasoning if asked, but do not annotate the JSON itself.\n\n# Timing guidance\n\n- Aim for the script config's \\`duration_target_seconds\\`. Distribute it across segments by how much screen-time each step needs.\n- Intro segment: ~6–10s. Outro segment: ~4–8s.\n- A click-only step needs ~3–5s of screen time. A fill+submit cycle needs ~6–12s.\n- Make sure the final segment's \\`end\\` equals \\`total_duration_seconds\\`.\n\n# Voiceover guidance\n\n- Tone follows the script config's \\`style\\` field.\n- One \\`vo_line\\` per segment. Write spoken English — contractions are fine, but avoid filler.\n- Length should fit roughly inside the segment duration at conversational pace (~2.5 words per second). Slightly under is better than over.\n- Highlight the features named in the script config when possible.\n\n# Output discipline\n\n- Emit JSON only. No prose, no markdown fences.\n- All segment start/end times are floats in seconds.\n- segments[i].start === segments[i-1].end (contiguous).\n- segments[0].start === 0.\n`;\n\nexport function renderManifestUserPrompt(\n productModel: ProductModel,\n scriptConfig: ScriptConfig,\n selectorInventory?: SelectorInventoryItem[],\n): string {\n const parts = [\n 'Generate a manifest for the product described below.',\n '',\n '## Script configuration',\n `- style: ${scriptConfig.style}`,\n `- duration_target_seconds: ${scriptConfig.duration_target_seconds}`,\n `- highlight_features: ${\n scriptConfig.highlight_features.length === 0\n ? '(none specified — choose them yourself from the product model)'\n : JSON.stringify(scriptConfig.highlight_features)\n }`,\n '',\n '## Product model',\n '```json',\n JSON.stringify(productModel, null, 2),\n '```',\n ];\n if (selectorInventory && selectorInventory.length > 0) {\n parts.push(\n '',\n '## Live DOM selector inventory',\n `Scraped from the target URL. Use ONLY selectors from this list. ${selectorInventory.length} entries:`,\n '```json',\n JSON.stringify(selectorInventory, null, 2),\n '```',\n );\n }\n return parts.join('\\n');\n}\n\nexport function renderRetryPrompt(\n productModel: ProductModel,\n scriptConfig: ScriptConfig,\n validationError: string,\n selectorInventory?: SelectorInventoryItem[],\n): string {\n return [\n renderManifestUserPrompt(productModel, scriptConfig, selectorInventory),\n '',\n '## Previous attempt failed validation',\n 'Your previous response did not pass validation. Fix these issues and emit a corrected manifest:',\n '```',\n validationError,\n '```',\n ].join('\\n');\n}\n","import type { Action, Manifest } from '../manifest/schema.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\n\nexport interface SelectorViolation {\n segmentId: string;\n actionIndex: number;\n actionType: Action['type'];\n selector: string;\n reason: 'invalid_css_brackets' | 'not_in_inventory';\n hint?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n violations: SelectorViolation[];\n}\n\n/**\n * Tailwind class names with arbitrary-value brackets (e.g. `max-w-[1280px]`,\n * `bg-[#abc123]`) are common in modern CSS but are NOT legal CSS selectors —\n * Playwright will reject them with a SyntaxError. The LLM occasionally\n * synthesizes these when it walks up the DOM tree to build a fallback path.\n *\n * Match `.foo-[anything]` or `.foo[anything]` inside a CSS path segment.\n * (We don't ban legit attribute selectors like `[data-testid=\"x\"]` — those\n * stand alone, not glued to a class name.)\n */\nconst BRACKET_IN_CLASS_RE = /\\.[a-z0-9_-]+\\[[^\\]]+\\]/i;\n\nexport function validateManifestSelectors(\n manifest: Manifest,\n inventory: SelectorInventoryItem[],\n): ValidationResult {\n const inventorySet = new Set(inventory.map((i) => i.selector));\n const violations: SelectorViolation[] = [];\n\n for (const segment of manifest.segments) {\n for (let i = 0; i < segment.actions.length; i++) {\n const action = segment.actions[i]!;\n const selectors = extractSelectors(action);\n for (const sel of selectors) {\n if (BRACKET_IN_CLASS_RE.test(sel)) {\n violations.push({\n segmentId: segment.id,\n actionIndex: i,\n actionType: action.type,\n selector: sel,\n reason: 'invalid_css_brackets',\n hint:\n `Tailwind arbitrary-value classes like \\`.max-w-[1280px]\\` are not legal CSS selectors. ` +\n `Drop the bracket class from the path, or pick an inventory entry instead.`,\n });\n continue;\n }\n if (!inventorySet.has(sel)) {\n violations.push({\n segmentId: segment.id,\n actionIndex: i,\n actionType: action.type,\n selector: sel,\n reason: 'not_in_inventory',\n hint: 'This selector was not in the live DOM inventory. Pick one from the inventory list.',\n });\n }\n }\n }\n }\n\n return { ok: violations.length === 0, violations };\n}\n\nfunction extractSelectors(action: Action): string[] {\n // Actions without selectors (idle, navigate, wait, wait_for_url, custom) → skip\n switch (action.type) {\n case 'idle':\n case 'navigate':\n case 'wait':\n case 'wait_for_url':\n case 'custom':\n return [];\n case 'press':\n return action.selector ? toArray(action.selector) : [];\n default:\n return toArray(action.selector);\n }\n}\n\nfunction toArray(sel: string | readonly string[]): string[] {\n return typeof sel === 'string' ? [sel] : [...sel];\n}\n\n/**\n * Render a remediation prompt the LLM can use to fix a manifest whose\n * selectors didn't pass `validateManifestSelectors`.\n */\nexport function renderSelectorRemediation(violations: SelectorViolation[]): string {\n const lines: string[] = [\n 'Your previous manifest passed schema validation but its selectors are not usable:',\n '',\n ];\n for (const v of violations) {\n lines.push(\n `- Segment \"${v.segmentId}\", action ${v.actionIndex} (${v.actionType}): selector \\`${v.selector}\\` — ${v.reason}.`,\n );\n if (v.hint) lines.push(` ${v.hint}`);\n }\n lines.push('');\n lines.push(\n 'Re-emit the manifest. Every click/fill/type/hover/scroll/wait_for/assert_visible selector MUST appear verbatim in the live DOM selector inventory section above. For `:has-text` selectors, copy the `visibleText` field from the matching inventory entry exactly.',\n );\n return lines.join('\\n');\n}\n","import { parseManifest, ManifestError } from '../manifest/io.js';\nimport { manifestSchema, type Manifest } from '../manifest/schema.js';\nimport type { ProductModel } from '../productModel/schema.js';\nimport type { ScriptConfig } from '../config/schema.js';\nimport { logger } from '../util/logger.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\nimport { generateWithRetry } from '../providers/llm/withRetry.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\nimport {\n MANIFEST_GENERATOR_SYSTEM_PROMPT,\n renderManifestUserPrompt,\n renderRetryPrompt,\n} from './prompts.js';\nimport {\n renderSelectorRemediation,\n validateManifestSelectors,\n} from './validateSelectors.js';\n\nconst DEFAULT_MAX_TOKENS = 16000;\n\nexport interface GenerateManifestOptions {\n productModel: ProductModel;\n scriptConfig: ScriptConfig;\n provider: LLMProvider;\n selectorInventory?: SelectorInventoryItem[];\n}\n\nexport class ManifestGenerationError extends Error {\n override readonly name = 'ManifestGenerationError';\n}\n\nexport async function generateManifest(opts: GenerateManifestOptions): Promise<Manifest> {\n logger.debug('Generating manifest via LLM provider');\n try {\n const parsed = await generateWithRetry(opts.provider, {\n systemPrompt: MANIFEST_GENERATOR_SYSTEM_PROMPT,\n userPrompt: renderManifestUserPrompt(\n opts.productModel,\n opts.scriptConfig,\n opts.selectorInventory,\n ),\n schema: manifestSchema,\n schemaName: 'manifest',\n maxTokens: DEFAULT_MAX_TOKENS,\n retryRenderer: (errorText) =>\n renderRetryPrompt(\n opts.productModel,\n opts.scriptConfig,\n errorText,\n opts.selectorInventory,\n ),\n });\n\n let manifest: Manifest;\n try {\n manifest = parseManifest(parsed);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new ManifestGenerationError(`Manifest validation failed: ${err.message}`);\n }\n throw err;\n }\n\n // Post-validation: only if we have an inventory to compare against. With\n // no inventory the manifest's selectors are best-effort regardless.\n if (opts.selectorInventory && opts.selectorInventory.length > 0) {\n const check = validateManifestSelectors(manifest, opts.selectorInventory);\n if (!check.ok) {\n logger.warn(\n `manifest selector check failed: ${check.violations.length} violation(s) — retrying with remediation`,\n { violations: check.violations.length },\n );\n for (const v of check.violations.slice(0, 5)) {\n logger.debug(` ${v.segmentId}/${v.actionIndex}: ${v.reason} — ${v.selector}`);\n }\n\n const remediationUserPrompt = [\n renderManifestUserPrompt(opts.productModel, opts.scriptConfig, opts.selectorInventory),\n '',\n renderSelectorRemediation(check.violations),\n ].join('\\n');\n\n const retryResult = await opts.provider.generateStructured({\n systemPrompt: MANIFEST_GENERATOR_SYSTEM_PROMPT,\n userPrompt: remediationUserPrompt,\n schema: manifestSchema,\n schemaName: 'manifest',\n maxTokens: DEFAULT_MAX_TOKENS,\n });\n\n let retried: Manifest;\n try {\n retried = parseManifest(retryResult);\n } catch (err) {\n // Retry returned schema-invalid output — fall back to the first manifest\n // (violations and all). The record stage will warn per-failed-action\n // rather than crashing the whole pipeline.\n logger.warn(\n `selector-remediation retry returned schema-invalid output — keeping original manifest`,\n { error: err instanceof Error ? err.message : String(err) },\n );\n return manifest;\n }\n\n const recheck = validateManifestSelectors(retried, opts.selectorInventory);\n if (recheck.ok) {\n logger.event({ stage: 'script', status: 'selector_retry_resolved', segments: retried.segments.length });\n } else {\n logger.warn(\n `selector-remediation retry still has ${recheck.violations.length} violation(s) — accepting anyway`,\n { remaining: recheck.violations.length },\n );\n }\n return retried;\n }\n }\n\n return manifest;\n } catch (err) {\n if (err instanceof ManifestGenerationError) throw err;\n throw new ManifestGenerationError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { chromium, firefox, webkit } from 'playwright-core';\nimport type { RecordingConfig } from '../config/schema.js';\nimport { SELECTOR_FOR_FN_SOURCE } from '../recording/selectorHeuristic.js';\nimport { logger } from '../util/logger.js';\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport interface SelectorInventoryItem {\n tag: string;\n selector: string;\n visibleText?: string;\n role?: string;\n dataTestid?: string;\n name?: string;\n placeholder?: string;\n ariaLabel?: string;\n href?: string;\n}\n\nexport interface ScrapeOptions {\n targetUrl: string;\n recording: RecordingConfig;\n /** Network-idle ceiling. Falls back to load if it never fires. Default 3000ms. */\n networkIdleTimeoutMs?: number;\n /** Hard navigation timeout. Default 15000ms. */\n navigationTimeoutMs?: number;\n /** Maximum items returned (truncates from the end). Default 200. */\n maxItems?: number;\n}\n\n/**\n * Launches Playwright once, navigates to the target, and snapshots the\n * actionable DOM into a flat selector inventory. The LLM in the `script`\n * stage uses this as ground truth so it can't hallucinate selectors.\n *\n * Failure is non-fatal — caller should treat a thrown error as \"skip preflight\n * and fall back to LLM-only generation,\" logging a warning.\n */\nexport async function scrapeSelectorInventory(\n opts: ScrapeOptions,\n): Promise<SelectorInventoryItem[]> {\n const networkIdleMs = opts.networkIdleTimeoutMs ?? 3000;\n const navigationMs = opts.navigationTimeoutMs ?? 15000;\n const maxItems = opts.maxItems ?? 200;\n\n const browser = await browserMap[opts.recording.browser].launch({ headless: true });\n try {\n const context = await browser.newContext({\n viewport: {\n width: opts.recording.viewport.width,\n height: opts.recording.viewport.height,\n },\n });\n const page = await context.newPage();\n page.setDefaultNavigationTimeout(navigationMs);\n await page.goto(opts.targetUrl, { waitUntil: 'load' });\n try {\n await page.waitForLoadState('networkidle', { timeout: networkIdleMs });\n } catch {\n logger.debug('domPreflight: networkidle did not fire within budget — proceeding');\n }\n\n const items = (await page.evaluate(\n buildScrapeScript(SELECTOR_FOR_FN_SOURCE, maxItems),\n )) as SelectorInventoryItem[];\n\n await context.close();\n return items;\n } finally {\n await browser.close();\n }\n}\n\n/**\n * Build the in-page scrape script as a string. Returning the function body as\n * a string lets us reuse the shared SELECTOR_FOR_FN_SOURCE and sidesteps the\n * tsconfig DOM-lib issue (the host project doesn't include DOM types).\n */\nfunction buildScrapeScript(selectorSource: string, maxItems: number): string {\n return `(() => {\n ${selectorSource}\n\n var QUERY = 'button, a, input, textarea, select, summary, label, h1, h2, h3, [role=button], [role=link], [role=textbox], [data-testid], [data-test-id]';\n var nodes = Array.from(document.querySelectorAll(QUERY));\n var out = [];\n var seen = new Set();\n\n for (var i = 0; i < nodes.length; i++) {\n var el = nodes[i];\n if (!el || el.nodeType !== 1) continue;\n var rect = el.getBoundingClientRect();\n var styles = window.getComputedStyle(el);\n var visible = rect.width > 0 && rect.height > 0 && styles.visibility !== 'hidden' && styles.display !== 'none' && styles.opacity !== '0';\n if (!visible) continue;\n\n var selector = selectorFor(el);\n if (!selector) continue;\n if (seen.has(selector)) continue;\n seen.add(selector);\n\n var item = { tag: el.tagName.toLowerCase(), selector: selector };\n var rawText = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (rawText) item.visibleText = rawText.slice(0, 80);\n var role = el.getAttribute('role');\n if (role) item.role = role;\n var tid = el.getAttribute('data-testid') || el.getAttribute('data-test-id');\n if (tid) item.dataTestid = tid;\n var name = el.getAttribute('name');\n if (name) item.name = name;\n var placeholder = el.getAttribute('placeholder');\n if (placeholder) item.placeholder = placeholder;\n var aria = el.getAttribute('aria-label');\n if (aria) item.ariaLabel = aria;\n if (el.tagName === 'A' && el.href) item.href = el.href;\n out.push(item);\n if (out.length >= ${maxItems}) break;\n }\n return out;\n })()`;\n}\n","/**\n * The selector-preference heuristic used by `record-actions` (in-page event\n * capture) and `script` stage's DOM preflight (DOM scrape for selector inventory).\n *\n * Preference order:\n * 1. [data-testid=\"...\"]\n * 2. <tag>[name=\"...\"] for INPUT/TEXTAREA/SELECT\n * 3. <tag>[placeholder=\"...\"]\n * 4. [aria-label=\"...\"]\n * 5. #id (when id looks stable, not hash-like)\n * 6. <tag>:has-text(\"...\") for BUTTON/A/SUMMARY/LABEL with visible text\n * 7. Minimal CSS path (tag.class:nth-of-type, walked up to 5 levels)\n *\n * This module exports the function body as a string so it can be embedded\n * verbatim inside `page.evaluate` / `addInitScript` payloads (which can't\n * import from outside the page context).\n */\n\nexport const SELECTOR_FOR_FN_SOURCE = `\nfunction escapeAttr(v) {\n return String(v).replace(/\"/g, '\\\\\\\\\"');\n}\n\nfunction looksUnstable(s) {\n // hash-like ids and classnames are unstable. Examples:\n // \"css-1a2b3c\" - emotion/styled-components\n // \"x_abc123\" - generic\n // \"__variable_3eb911\" - Next.js compiled font/CSS variables\n // \"1a2b3c4d5e6f\" - bare hex hash\n // The leading \"_*\" tolerates one or more underscores at the start.\n return /^_*[a-z]+[-_][a-f0-9]{6,}$/i.test(s) || /^[a-zA-Z]?[a-f0-9]{8,}$/.test(s);\n}\n\nfunction selectorFor(el) {\n if (!el || el.nodeType !== 1) return null;\n const testid = el.getAttribute('data-testid') || el.getAttribute('data-test-id');\n if (testid) return '[data-testid=\"' + escapeAttr(testid) + '\"]';\n\n const name = el.getAttribute('name');\n if (name && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT')) {\n return el.tagName.toLowerCase() + '[name=\"' + escapeAttr(name) + '\"]';\n }\n\n const placeholder = el.getAttribute('placeholder');\n if (placeholder) return el.tagName.toLowerCase() + '[placeholder=\"' + escapeAttr(placeholder) + '\"]';\n\n const aria = el.getAttribute('aria-label');\n if (aria) return '[aria-label=\"' + escapeAttr(aria) + '\"]';\n\n if (el.id && !looksUnstable(el.id)) return '#' + el.id;\n\n const textTags = new Set(['BUTTON', 'A', 'SUMMARY', 'LABEL']);\n if (textTags.has(el.tagName)) {\n const text = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (text.length > 0 && text.length <= 64) {\n return el.tagName.toLowerCase() + ':has-text(\"' + escapeAttr(text) + '\")';\n }\n }\n\n const parts = [];\n let node = el;\n while (node && node.nodeType === 1 && parts.length < 5) {\n let part = node.tagName.toLowerCase();\n if (node.id && !looksUnstable(node.id)) {\n parts.unshift('#' + node.id);\n break;\n }\n const cls = (node.className || '').toString().split(/\\\\s+/).filter((c) => c && !looksUnstable(c));\n if (cls.length > 0) part += '.' + cls[0];\n const parent = node.parentElement;\n if (parent) {\n const same = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (same.length > 1) {\n const idx = same.indexOf(node) + 1;\n part += ':nth-of-type(' + idx + ')';\n }\n }\n parts.unshift(part);\n node = parent;\n }\n return parts.join(' > ');\n}\n`;\n","import Anthropic from '@anthropic-ai/sdk';\nimport { zodOutputFormat } from '@anthropic-ai/sdk/helpers/zod';\nimport type { ParsedMessage } from '@anthropic-ai/sdk/lib/parser';\nimport type { z, ZodTypeAny } from 'zod';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface AnthropicProviderConfig {\n apiKey: string;\n model: string;\n /** Default max_tokens when the call site doesn't override. */\n maxTokens?: number;\n}\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nexport class AnthropicLLMProvider implements LLMProvider {\n private readonly client: Anthropic;\n private readonly model: string;\n private readonly defaultMaxTokens: number;\n\n constructor(cfg: AnthropicProviderConfig) {\n if (!cfg.apiKey) {\n throw new LLMProviderError(\n 'AnthropicLLMProvider: apiKey is required',\n 'anthropic',\n );\n }\n this.client = new Anthropic({ apiKey: cfg.apiKey });\n this.model = cfg.model;\n this.defaultMaxTokens = cfg.maxTokens ?? DEFAULT_MAX_TOKENS;\n }\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const response = await this.client.messages.parse({\n model: this.model,\n max_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n thinking: { type: 'adaptive' as const },\n system: [\n {\n type: 'text' as const,\n text: opts.systemPrompt,\n cache_control: { type: 'ephemeral' as const },\n },\n ],\n output_config: { format: zodOutputFormat(opts.schema) },\n messages: [{ role: 'user', content: opts.userPrompt }],\n });\n\n return extractAndValidate(response, opts.schema);\n }\n}\n\nfunction extractAndValidate<S extends ZodTypeAny>(\n response: ParsedMessage<unknown>,\n schema: S,\n): z.infer<S> {\n if (response.parsed_output !== undefined && response.parsed_output !== null) {\n return schema.parse(response.parsed_output);\n }\n const text = response.content\n .filter((b): b is Anthropic.Messages.TextBlock => b.type === 'text')\n .map((b) => b.text)\n .join('\\n')\n .trim();\n throw new LLMProviderError(\n text.length > 0\n ? `Anthropic returned no parseable structured output. Raw text:\\n${text.slice(0, 2000)}`\n : 'Anthropic returned an empty response with no parseable output.',\n 'anthropic',\n );\n}\n","import OpenAI from 'openai';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { z, ZodTypeAny } from 'zod';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface OpenAIProviderConfig {\n apiKey: string;\n model: string;\n /** Default max output tokens. */\n maxTokens?: number;\n /** Override the API base (Azure / OpenRouter / etc). */\n baseURL?: string;\n}\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\n/**\n * Uses the OpenAI chat-completions API with `response_format: json_schema`\n * for native structured-output validation. Falls back to `json_object` mode\n * (free-form JSON + post-parse) when the schema is rejected (some Zod\n * constructs OpenAI's strict mode can't validate — discriminated unions,\n * deeply-nested z.record, etc).\n */\nexport class OpenAILLMProvider implements LLMProvider {\n private readonly client: OpenAI;\n private readonly model: string;\n private readonly defaultMaxTokens: number;\n\n constructor(cfg: OpenAIProviderConfig) {\n if (!cfg.apiKey) {\n throw new LLMProviderError(\n 'OpenAILLMProvider: apiKey is required',\n 'openai',\n );\n }\n this.client = new OpenAI({ apiKey: cfg.apiKey, baseURL: cfg.baseURL });\n this.model = cfg.model;\n this.defaultMaxTokens = cfg.maxTokens ?? DEFAULT_MAX_TOKENS;\n }\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const jsonSchema = patchSchemaForStrict(\n zodToJsonSchema(opts.schema, opts.schemaName ?? 'output'),\n );\n const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [\n { role: 'system', content: opts.systemPrompt },\n { role: 'user', content: opts.userPrompt },\n ];\n\n try {\n const response = await this.client.chat.completions.create({\n model: this.model,\n max_completion_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n messages,\n response_format: {\n type: 'json_schema',\n json_schema: {\n name: opts.schemaName ?? 'output',\n schema: jsonSchema as Record<string, unknown>,\n strict: true,\n },\n },\n });\n const raw = response.choices[0]?.message?.content ?? '';\n const parsed = safeJsonParse(raw);\n return opts.schema.parse(parsed);\n } catch (err) {\n // OpenAI rejects some schema shapes outright. Fall back to free-form\n // JSON output + post-parse via Zod.\n if (!isSchemaRejection(err)) throw wrap(err);\n logger.warn('OpenAI rejected the json_schema; falling back to json_object mode', {\n cause: err instanceof Error ? err.message : String(err),\n });\n const response = await this.client.chat.completions.create({\n model: this.model,\n max_completion_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n messages: [\n {\n role: 'system',\n content: `${opts.systemPrompt}\\n\\nRespond with a single JSON object that matches the schema described in the user message. Do not include any prose.`,\n },\n { role: 'user', content: opts.userPrompt },\n ],\n response_format: { type: 'json_object' },\n });\n const raw = response.choices[0]?.message?.content ?? '';\n const parsed = safeJsonParse(raw);\n return opts.schema.parse(parsed);\n }\n }\n}\n\nfunction isSchemaRejection(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const msg = (err as { message?: string }).message ?? '';\n return /Invalid schema|response_format|json_schema/i.test(msg);\n}\n\nfunction wrap(err: unknown): LLMProviderError {\n return new LLMProviderError(\n `OpenAI call failed: ${err instanceof Error ? err.message : String(err)}`,\n 'openai',\n err,\n );\n}\n\nfunction safeJsonParse(raw: string): unknown {\n const trimmed = raw.trim();\n if (!trimmed) {\n throw new LLMProviderError('OpenAI returned empty content', 'openai');\n }\n try {\n return JSON.parse(trimmed);\n } catch {\n // Some models still wrap output in a fence even when asked not to.\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)```/.exec(trimmed);\n if (fenced && fenced[1]) return JSON.parse(fenced[1].trim());\n throw new LLMProviderError(\n `OpenAI content was not valid JSON. First 500 chars:\\n${trimmed.slice(0, 500)}`,\n 'openai',\n );\n }\n}\n\n/**\n * OpenAI's strict json_schema rejects schemas that don't set\n * `additionalProperties: false` on every object node. Walk the tree and patch.\n */\nfunction patchSchemaForStrict(schema: unknown): unknown {\n if (Array.isArray(schema)) return schema.map(patchSchemaForStrict);\n if (schema && typeof schema === 'object') {\n const obj = { ...(schema as Record<string, unknown>) };\n if (obj['type'] === 'object' && obj['additionalProperties'] === undefined) {\n obj['additionalProperties'] = false;\n }\n for (const k of Object.keys(obj)) {\n obj[k] = patchSchemaForStrict(obj[k]);\n }\n return obj;\n }\n return schema;\n}\n","import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { z, ZodTypeAny } from 'zod';\nimport { runCommandCapture } from '../../recording/lifecycle.js';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport type AgentBridgeMode = 'spawn' | 'file_poll';\n\nexport interface AgentBridgeSpawnConfig {\n mode: 'spawn';\n /** Default `claude` */\n command: string;\n /** Default `['-p', '--output-format', 'json']` (Claude CLI headless mode). */\n args: string[];\n /** Kill the subprocess after this many ms. Default 300000 (5 minutes). */\n timeoutMs?: number;\n /** Run the child process in this directory. */\n cwd?: string;\n}\n\nexport interface AgentBridgeFilePollConfig {\n mode: 'file_poll';\n /** Directory where request files are written and response files are awaited. */\n requestDir: string;\n /** Polling interval (ms). Default 500. */\n pollIntervalMs?: number;\n /** Give up after this many ms. Default 600000 (10 minutes). */\n timeoutMs?: number;\n}\n\nexport type AgentBridgeConfig = AgentBridgeSpawnConfig | AgentBridgeFilePollConfig;\n\nconst FENCED_JSON = /```(?:json)?\\s*([\\s\\S]*?)```/;\n\nexport class AgentBridgeLLMProvider implements LLMProvider {\n constructor(private readonly cfg: AgentBridgeConfig) {}\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const jsonSchema = zodToJsonSchema(opts.schema, opts.schemaName ?? 'output');\n const prompt = renderBridgePrompt(opts.systemPrompt, opts.userPrompt, jsonSchema);\n\n let rawResponse: string;\n if (this.cfg.mode === 'spawn') {\n rawResponse = await invokeSpawn(this.cfg, prompt);\n } else {\n rawResponse = await invokeFilePoll(this.cfg, prompt);\n }\n\n const structured = extractJson(rawResponse);\n try {\n return opts.schema.parse(structured);\n } catch (err) {\n throw new LLMProviderError(\n `Agent bridge response did not match the expected schema: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'agent_bridge',\n err,\n );\n }\n }\n}\n\nfunction renderBridgePrompt(systemPrompt: string, userPrompt: string, jsonSchema: unknown): string {\n return [\n 'You are being called via a non-interactive bridge. Your job is to return ONLY a JSON object that conforms to the provided JSON Schema. No prose, no greeting, no markdown — emit just the JSON inside a single ```json fenced block.',\n '',\n '## System instructions for this task',\n systemPrompt,\n '',\n '## JSON Schema your response must satisfy',\n '```json',\n JSON.stringify(jsonSchema, null, 2),\n '```',\n '',\n '## Task',\n userPrompt,\n '',\n 'Respond with exactly one ```json ... ``` block containing the structured output. Do not include any text before or after the fence.',\n ].join('\\n');\n}\n\nasync function invokeSpawn(cfg: AgentBridgeSpawnConfig, prompt: string): Promise<string> {\n const result = await runCommandCapture({\n cmd: cfg.command,\n args: cfg.args,\n cwd: cfg.cwd,\n label: `llm-bridge:${cfg.command}`,\n stdin: prompt,\n timeoutMs: cfg.timeoutMs ?? 300_000,\n });\n if (result.exitCode !== 0) {\n throw new LLMProviderError(\n `Agent bridge command \\`${cfg.command}\\` exited with code ${result.exitCode}\\nstderr:\\n${result.stderr.slice(-2000)}`,\n 'agent_bridge',\n );\n }\n // Claude CLI in --output-format json mode emits a JSON envelope on stdout\n // with a `content` field (and other metadata like total_cost_usd). If we can\n // parse the envelope, prefer the content field; otherwise treat stdout as\n // the raw model output.\n const trimmed = result.stdout.trim();\n if (trimmed.startsWith('{')) {\n try {\n const envelope = JSON.parse(trimmed) as Record<string, unknown>;\n const content = envelope['content'] ?? envelope['result'];\n if (typeof content === 'string') return content;\n } catch {\n // Not a JSON envelope — fall through and treat stdout as raw text.\n }\n }\n return trimmed;\n}\n\nasync function invokeFilePoll(cfg: AgentBridgeFilePollConfig, prompt: string): Promise<string> {\n await mkdir(cfg.requestDir, { recursive: true });\n const id = randomUUID();\n const reqPath = join(cfg.requestDir, `${id}.request.json`);\n const resPath = join(cfg.requestDir, `${id}.response.json`);\n await writeFile(reqPath, JSON.stringify({ id, prompt }, null, 2) + '\\n', 'utf8');\n logger.info('Agent bridge: wrote LLM request, waiting for response', { reqPath, resPath });\n\n const pollInterval = cfg.pollIntervalMs ?? 500;\n const timeout = cfg.timeoutMs ?? 600_000;\n const deadline = Date.now() + timeout;\n\n while (Date.now() < deadline) {\n if (await fileExists(resPath)) {\n const raw = await readFile(resPath, 'utf8');\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const content = parsed['content'] ?? parsed['response'];\n if (typeof content === 'string') return content;\n return raw;\n } catch {\n return raw;\n }\n }\n await sleep(pollInterval);\n }\n\n throw new LLMProviderError(\n `Agent bridge (file_poll) timed out after ${timeout}ms waiting for ${resPath}`,\n 'agent_bridge',\n );\n}\n\nfunction extractJson(raw: string): unknown {\n const fenced = FENCED_JSON.exec(raw);\n if (fenced && fenced[1]) {\n try {\n return JSON.parse(fenced[1].trim());\n } catch {\n // fall through to balanced-brace extraction\n }\n }\n // Find the longest balanced { ... } block.\n const start = raw.indexOf('{');\n const end = raw.lastIndexOf('}');\n if (start === -1 || end <= start) {\n throw new LLMProviderError(\n `Agent bridge response contained no parseable JSON. First 500 chars:\\n${raw.slice(0, 500)}`,\n 'agent_bridge',\n );\n }\n const candidate = raw.slice(start, end + 1);\n try {\n return JSON.parse(candidate);\n } catch (err) {\n throw new LLMProviderError(\n `Agent bridge response had JSON-like text but it didn't parse: ${\n err instanceof Error ? err.message : String(err)\n }\\nFirst 500 chars:\\n${raw.slice(0, 500)}`,\n 'agent_bridge',\n );\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { spawn } from 'node:child_process';\nimport { stat } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { logger } from '../util/logger.js';\n\nexport class LifecycleScriptError extends Error {\n override readonly name = 'LifecycleScriptError';\n constructor(\n message: string,\n readonly script: string,\n readonly exitCode: number | null,\n ) {\n super(message);\n }\n}\n\nexport interface RunScriptOptions {\n scriptPath: string;\n configDir: string;\n env: Record<string, string>;\n label: string;\n}\n\nexport interface RunCommandOptions {\n cmd: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n label: string;\n /** When true, child inherits stdio (for interactive viewers like trace UI). */\n inherit?: boolean;\n}\n\n/**\n * Spawn an external command, prefix stdout/stderr lines with the label, and\n * resolve on exit-code-0 or reject with a LifecycleScriptError. Bypasses any\n * file-existence check — use this for commands like `npx playwright show-trace`\n * where the binary is resolved via the user's PATH.\n */\nexport async function runCommand(opts: RunCommandOptions): Promise<void> {\n const { cmd, args = [], cwd, env = {}, label, inherit = false } = opts;\n logger.debug(`spawn ${label}`, { cmd, args });\n\n await new Promise<void>((resolveRun, rejectRun) => {\n const child = spawn(cmd, args, {\n cwd,\n env: { ...process.env, ...env },\n stdio: inherit ? 'inherit' : ['ignore', 'pipe', 'pipe'],\n shell: process.platform === 'win32',\n });\n\n if (!inherit) {\n const prefix = `[${label}]`;\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (chunk: string) => {\n for (const line of chunk.split(/\\r?\\n/)) {\n if (line.length === 0) continue;\n process.stdout.write(`${prefix} ${line}\\n`);\n }\n });\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (chunk: string) => {\n for (const line of chunk.split(/\\r?\\n/)) {\n if (line.length === 0) continue;\n process.stderr.write(`${prefix} ${line}\\n`);\n }\n });\n }\n\n child.on('error', (err) => {\n rejectRun(\n new LifecycleScriptError(\n `Failed to spawn ${label}: ${err.message}`,\n cmd,\n null,\n ),\n );\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n resolveRun();\n } else {\n rejectRun(\n new LifecycleScriptError(\n `${label} exited with code ${code}`,\n cmd,\n code,\n ),\n );\n }\n });\n });\n}\n\nexport interface RunCommandCaptureOptions {\n cmd: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n /** Text to write to the child's stdin before it's closed. */\n stdin?: string;\n label: string;\n /** Kill the child if it hasn't exited by this deadline (ms). */\n timeoutMs?: number;\n}\n\nexport interface CapturedRunResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/**\n * Spawn an external command, optionally pipe stdin to it, capture stdout +\n * stderr to strings, and return on exit. Unlike `runCommand` this does NOT\n * mirror stdio to the parent process — it's intended for one-shot helpers\n * (LLM agent bridges, ffprobe pipes, version checks) where the caller wants\n * to inspect the output programmatically.\n */\nexport async function runCommandCapture(opts: RunCommandCaptureOptions): Promise<CapturedRunResult> {\n const { cmd, args = [], cwd, env = {}, label, stdin, timeoutMs } = opts;\n logger.debug(`capture ${label}`, { cmd, args });\n\n return await new Promise<CapturedRunResult>((resolveRun, rejectRun) => {\n const child = spawn(cmd, args, {\n cwd,\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: process.platform === 'win32',\n });\n\n let stdout = '';\n let stderr = '';\n let timer: NodeJS.Timeout | undefined;\n\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (chunk: string) => {\n stderr += chunk;\n });\n\n if (timeoutMs && timeoutMs > 0) {\n timer = setTimeout(() => {\n child.kill('SIGTERM');\n rejectRun(\n new LifecycleScriptError(\n `${label} timed out after ${timeoutMs}ms`,\n cmd,\n null,\n ),\n );\n }, timeoutMs);\n }\n\n child.on('error', (err) => {\n if (timer) clearTimeout(timer);\n rejectRun(\n new LifecycleScriptError(\n `Failed to spawn ${label}: ${err.message}`,\n cmd,\n null,\n ),\n );\n });\n\n child.on('exit', (code) => {\n if (timer) clearTimeout(timer);\n resolveRun({ stdout, stderr, exitCode: code ?? -1 });\n });\n\n if (stdin !== undefined && child.stdin) {\n child.stdin.write(stdin);\n child.stdin.end();\n } else if (child.stdin) {\n child.stdin.end();\n }\n });\n}\n\nexport async function runLifecycleScript(opts: RunScriptOptions): Promise<void> {\n const abs = isAbsolute(opts.scriptPath) ? opts.scriptPath : resolve(opts.configDir, opts.scriptPath);\n try {\n await stat(abs);\n } catch {\n throw new LifecycleScriptError(\n `${opts.label} script not found at ${abs}`,\n abs,\n null,\n );\n }\n\n logger.info(`Running ${opts.label} script`, { script: abs });\n\n await runCommand({\n cmd: abs,\n args: [],\n cwd: opts.configDir,\n env: opts.env,\n label: opts.label,\n });\n}\n","import { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { z, ZodTypeAny } from 'zod';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface CustomLLMProviderConfig {\n modulePath: string;\n configDir: string;\n /** Free-form provider options forwarded to the loaded module's factory. */\n options?: Record<string, unknown>;\n}\n\n/**\n * Loads an operator-supplied module that default-exports either an LLMProvider\n * directly or a factory function `(options) => LLMProvider`. The module is\n * resolved relative to `configDir` and cached for the lifetime of the process.\n */\nexport class CustomLLMProvider implements LLMProvider {\n private inner: Promise<LLMProvider> | null = null;\n constructor(private readonly cfg: CustomLLMProviderConfig) {}\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const provider = await this.load();\n return provider.generateStructured(opts);\n }\n\n private async load(): Promise<LLMProvider> {\n if (this.inner) return this.inner;\n this.inner = (async () => {\n const absPath = isAbsolute(this.cfg.modulePath)\n ? this.cfg.modulePath\n : resolve(this.cfg.configDir, this.cfg.modulePath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(absPath).href)) as { default?: unknown };\n } catch (err) {\n throw new LLMProviderError(\n `Failed to load custom LLM module at ${absPath}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'custom',\n err,\n );\n }\n const exp = mod.default ?? mod;\n if (typeof exp === 'function') {\n const built = await (exp as (o?: unknown) => Promise<LLMProvider> | LLMProvider)(\n this.cfg.options,\n );\n if (!isLLMProvider(built)) {\n throw new LLMProviderError(\n `Custom LLM module at ${absPath} returned a value that is not a LLMProvider (missing generateStructured)`,\n 'custom',\n );\n }\n return built;\n }\n if (isLLMProvider(exp)) return exp;\n throw new LLMProviderError(\n `Custom LLM module at ${absPath} must default-export an LLMProvider or a factory function`,\n 'custom',\n );\n })();\n return this.inner;\n }\n}\n\nfunction isLLMProvider(v: unknown): v is LLMProvider {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as { generateStructured?: unknown }).generateStructured === 'function'\n );\n}\n","import type { LLMProvider } from './types.js';\nimport { LLMProviderError } from './types.js';\nimport { AnthropicLLMProvider } from './anthropic.js';\nimport { OpenAILLMProvider } from './openai.js';\nimport { AgentBridgeLLMProvider, type AgentBridgeConfig } from './agentBridge.js';\nimport { CustomLLMProvider } from './custom.js';\n\nexport interface AnthropicProviderSpec {\n provider: 'anthropic';\n model: string;\n api_key_env: string;\n max_tokens?: number;\n}\n\nexport interface OpenAIProviderSpec {\n provider: 'openai';\n model: string;\n api_key_env: string;\n max_tokens?: number;\n base_url?: string;\n}\n\nexport interface AgentBridgeProviderSpec {\n provider: 'agent_bridge';\n bridge: {\n mode: 'spawn' | 'file_poll';\n command?: string;\n args?: string[];\n cwd?: string;\n request_dir?: string;\n poll_interval_ms?: number;\n timeout_ms?: number;\n };\n}\n\nexport interface CustomProviderSpec {\n provider: 'custom';\n module_path: string;\n options?: Record<string, unknown>;\n}\n\nexport type LLMProviderSpec =\n | AnthropicProviderSpec\n | OpenAIProviderSpec\n | AgentBridgeProviderSpec\n | CustomProviderSpec;\n\nexport interface CreateContext {\n configDir: string;\n}\n\nexport function createLLMProvider(spec: LLMProviderSpec, ctx: CreateContext): LLMProvider {\n switch (spec.provider) {\n case 'anthropic': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new LLMProviderError(\n `LLM provider 'anthropic' configured with api_key_env='${spec.api_key_env}' but that env var is not set. Set it (e.g. in your project .env) or switch to a different provider.`,\n 'anthropic',\n );\n }\n return new AnthropicLLMProvider({\n apiKey,\n model: spec.model,\n maxTokens: spec.max_tokens,\n });\n }\n case 'openai': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new LLMProviderError(\n `LLM provider 'openai' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'openai',\n );\n }\n return new OpenAILLMProvider({\n apiKey,\n model: spec.model,\n maxTokens: spec.max_tokens,\n baseURL: spec.base_url,\n });\n }\n case 'agent_bridge': {\n const bridgeCfg: AgentBridgeConfig =\n spec.bridge.mode === 'file_poll'\n ? {\n mode: 'file_poll',\n requestDir: spec.bridge.request_dir ?? `${ctx.configDir}/.showrunner-cache/llm-bridge`,\n pollIntervalMs: spec.bridge.poll_interval_ms,\n timeoutMs: spec.bridge.timeout_ms,\n }\n : {\n mode: 'spawn',\n command: spec.bridge.command ?? 'claude',\n args: spec.bridge.args ?? ['-p', '--output-format', 'json'],\n cwd: spec.bridge.cwd,\n timeoutMs: spec.bridge.timeout_ms,\n };\n return new AgentBridgeLLMProvider(bridgeCfg);\n }\n case 'custom':\n return new CustomLLMProvider({\n modulePath: spec.module_path,\n configDir: ctx.configDir,\n options: spec.options,\n });\n }\n}\n\nexport type LLMStage = 'comprehension' | 'script' | 'instrument';\n\nexport interface LLMRouter {\n default: LLMProvider;\n forStage(stage: LLMStage): LLMProvider;\n}\n\nexport interface LLMRouterConfig {\n default: LLMProviderSpec;\n overrides?: Partial<Record<LLMStage, LLMProviderSpec>>;\n}\n\nexport function createLLMRouter(cfg: LLMRouterConfig, ctx: CreateContext): LLMRouter {\n // Lazy: only construct each provider on first access. This lets pipelines\n // that run a subset of stages avoid touching the env vars for providers\n // they don't need. Construction failures (missing env var, custom-module\n // import failure) surface when the stage actually tries to use the LLM.\n let cachedDefault: LLMProvider | undefined;\n const getDefault = (): LLMProvider => {\n if (cachedDefault) return cachedDefault;\n cachedDefault = createLLMProvider(cfg.default, ctx);\n return cachedDefault;\n };\n const overrideFactories = new Map<LLMStage, () => LLMProvider>();\n if (cfg.overrides) {\n for (const [stage, spec] of Object.entries(cfg.overrides) as [LLMStage, LLMProviderSpec | undefined][]) {\n if (!spec) continue;\n let cached: LLMProvider | undefined;\n overrideFactories.set(stage, () => {\n if (cached) return cached;\n cached = createLLMProvider(spec, ctx);\n return cached;\n });\n }\n }\n return {\n get default(): LLMProvider {\n return getDefault();\n },\n forStage(stage: LLMStage): LLMProvider {\n const override = overrideFactories.get(stage);\n return override ? override() : getDefault();\n },\n };\n}\n","import type { PipelineContext } from '../../pipeline/types.js';\nimport type { LLMProvider } from './types.js';\nimport { LLMProviderError } from './types.js';\nimport {\n createLLMRouter,\n type LLMProviderSpec,\n type LLMRouter,\n type LLMStage,\n} from './factory.js';\nimport type { LLMProviderConfig } from '../../config/schema.js';\n\n/**\n * Build the LLM router for the current run. Pulls from `ctx.providers.llm`\n * when set (the pipeline pre-wires it for re-use across stages), otherwise\n * lazily constructs one from `ctx.config.llm` and caches via the WeakMap.\n */\nconst ROUTER_CACHE = new WeakMap<PipelineContext, LLMRouter>();\n\nexport function resolveLLMProviderForStage(\n ctx: PipelineContext,\n stage: LLMStage,\n): LLMProvider {\n const router = getRouter(ctx);\n return router.forStage(stage);\n}\n\nexport function resolveDefaultLLMProvider(\n ctxOrConfigDir: PipelineContext | { configDir: string; llm?: import('../../config/schema.js').LLMConfig },\n): LLMProvider {\n // Convenience overload for `understand` / `instrument` commands that don't\n // have a full PipelineContext on hand — they pass `{ configDir, llm }` instead.\n if ('config' in (ctxOrConfigDir as PipelineContext) && (ctxOrConfigDir as PipelineContext).config) {\n return getRouter(ctxOrConfigDir as PipelineContext).default;\n }\n const standalone = ctxOrConfigDir as { configDir: string; llm?: import('../../config/schema.js').LLMConfig };\n const llm = standalone.llm ?? {\n default: { provider: 'anthropic', model: 'claude-opus-4-7', api_key_env: 'ANTHROPIC_API_KEY' },\n };\n const router = createLLMRouter(toRouterConfig(llm), { configDir: standalone.configDir });\n return router.default;\n}\n\nfunction getRouter(ctx: PipelineContext): LLMRouter {\n const pre = (ctx as PipelineContext & { providers?: { llm?: LLMRouter } }).providers;\n if (pre?.llm) return pre.llm;\n\n const cached = ROUTER_CACHE.get(ctx);\n if (cached) return cached;\n\n // ctx.config.llm gets a schema default, but tests sometimes hand-build ctx\n // without going through loadConfig — fall back to the same default rather\n // than throwing here.\n const llm = ctx.config.llm ?? {\n default: {\n provider: 'anthropic' as const,\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n },\n };\n const router = createLLMRouter(toRouterConfig(llm), { configDir: ctx.configDir });\n ROUTER_CACHE.set(ctx, router);\n return router;\n}\n\nfunction toRouterConfig(llm: import('../../config/schema.js').LLMConfig): {\n default: LLMProviderSpec;\n overrides?: Partial<Record<LLMStage, LLMProviderSpec>>;\n} {\n return {\n default: configToSpec(llm.default),\n overrides: llm.overrides\n ? {\n ...(llm.overrides.comprehension && {\n comprehension: configToSpec(llm.overrides.comprehension),\n }),\n ...(llm.overrides.script && { script: configToSpec(llm.overrides.script) }),\n ...(llm.overrides.instrument && {\n instrument: configToSpec(llm.overrides.instrument),\n }),\n }\n : undefined,\n };\n}\n\nfunction configToSpec(cfg: LLMProviderConfig): LLMProviderSpec {\n // The config shape and the spec shape are aligned by design — same fields,\n // same discriminator. This adapter exists so callers don't import config\n // types into the factory and vice versa.\n switch (cfg.provider) {\n case 'anthropic':\n return {\n provider: 'anthropic',\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.max_tokens !== undefined && { max_tokens: cfg.max_tokens }),\n };\n case 'openai':\n return {\n provider: 'openai',\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.max_tokens !== undefined && { max_tokens: cfg.max_tokens }),\n ...(cfg.base_url !== undefined && { base_url: cfg.base_url }),\n };\n case 'agent_bridge':\n return {\n provider: 'agent_bridge',\n bridge: cfg.bridge,\n };\n case 'custom':\n return {\n provider: 'custom',\n module_path: cfg.module_path,\n ...(cfg.options !== undefined && { options: cfg.options }),\n };\n }\n}\n","import { mkdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport {\n runLifecycleScript,\n LifecycleScriptError,\n} from '../recording/lifecycle.js';\nimport { recordDemo, type SlicePlan } from '../recording/record.js';\nimport { AuthError } from '../recording/auth.js';\nimport {\n assertEnoughDisk,\n estimateMasterWebmBytes,\n formatBytes,\n getFreeDiskBytes,\n} from '../util/resources.js';\n\nexport const recordStage: Stage = {\n name: 'record',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const videoDir = resolve(ctx.configDir, ctx.config.recording.output_dir);\n const masterPath = resolve(videoDir, 'master.webm');\n const slicePlanPath = resolve(videoDir, 'slice_plan.json');\n\n const masterExists = await fileExists(masterPath);\n const forced = ctx.forced.has('record');\n\n if (masterExists && !forced) {\n logger.event({\n stage: 'record',\n status: 'reusing',\n reason: 'master.webm present',\n path: masterPath,\n });\n return {\n stage: 'record',\n skipped: true,\n reason: 'master.webm already present',\n durationMs: Date.now() - start,\n artifacts: { master_video: masterPath, slice_plan: slicePlanPath },\n };\n }\n\n if (!(await fileExists(manifestPath))) {\n return {\n stage: 'record',\n skipped: true,\n reason: `manifest.json not found at ${manifestPath} — run the script stage first`,\n durationMs: Date.now() - start,\n };\n }\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`record stage: ${err.message}`);\n }\n throw err;\n }\n\n const baseEnv = { SHOWRUNNER_RUN_ID: ctx.runId };\n\n if (ctx.config.recording.state.seed_script) {\n try {\n await runLifecycleScript({\n scriptPath: ctx.config.recording.state.seed_script,\n configDir: ctx.configDir,\n env: baseEnv,\n label: 'seed',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n throw new Error(`record stage: seed script failed — ${err.message}`);\n }\n throw err;\n }\n }\n\n // Preflight: estimate the master.webm size against free disk on the video dir.\n const estimatedWebm = estimateMasterWebmBytes({\n durationSec: manifest.total_duration_seconds,\n width: ctx.config.recording.viewport.width,\n height: ctx.config.recording.viewport.height,\n fps: 25, // Playwright records at 25fps regardless of output.fps\n });\n const headroom = Math.ceil(estimatedWebm * 1.5);\n const freeBytes = await getFreeDiskBytes(videoDir);\n logger.event({\n stage: 'record',\n status: 'preflight',\n free_disk: formatBytes(freeBytes),\n estimated_webm: formatBytes(estimatedWebm),\n required: formatBytes(headroom),\n });\n await assertEnoughDisk(videoDir, headroom, 'record video dir');\n\n let slicePlan: SlicePlan;\n let recordError: unknown;\n try {\n slicePlan = await recordDemo({\n recording: ctx.config.recording,\n voiceover: ctx.config.voiceover,\n manifest,\n configDir: ctx.configDir,\n overrides: ctx.overrides,\n });\n } catch (err) {\n recordError = err;\n slicePlan = {\n recording_path: '',\n recording_started_at: new Date().toISOString(),\n segments: [],\n };\n } finally {\n if (ctx.config.recording.state.teardown_script) {\n try {\n await runLifecycleScript({\n scriptPath: ctx.config.recording.state.teardown_script,\n configDir: ctx.configDir,\n env: {\n ...baseEnv,\n SHOWRUNNER_STATUS: recordError ? 'failure' : 'success',\n },\n label: 'teardown',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n warnings.push(`teardown script failed: ${err.message}`);\n logger.warn(`teardown script failed`, { error: err.message });\n } else {\n throw err;\n }\n }\n }\n }\n\n if (recordError) {\n const cause = recordError instanceof Error ? recordError.message : String(recordError);\n if (recordError instanceof AuthError) {\n throw new Error(\n `record stage: auth failed — ${cause}. If a captured session expired, re-run \\`showrunner capture-auth\\`.`,\n );\n }\n throw new Error(`record stage: ${cause}`);\n }\n\n await mkdir(dirname(slicePlanPath), { recursive: true });\n await writeFile(slicePlanPath, JSON.stringify(slicePlan, null, 2) + '\\n', 'utf8');\n\n const failedSegments = slicePlan.segments.filter((s) => s.status === 'failed');\n for (const s of failedSegments) {\n const tail =\n s.failure_screenshots.length > 0\n ? ` (screenshot: ${s.failure_screenshots.join(', ')})`\n : '';\n warnings.push(`segment ${s.id} failed: ${s.failure_reason ?? 'unknown'}${tail}`);\n }\n\n const allScreenshots = slicePlan.segments.flatMap((s) => s.failure_screenshots);\n\n return {\n stage: 'record',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: {\n master_video: slicePlan.recording_path,\n slice_plan: slicePlanPath,\n },\n warnings,\n meta: {\n segments: slicePlan.segments.length,\n failed_segments: failedSegments.length,\n failure_screenshots: allScreenshots,\n },\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { mkdir, rename } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type BrowserContextOptions,\n} from 'playwright-core';\nimport type { RecordingConfig, VoiceoverConfig } from '../config/schema.js';\nimport type { Manifest } from '../manifest/schema.js';\nimport type { PipelineOverrides } from '../pipeline/types.js';\nimport { findWordStartTime, loadAlignment } from '../manifest/alignment.js';\nimport { logger } from '../util/logger.js';\nimport { buildAuthPlan, type AuthPlan } from './auth.js';\nimport { executeAction } from './actions.js';\nimport {\n ensureCursorInstalled,\n installCursorOverlay,\n moveCursor,\n verifyCursorMounted,\n} from './cursorOverlay.js';\nimport {\n isChainedTarget,\n normalizeSelector,\n resolveSelector,\n type SelectorSpec,\n} from './selector.js';\n\nexport interface RecordOptions {\n recording: RecordingConfig;\n voiceover: VoiceoverConfig;\n manifest: Manifest;\n configDir: string;\n overrides?: PipelineOverrides;\n}\n\nexport interface SegmentSlice {\n id: string;\n t_start: number;\n t_end: number;\n status: 'ok' | 'failed';\n failure_reason?: string;\n failure_screenshots: string[];\n warnings: string[];\n trace_path: string;\n}\n\nexport interface SlicePlan {\n recording_path: string;\n recording_started_at: string;\n segments: SegmentSlice[];\n}\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function recordDemo(opts: RecordOptions): Promise<SlicePlan> {\n const { recording, voiceover, manifest, configDir, overrides } = opts;\n const videoDir = resolve(configDir, recording.output_dir);\n const traceDir = resolve(configDir, recording.trace_dir);\n const failureDir = join(traceDir, 'failures');\n const alignmentDir = resolve(configDir, voiceover.alignment_dir);\n await mkdir(videoDir, { recursive: true });\n await mkdir(traceDir, { recursive: true });\n await mkdir(failureDir, { recursive: true });\n\n const headless = overrides?.headed ? false : recording.headless;\n const authPlan = await buildAuthPlan(recording.auth, configDir);\n const browser = await browserMap[recording.browser].launch({ headless });\n\n try {\n const storageState = await resolveStorageState(browser, recording, authPlan);\n\n const contextOptions: BrowserContextOptions = {\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n recordVideo: {\n dir: videoDir,\n size: { width: recording.viewport.width, height: recording.viewport.height },\n },\n storageState,\n };\n const context = await browser.newContext(contextOptions);\n const tRecordingStart = performance.now();\n if (recording.cursor_highlight) {\n await installCursorOverlay(context);\n }\n await context.tracing.start({ screenshots: true, snapshots: true, sources: true });\n\n const page = await context.newPage();\n if (recording.cursor_highlight) {\n page.on('console', (msg) => {\n const text = msg.text();\n if (text.startsWith('[showrunner-cursor]')) {\n logger.debug(`browser: ${text}`);\n }\n });\n }\n const startedAt = new Date();\n await page.goto(recording.target_url);\n if (recording.cursor_highlight) {\n await ensureCursorInstalled(page);\n const mounted = await verifyCursorMounted(page);\n logger.info(`cursor overlay mount check: ${mounted ? 'OK' : 'NOT FOUND'}`);\n }\n\n if (recording.preflight) {\n await preflightSelectors(page, manifest);\n }\n\n const tFirstSegmentStart = performance.now();\n const preSegmentOffsetSec = (tFirstSegmentStart - tRecordingStart) / 1000;\n logger.info(\n `pre-segment recording offset: ${preSegmentOffsetSec.toFixed(2)}s (page.goto + setup) — slice_plan will be offset by this amount`,\n );\n const t0 = tFirstSegmentStart;\n let cursorPos = {\n x: recording.viewport.width / 2,\n y: recording.viewport.height / 2,\n };\n\n const slices: SegmentSlice[] = [];\n\n for (const seg of manifest.segments) {\n await context.tracing.startChunk({ title: seg.id });\n const segStart = (performance.now() - t0) / 1000;\n const tracePath = join(traceDir, `${seg.id}.zip`);\n const warnings: string[] = [];\n const failureScreenshots: string[] = [];\n let failure: string | undefined;\n let lastTargetSelector: SelectorSpec | undefined;\n\n const alignment = await loadAlignment(join(alignmentDir, `${seg.id}.alignment.json`));\n const resolveAtForAction = (action: { at?: number; at_word?: string; at_occurrence?: number }):\n | number\n | undefined => {\n if (action.at_word) {\n if (!alignment) {\n warnings.push(\n `action references at_word=\"${action.at_word}\" but no alignment data found for segment \"${seg.id}\"`,\n );\n return action.at;\n }\n const t = findWordStartTime(alignment, action.at_word, action.at_occurrence ?? 1);\n if (t == null) {\n warnings.push(\n `at_word=\"${action.at_word}\" (occurrence ${action.at_occurrence ?? 1}) not found in VO of segment \"${seg.id}\"`,\n );\n return action.at;\n }\n return t;\n }\n return action.at;\n };\n\n logger.event({ stage: 'record', status: 'segment_start', segment: seg.id, t: segStart });\n\n let actionIndex = -1;\n for (const action of seg.actions) {\n actionIndex++;\n const resolvedAt = resolveAtForAction(action);\n const hasAt = resolvedAt !== undefined;\n const hasSelector =\n 'selector' in action &&\n (typeof action.selector === 'string' || Array.isArray(action.selector));\n const actionSelector: SelectorSpec | undefined = hasSelector\n ? (action as { selector: SelectorSpec }).selector\n : undefined;\n const chainSameTarget = isChainedTarget(\n lastTargetSelector,\n actionSelector,\n recording.cursor_chain_mode,\n );\n let preMovedCursor = false;\n\n if (hasAt && hasSelector && recording.cursor_highlight && !chainSameTarget) {\n const sel = actionSelector!;\n let box: { x: number; y: number; width: number; height: number } | null = null;\n try {\n const locator = await resolveSelector(page, sel, { timeoutMs: 2000 });\n box = await locator.boundingBox({ timeout: 2000 });\n } catch {\n box = null;\n }\n if (box) {\n const targetX = box.x + box.width / 2;\n const targetY = box.y + box.height / 2;\n const distance = Math.hypot(targetX - cursorPos.x, targetY - cursorPos.y);\n const speedFactor = recording.cursor_speed_factor;\n const rawMs = (180 + 0.18 * distance) / speedFactor;\n let motionMs = Math.min(\n recording.cursor_max_motion_ms,\n Math.max(recording.cursor_min_motion_ms, rawMs),\n );\n\n const arrivalAt = resolvedAt!;\n const elapsedNow = (performance.now() - t0) / 1000 - segStart;\n let timeAvailableUntilArrival = arrivalAt - elapsedNow;\n\n if (timeAvailableUntilArrival * 1000 < motionMs) {\n const adjusted = Math.max(\n recording.cursor_min_motion_ms,\n Math.round(timeAvailableUntilArrival * 1000),\n );\n if (adjusted < motionMs) {\n warnings.push(\n `cursor motion for action at ${arrivalAt}s clamped from ${Math.round(motionMs)}ms to ${adjusted}ms — manifest timing tight`,\n );\n }\n motionMs = adjusted;\n timeAvailableUntilArrival = motionMs / 1000;\n }\n\n const motionStartAt = arrivalAt - motionMs / 1000;\n const waitMs = Math.round((motionStartAt - elapsedNow) * 1000);\n if (waitMs > 20) {\n await page.waitForTimeout(waitMs);\n }\n await moveCursor(page, targetX, targetY, motionMs);\n cursorPos = { x: targetX, y: targetY };\n preMovedCursor = true;\n\n const elapsedAfterMove = (performance.now() - t0) / 1000 - segStart;\n const remainingToArrival = arrivalAt - elapsedAfterMove;\n if (remainingToArrival > 0.02) {\n await page.waitForTimeout(Math.round(remainingToArrival * 1000));\n }\n if (recording.cursor_post_arrival_ms > 0) {\n await page.waitForTimeout(recording.cursor_post_arrival_ms);\n }\n } else {\n const elapsedInSeg = (performance.now() - t0) / 1000 - segStart;\n const waitFor = resolvedAt! - elapsedInSeg;\n if (waitFor > 0.02) await page.waitForTimeout(Math.round(waitFor * 1000));\n }\n } else if (hasAt) {\n // chained same-target action, or no-selector action: just wait until at, no cursor ceremony\n const elapsedInSeg = (performance.now() - t0) / 1000 - segStart;\n const waitFor = resolvedAt! - elapsedInSeg;\n if (waitFor > 0.02) await page.waitForTimeout(Math.round(waitFor * 1000));\n if (chainSameTarget) preMovedCursor = true;\n }\n if (actionSelector) lastTargetSelector = actionSelector;\n\n const fireT = (performance.now() - t0) / 1000 - segStart;\n logger.debug(\n `action fire: seg=${seg.id} type=${action.type} resolvedAt=${\n resolvedAt !== undefined ? resolvedAt.toFixed(2) : 'none'\n } elapsed=${fireT.toFixed(2)} chain=${chainSameTarget}`,\n );\n const outcome = await executeAction(page, action, {\n cursorEnabled: recording.cursor_highlight,\n skipCursorPositioning: preMovedCursor,\n failureDir,\n segmentId: seg.id,\n actionIndex,\n });\n if (outcome.status === 'skipped') {\n warnings.push(`${action.type}: ${outcome.reason}`);\n if (outcome.screenshot) failureScreenshots.push(outcome.screenshot);\n logger.warn(`segment ${seg.id} — ${action.type} skipped`, {\n reason: outcome.reason,\n screenshot: outcome.screenshot,\n });\n } else if (outcome.status === 'segment_failed') {\n failure = outcome.reason;\n if (outcome.screenshot) failureScreenshots.push(outcome.screenshot);\n logger.error(`segment ${seg.id} — failed`, {\n reason: outcome.reason,\n screenshot: outcome.screenshot,\n });\n break;\n }\n }\n\n if (recording.segment_buffer_ms > 0) {\n await page.waitForTimeout(recording.segment_buffer_ms);\n }\n\n const allocated = seg.end - seg.start;\n const elapsedInSegment = (performance.now() - t0) / 1000 - segStart;\n const remaining = allocated - elapsedInSegment;\n if (remaining > 0.05) {\n await page.waitForTimeout(Math.round(remaining * 1000));\n } else if (remaining < -0.5) {\n warnings.push(\n `segment took ${elapsedInSegment.toFixed(2)}s but only ${allocated.toFixed(2)}s allocated — manifest timing tight for this segment`,\n );\n }\n\n const segEnd = (performance.now() - t0) / 1000;\n await context.tracing.stopChunk({ path: tracePath });\n\n slices.push({\n id: seg.id,\n t_start: segStart + preSegmentOffsetSec,\n t_end: segEnd + preSegmentOffsetSec,\n status: failure ? 'failed' : 'ok',\n failure_reason: failure,\n failure_screenshots: failureScreenshots,\n warnings,\n trace_path: tracePath,\n });\n\n logger.event({\n stage: 'record',\n status: 'segment_end',\n segment: seg.id,\n t: segEnd,\n outcome: failure ? 'failed' : 'ok',\n warnings: warnings.length,\n });\n }\n\n const videoHandle = page.video();\n await context.close();\n\n let recordingPath = '';\n if (videoHandle) {\n const original = await videoHandle.path();\n const dest = join(videoDir, 'master.webm');\n if (original !== dest) {\n await rename(original, dest);\n }\n recordingPath = dest;\n } else {\n logger.warn('Recording context did not produce a video file — recordVideo may have been ignored');\n }\n\n return {\n recording_path: recordingPath,\n recording_started_at: startedAt.toISOString(),\n segments: slices,\n };\n } finally {\n await browser.close();\n }\n}\n\nasync function resolveStorageState(\n browser: Browser,\n recording: RecordingConfig,\n authPlan: AuthPlan,\n): Promise<BrowserContextOptions['storageState']> {\n if (authPlan.storageState !== undefined) {\n return authPlan.storageState;\n }\n if (!authPlan.postLaunch) {\n return undefined;\n }\n\n logger.info('Running auth setup off-camera before recording');\n const authContext: BrowserContext = await browser.newContext({\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n });\n try {\n const authPage = await authContext.newPage();\n await authPage.goto(recording.target_url);\n await authPlan.postLaunch(authPage);\n return await authContext.storageState();\n } finally {\n await authContext.close();\n }\n}\n\nexport class PreflightError extends Error {\n override readonly name = 'PreflightError';\n constructor(\n readonly failures: { segment: string; actionIndex: number; selectors: string[] }[],\n ) {\n const lines = failures.map(\n (f) => ` - ${f.segment}#${f.actionIndex} → [${f.selectors.join(' | ')}]`,\n );\n super(\n `Pre-flight check failed — ${failures.length} selector(s) did not resolve on ${\n failures[0]?.segment ? `the live target page` : 'the page'\n }:\\n${lines.join('\\n')}\\n\\nFix the manifest selectors, or set recording.preflight: false to skip this check.`,\n );\n }\n}\n\n/**\n * Pre-flight checks the *first segment's* selector-bearing actions against the\n * just-loaded target page. This catches the common \"URL changed / page didn't\n * load / class renamed\" failure modes without false-positiving on selectors that\n * only become available after intermediate navigations or clicks. Deeper\n * selectors fail at action time with the resolver's full diagnostic.\n */\nasync function preflightSelectors(page: import('playwright-core').Page, manifest: Manifest): Promise<void> {\n const firstSeg = manifest.segments[0];\n if (!firstSeg) return;\n\n // Give SPAs a beat to hydrate before probing — best-effort.\n try {\n await page.waitForLoadState('networkidle', { timeout: 3000 });\n } catch {\n // pages with long-poll connections never reach networkidle; carry on\n }\n\n const checks: { segment: string; actionIndex: number; sel: SelectorSpec }[] = [];\n for (let i = 0; i < firstSeg.actions.length; i++) {\n const a = firstSeg.actions[i]!;\n if ('selector' in a && a.selector !== undefined) {\n checks.push({ segment: firstSeg.id, actionIndex: i, sel: a.selector as SelectorSpec });\n }\n }\n\n const failures: { segment: string; actionIndex: number; selectors: string[] }[] = [];\n for (const c of checks) {\n const candidates = normalizeSelector(c.sel);\n let resolved = false;\n for (const cand of candidates) {\n try {\n await page.locator(cand).first().waitFor({ state: 'attached', timeout: 3000 });\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved) {\n failures.push({ segment: c.segment, actionIndex: c.actionIndex, selectors: candidates });\n }\n }\n\n if (failures.length > 0) {\n throw new PreflightError(failures);\n }\n logger.info('pre-flight selector check: first-segment anchors resolved', {\n checks: checks.length,\n });\n}\n","import { readFile } from 'node:fs/promises';\n\nexport interface CharacterAlignment {\n characters: string[];\n character_start_times_seconds: number[];\n character_end_times_seconds: number[];\n}\n\nexport async function loadAlignment(path: string): Promise<CharacterAlignment | null> {\n try {\n const raw = await readFile(path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<CharacterAlignment>;\n if (\n Array.isArray(parsed.characters) &&\n Array.isArray(parsed.character_start_times_seconds) &&\n Array.isArray(parsed.character_end_times_seconds)\n ) {\n return parsed as CharacterAlignment;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Locate the start-time (relative to the segment's audio start) of a target word\n * within the synthesized VO. Returns null if alignment is missing, the word can't\n * be found, or the requested occurrence doesn't exist.\n */\nexport function findWordStartTime(\n alignment: CharacterAlignment,\n word: string,\n occurrence: number = 1,\n): number | null {\n if (!word || occurrence < 1) return null;\n const haystack = alignment.characters.join('').toLowerCase();\n const target = word.toLowerCase();\n const wordBoundary = /\\w/.test(target[0]!) || /\\w/.test(target[target.length - 1]!);\n const escaped = target.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = wordBoundary\n ? new RegExp(`(?<![a-z0-9])${escaped}(?![a-z0-9])`, 'g')\n : new RegExp(escaped, 'g');\n\n let found = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(haystack)) !== null) {\n found++;\n if (found === occurrence) {\n const charIdx = match.index;\n const t = alignment.character_start_times_seconds[charIdx];\n return typeof t === 'number' ? t : null;\n }\n if (match.index === pattern.lastIndex) pattern.lastIndex++; // empty-match guard\n }\n return null;\n}\n","import { readFile } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { Page, BrowserContextOptions } from 'playwright-core';\n\ntype StorageState = BrowserContextOptions['storageState'];\nimport type { AuthConfig } from '../config/schema.js';\nimport { logger } from '../util/logger.js';\n\nexport class AuthError extends Error {\n override readonly name = 'AuthError';\n}\n\nexport interface AuthPlan {\n storageState?: StorageState;\n postLaunch?: (page: Page) => Promise<void>;\n}\n\nexport async function buildAuthPlan(\n auth: AuthConfig | undefined,\n configDir: string,\n): Promise<AuthPlan> {\n if (!auth) return {};\n\n if (auth.type === 'setup_script') {\n return { postLaunch: await loadSetupScript(auth.path, configDir) };\n }\n\n if (auth.type === 'session') {\n return { storageState: await buildStorageState(auth.cookies_file, auth.local_storage_file, configDir) };\n }\n\n if (auth.type === 'form') {\n return { postLaunch: buildFormFill(auth) };\n }\n\n return {};\n}\n\nasync function loadSetupScript(\n scriptPath: string,\n configDir: string,\n): Promise<(page: Page) => Promise<void>> {\n const abs = isAbsolute(scriptPath) ? scriptPath : resolve(configDir, scriptPath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(abs).href)) as { default?: unknown };\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to load setup_script at ${abs}: ${cause}`);\n }\n if (typeof mod.default !== 'function') {\n throw new AuthError(\n `setup_script at ${abs} must default-export an async function (page: Page) => Promise<void>`,\n );\n }\n const fn = mod.default as (page: Page) => Promise<void>;\n return async (page) => {\n try {\n await fn(page);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`setup_script failed: ${cause}`);\n }\n };\n}\n\nasync function buildStorageState(\n cookiesFile: string,\n localStorageFile: string | undefined,\n configDir: string,\n): Promise<StorageState> {\n const cookiesAbs = isAbsolute(cookiesFile) ? cookiesFile : resolve(configDir, cookiesFile);\n let cookiesRaw: string;\n try {\n cookiesRaw = await readFile(cookiesAbs, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to read cookies_file at ${cookiesAbs}: ${cause}`);\n }\n let cookiesJson: unknown;\n try {\n cookiesJson = JSON.parse(cookiesRaw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Invalid JSON in cookies_file ${cookiesAbs}: ${cause}`);\n }\n\n if (!isPlaywrightStorageState(cookiesJson)) {\n throw new AuthError(\n `cookies_file at ${cookiesAbs} is not in Playwright storageState format (expected { cookies: [...], origins: [...] })`,\n );\n }\n\n if (localStorageFile) {\n const lsAbs = isAbsolute(localStorageFile)\n ? localStorageFile\n : resolve(configDir, localStorageFile);\n try {\n const lsRaw = await readFile(lsAbs, 'utf8');\n const lsJson = JSON.parse(lsRaw) as unknown;\n if (isOriginsList(lsJson)) {\n cookiesJson.origins = [...(cookiesJson.origins ?? []), ...lsJson];\n } else {\n logger.warn(\n `local_storage_file at ${lsAbs} is not a Playwright origins list — skipping. Use storageState() output format.`,\n );\n }\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to read local_storage_file at ${lsAbs}: ${cause}`);\n }\n }\n\n return cookiesJson as StorageState;\n}\n\ninterface PlaywrightStorageState {\n cookies?: unknown[];\n origins?: unknown[];\n}\n\nfunction isPlaywrightStorageState(value: unknown): value is PlaywrightStorageState {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n return Array.isArray(v['cookies']) || Array.isArray(v['origins']);\n}\n\nfunction isOriginsList(value: unknown): value is unknown[] {\n return Array.isArray(value);\n}\n\nfunction buildFormFill(\n auth: Extract<AuthConfig, { type: 'form' }>,\n): (page: Page) => Promise<void> {\n return async (page) => {\n const email = process.env[auth.fields.email.env];\n const password = process.env[auth.fields.password.env];\n if (!email) {\n throw new AuthError(\n `Form auth: env var ${auth.fields.email.env} is not set`,\n );\n }\n if (!password) {\n throw new AuthError(\n `Form auth: env var ${auth.fields.password.env} is not set`,\n );\n }\n await page.goto(auth.login_url);\n await page.fill(auth.fields.email.selector, email);\n await page.fill(auth.fields.password.selector, password);\n await page.click(auth.submit_selector);\n try {\n await page.waitForURL(auth.success_url_pattern, { timeout: auth.timeout_ms });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(\n `Form auth: did not reach ${auth.success_url_pattern} within ${auth.timeout_ms}ms — ${cause}`,\n );\n }\n };\n}\n","import { mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { errors as playwrightErrors, type Page } from 'playwright-core';\nimport type { Action } from '../manifest/schema.js';\nimport { moveCursor, pulseCursor } from './cursorOverlay.js';\nimport { resolveSelector } from './selector.js';\n\nexport type ActionOutcome =\n | { status: 'ok' }\n | { status: 'skipped'; reason: string; screenshot?: string }\n | { status: 'segment_failed'; reason: string; screenshot?: string };\n\nexport class SegmentFailedError extends Error {\n override readonly name = 'SegmentFailedError';\n}\n\nconst CURSOR_SETTLE_MS = 280;\n\nexport interface ExecuteOptions {\n cursorEnabled: boolean;\n skipCursorPositioning?: boolean;\n /** When set, on-error screenshots will be written under this directory. */\n failureDir?: string;\n /** Owning segment id, used in the screenshot filename. */\n segmentId?: string;\n /** Index of the action inside the segment, used in the screenshot filename. */\n actionIndex?: number;\n}\n\nexport async function executeAction(\n page: Page,\n action: Action,\n opts: ExecuteOptions = { cursorEnabled: false },\n): Promise<ActionOutcome> {\n try {\n if (opts.cursorEnabled && !opts.skipCursorPositioning) {\n await positionCursorForAction(page, action);\n }\n switch (action.type) {\n case 'idle':\n return { status: 'ok' };\n case 'click': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.click();\n return { status: 'ok' };\n }\n case 'fill': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.fill(action.value);\n return { status: 'ok' };\n }\n case 'type': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.pressSequentially(action.value, { delay: 60 });\n return { status: 'ok' };\n }\n case 'hover': {\n const locator = await resolveSelector(page, action.selector);\n await locator.hover();\n return { status: 'ok' };\n }\n case 'scroll': {\n const direction = action.direction;\n const locator = await resolveSelector(page, action.selector);\n await locator.evaluate((el, dir) => {\n const node = el as unknown as { scrollTop: number; scrollHeight: number };\n node.scrollTop = dir === 'down' ? node.scrollHeight : -node.scrollHeight;\n }, direction);\n return { status: 'ok' };\n }\n case 'navigate':\n await page.goto(action.url);\n return { status: 'ok' };\n case 'wait_for': {\n const locator = await resolveSelector(page, action.selector);\n await locator.waitFor({ state: 'attached' });\n return { status: 'ok' };\n }\n case 'wait_for_url':\n await page.waitForURL(action.pattern);\n return { status: 'ok' };\n case 'wait':\n await page.waitForTimeout(action.ms);\n return { status: 'ok' };\n case 'assert_visible': {\n const locator = await resolveSelector(page, action.selector, { state: 'visible' });\n await locator.waitFor({ state: 'visible' });\n return { status: 'ok' };\n }\n case 'press':\n if (opts.cursorEnabled) await pulseCursor(page);\n if (action.selector) {\n const locator = await resolveSelector(page, action.selector);\n await locator.press(action.key);\n } else {\n await page.keyboard.press(action.key);\n }\n return { status: 'ok' };\n case 'custom':\n await page.evaluate(action.js);\n return { status: 'ok' };\n }\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n const screenshot = await captureFailureScreenshot(page, opts, action.type);\n\n if (action.type === 'assert_visible') {\n return {\n status: 'segment_failed',\n reason: `assert_visible failed: ${reason}`,\n screenshot,\n };\n }\n\n if (err instanceof playwrightErrors.TimeoutError) {\n return { status: 'skipped', reason: `timeout on ${action.type}: ${reason}`, screenshot };\n }\n\n return { status: 'skipped', reason: `${action.type} error: ${reason}`, screenshot };\n }\n}\n\nasync function captureFailureScreenshot(\n page: Page,\n opts: ExecuteOptions,\n actionType: string,\n): Promise<string | undefined> {\n if (!opts.failureDir || !opts.segmentId) return undefined;\n const idx = opts.actionIndex ?? 0;\n const path = join(opts.failureDir, `${opts.segmentId}-${idx}-${actionType}.png`);\n try {\n await mkdir(dirname(path), { recursive: true });\n await page.screenshot({ path, fullPage: false });\n return path;\n } catch {\n return undefined;\n }\n}\n\nasync function positionCursorForAction(page: Page, action: Action): Promise<void> {\n if (!('selector' in action) || !action.selector) return;\n try {\n const locator = await resolveSelector(page, action.selector, { timeoutMs: 2000 });\n const box = await locator.boundingBox({ timeout: 2000 });\n if (!box) return;\n const x = box.x + box.width / 2;\n const y = box.y + box.height / 2;\n await moveCursor(page, x, y);\n await page.waitForTimeout(CURSOR_SETTLE_MS);\n } catch {\n // selector might not exist yet; cursor stays where it was\n }\n}\n","import type { BrowserContext, Page } from 'playwright-core';\n\nconst CURSOR_INIT_SCRIPT = `\n(() => {\n if (window.__showrunnerCursorInstalled) return;\n console.log('[showrunner-cursor] boot');\n\n const tryInstall = () => {\n if (window.__showrunnerCursorInstalled) return true;\n if (!document.body || !document.head) return false;\n\n const style = document.createElement('style');\n style.textContent = \\`\n @keyframes sr-cursor-pulse-kf {\n 0% { transform: scale(1); opacity: 0.9; }\n 100% { transform: scale(2.6); opacity: 0; }\n }\n #showrunner-cursor {\n position: fixed !important;\n left: 50vw;\n top: 50vh;\n width: 28px !important;\n height: 28px !important;\n margin-left: -14px !important;\n margin-top: -14px !important;\n pointer-events: none !important;\n z-index: 2147483647 !important;\n transition: left 240ms cubic-bezier(0.42, 0, 0.58, 1),\n top 240ms cubic-bezier(0.42, 0, 0.58, 1);\n display: block !important;\n opacity: 1 !important;\n visibility: visible !important;\n }\n #showrunner-cursor .sr-cursor-dot {\n width: 28px !important;\n height: 28px !important;\n border-radius: 50% !important;\n background: rgba(255, 60, 60, 0.85) !important;\n box-shadow: 0 0 0 3px rgba(255, 60, 60, 1),\n 0 0 0 6px rgba(255, 255, 255, 0.6),\n 0 4px 18px rgba(0, 0, 0, 0.45) !important;\n }\n #showrunner-cursor .sr-cursor-ring {\n position: absolute !important;\n inset: 0 !important;\n border-radius: 50% !important;\n border: 4px solid rgba(255, 60, 60, 0.9) !important;\n opacity: 0;\n pointer-events: none !important;\n }\n #showrunner-cursor.sr-cursor-pulse .sr-cursor-ring {\n animation: sr-cursor-pulse-kf 420ms ease-out;\n }\n \\`;\n document.head.appendChild(style);\n\n const cursor = document.createElement('div');\n cursor.id = 'showrunner-cursor';\n const dot = document.createElement('div');\n dot.className = 'sr-cursor-dot';\n const ring = document.createElement('div');\n ring.className = 'sr-cursor-ring';\n cursor.appendChild(dot);\n cursor.appendChild(ring);\n document.body.appendChild(cursor);\n\n window.__showrunnerCursorInstalled = true;\n console.log('[showrunner-cursor] mounted');\n return true;\n };\n\n if (tryInstall()) return;\n\n console.log('[showrunner-cursor] deferring — body not ready');\n\n const tick = () => { if (tryInstall()) cleanup(); };\n const observer = new MutationObserver(tick);\n const target = document.documentElement || document;\n observer.observe(target, { childList: true, subtree: true });\n const interval = setInterval(tick, 50);\n const onReady = () => tick();\n document.addEventListener('DOMContentLoaded', onReady);\n document.addEventListener('readystatechange', onReady);\n const cleanup = () => {\n observer.disconnect();\n clearInterval(interval);\n document.removeEventListener('DOMContentLoaded', onReady);\n document.removeEventListener('readystatechange', onReady);\n };\n})();\n`;\n\nexport async function installCursorOverlay(context: BrowserContext): Promise<void> {\n await context.addInitScript(CURSOR_INIT_SCRIPT);\n}\n\nexport async function ensureCursorInstalled(page: Page): Promise<void> {\n try {\n await page.evaluate(CURSOR_INIT_SCRIPT);\n } catch {\n // best effort\n }\n}\n\nexport async function verifyCursorMounted(page: Page): Promise<boolean> {\n try {\n return await page.evaluate(() => {\n const doc = (globalThis as unknown as { document?: { getElementById: (id: string) => unknown } })\n .document;\n return Boolean(doc && doc.getElementById('showrunner-cursor'));\n });\n } catch {\n return false;\n }\n}\n\ninterface CursorElement {\n style: { left: string; top: string };\n classList: { add: (c: string) => void; remove: (c: string) => void };\n offsetWidth: number;\n}\ninterface CursorDoc {\n getElementById: (id: string) => CursorElement | null;\n}\n\ninterface CursorElementWithTransition extends CursorElement {\n style: { left: string; top: string; transition: string };\n}\ninterface CursorDocWithTransition {\n getElementById: (id: string) => CursorElementWithTransition | null;\n}\n\n// easeInOutCubic: pronounced ease at both ends, fast through the middle.\n// cubic-bezier(0.42, 0, 0.58, 1) — much more dramatic than Material's standard curve.\nconst CURSOR_EASE = 'cubic-bezier(0.42, 0, 0.58, 1)';\n\nexport async function moveCursor(\n page: Page,\n x: number,\n y: number,\n motionMs?: number,\n): Promise<void> {\n try {\n await page.evaluate(\n ({ x: cx, y: cy, ms, ease }) => {\n const doc = (globalThis as unknown as { document?: CursorDocWithTransition }).document;\n const el = doc?.getElementById('showrunner-cursor');\n if (!el) return;\n const duration = typeof ms === 'number' && ms > 0 ? ms : 240;\n el.style.transition = `left ${duration}ms ${ease}, top ${duration}ms ${ease}`;\n el.style.left = cx + 'px';\n el.style.top = cy + 'px';\n },\n { x, y, ms: motionMs, ease: CURSOR_EASE },\n );\n } catch {\n // page closed or eval failed — cursor is best-effort\n }\n}\n\nexport async function pulseCursor(page: Page): Promise<void> {\n try {\n await page.evaluate(() => {\n const doc = (globalThis as unknown as { document?: CursorDoc }).document;\n const el = doc?.getElementById('showrunner-cursor');\n if (el) {\n el.classList.remove('sr-cursor-pulse');\n void el.offsetWidth;\n el.classList.add('sr-cursor-pulse');\n }\n });\n } catch {\n // ignore\n }\n}\n","import type { Locator, Page } from 'playwright-core';\nimport type { SelectorSpec } from '../manifest/schema.js';\n\nexport type { SelectorSpec } from '../manifest/schema.js';\n\nexport class SelectorResolutionError extends Error {\n override readonly name = 'SelectorResolutionError';\n constructor(\n readonly tried: string[],\n cause: string,\n ) {\n super(`None of [${tried.join(' | ')}] resolved: ${cause}`);\n }\n}\n\nexport function normalizeSelector(sel: SelectorSpec): string[] {\n return Array.isArray(sel) ? sel : [sel];\n}\n\nexport interface ResolveOptions {\n timeoutMs?: number;\n state?: 'attached' | 'visible';\n}\n\nexport async function resolveSelector(\n page: Page,\n sel: SelectorSpec,\n opts: ResolveOptions = {},\n): Promise<Locator> {\n const timeout = opts.timeoutMs ?? 5000;\n const state = opts.state ?? 'attached';\n const candidates = normalizeSelector(sel);\n const errors: string[] = [];\n for (const candidate of candidates) {\n const locator = page.locator(candidate).first();\n try {\n await locator.waitFor({ state, timeout });\n return locator;\n } catch (err) {\n errors.push(`${candidate}: ${err instanceof Error ? err.message.split('\\n')[0] : String(err)}`);\n }\n }\n throw new SelectorResolutionError(candidates, errors.join(' ; '));\n}\n\n/**\n * Heuristic chain detection. In 'strict' mode, only exact equality counts.\n * In 'smart' mode, also treat as chained when:\n * - selectors share a `[name=\"...\"]` or `[data-testid=\"...\"]` attribute literal,\n * - one selector string is a prefix of the other (e.g. `form input` vs `form input[name=email]`).\n * Selector arrays are reduced to their first entry for comparison — the resolver\n * picks the first match at runtime, so first-entry equivalence is the load-bearing signal.\n */\nexport function isChainedTarget(\n prev: SelectorSpec | undefined,\n cur: SelectorSpec | undefined,\n mode: 'strict' | 'smart',\n): boolean {\n if (prev === undefined || cur === undefined) return false;\n const prevFirst = normalizeSelector(prev)[0]!;\n const curFirst = normalizeSelector(cur)[0]!;\n if (prevFirst === curFirst) return true;\n if (mode === 'strict') return false;\n\n const attrMatch = (a: string, b: string, attr: 'name' | 'data-testid'): boolean => {\n const re = new RegExp(`\\\\[${attr}=[\"']([^\"']+)[\"']\\\\]`);\n const ma = re.exec(a);\n const mb = re.exec(b);\n return ma !== null && mb !== null && ma[1] === mb[1];\n };\n if (attrMatch(prevFirst, curFirst, 'name')) return true;\n if (attrMatch(prevFirst, curFirst, 'data-testid')) return true;\n if (prevFirst.startsWith(curFirst) || curFirst.startsWith(prevFirst)) return true;\n return false;\n}\n","import { cpus, freemem, totalmem } from 'node:os';\nimport { statfs } from 'node:fs/promises';\nimport { logger } from './logger.js';\n\nexport class ResourceError extends Error {\n override readonly name = 'ResourceError';\n constructor(\n message: string,\n readonly kind: 'disk' | 'memory',\n ) {\n super(message);\n }\n}\n\nconst MB = 1024 * 1024;\nconst GB = 1024 * MB;\nconst SAFETY_FLOOR_BYTES = 500 * MB;\n\nexport function getFreeMemoryBytes(): number {\n return freemem();\n}\n\nexport function getTotalMemoryBytes(): number {\n return totalmem();\n}\n\n/**\n * Free disk space at `path` in bytes. Returns Infinity on filesystems that\n * don't support statfs (network mounts, some Windows configurations).\n */\nexport async function getFreeDiskBytes(path: string): Promise<number> {\n try {\n const stats = await statfs(path);\n return stats.bavail * stats.bsize;\n } catch {\n return Infinity;\n }\n}\n\nexport interface ThreadCapOptions {\n width: number;\n height: number;\n fps: number;\n quality: 'draft' | 'standard' | 'high';\n freeMemBytes: number;\n}\n\n/**\n * libx264 working set ≈ frame buffer (W*H*1.5 bytes for YUV420) × per-thread\n * coefficient × lookahead frames. Quality preset drives lookahead.\n * draft → veryfast → ~10 lookahead frames\n * standard → medium → ~25 lookahead frames\n * high → slow → ~50 lookahead frames\n * Cap at the CPU count. Operator escape hatch: SHOWRUNNER_FFMPEG_THREADS env.\n */\nexport function computeThreadCap(opts: ThreadCapOptions): number {\n const override = process.env['SHOWRUNNER_FFMPEG_THREADS'];\n if (override) {\n const n = parseInt(override, 10);\n if (Number.isFinite(n) && n > 0) return n;\n }\n const cpuCount = Math.max(1, cpus().length);\n const lookaheadByQuality: Record<ThreadCapOptions['quality'], number> = {\n draft: 10,\n standard: 25,\n high: 50,\n };\n const lookahead = lookaheadByQuality[opts.quality];\n const frameBytes = Math.ceil(opts.width * opts.height * 1.5);\n // Per-thread overhead: roughly one frame buffer × lookahead, plus some slack\n const perThreadBytes = frameBytes * lookahead * 1.2;\n const headroom = Math.max(0, opts.freeMemBytes - SAFETY_FLOOR_BYTES);\n if (headroom < perThreadBytes) return 1;\n const capByMemory = Math.floor(headroom / perThreadBytes);\n return Math.max(1, Math.min(cpuCount, capByMemory));\n}\n\nexport interface MasterWebmEstimateOptions {\n durationSec: number;\n width: number;\n height: number;\n fps: number;\n}\n\n/**\n * Conservative size estimate for the master.webm Playwright will record.\n * VP8 in Playwright defaults to ~1 Mbps at 720p and scales with resolution +\n * fps. Used to fail-fast before recording if disk space is too tight.\n */\nexport function estimateMasterWebmBytes(opts: MasterWebmEstimateOptions): number {\n const pixelRate = opts.width * opts.height * opts.fps;\n // Bytes per pixel-frame ≈ 0.1 bits → ~0.0125 bytes\n const bytesPerSec = pixelRate * 0.0125;\n return Math.ceil(bytesPerSec * opts.durationSec);\n}\n\nexport async function assertEnoughDisk(\n targetDir: string,\n minBytes: number,\n label: string,\n): Promise<void> {\n const free = await getFreeDiskBytes(targetDir);\n if (free < minBytes) {\n throw new ResourceError(\n `${label}: insufficient free disk at ${targetDir} — need ~${formatBytes(minBytes)}, found ~${formatBytes(free)}. Free up space or move the project off this filesystem.`,\n 'disk',\n );\n }\n logger.debug(`disk check ok: ${label}`, {\n path: targetDir,\n free_mb: Math.round(free / MB),\n required_mb: Math.round(minBytes / MB),\n });\n}\n\nexport function formatBytes(n: number): string {\n if (!Number.isFinite(n)) return '∞';\n if (n >= GB) return `${(n / GB).toFixed(1)} GB`;\n if (n >= MB) return `${Math.round(n / MB)} MB`;\n return `${Math.round(n / 1024)} KB`;\n}\n","import { mkdir, stat, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport type { Manifest, Segment } from '../manifest/schema.js';\nimport { ffprobeDuration } from '../voiceover/ffmpeg.js';\nimport {\n buildFullScript,\n computeSliceBoundaries,\n loadMasterAlignment,\n locateSegmentWindows,\n masterPaths,\n sliceAlignment,\n sliceMasterAudio,\n writeMasterAlignment,\n type SegmentWindow,\n type SliceBoundary,\n} from '../voiceover/fullVo.js';\nimport {\n resolveAlignmentStrategy,\n resolveElevenLabsConfigOrNull,\n resolveTTSProvider,\n type AlignmentStrategy,\n} from '../providers/tts/resolveFromContext.js';\nimport { TTSProviderError, type TTSProvider } from '../providers/tts/types.js';\nimport type { VoiceoverConfig } from '../config/schema.js';\n\ninterface SegmentArtifact {\n segment_id: string;\n final_path: string;\n natural_duration_seconds: number;\n final_duration_seconds: number;\n target_duration_seconds: number;\n characters_synthesized: number;\n used_speed: number;\n drift_action: 'kept' | 'auto_extended' | 'reused';\n pause_strategy: 'master_slice';\n warnings: string[];\n}\n\nexport const voiceoverStage: Stage = {\n name: 'voiceover',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const stageWarnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const audioDir = resolve(ctx.configDir, ctx.config.voiceover.output_dir);\n const alignmentDir = resolve(ctx.configDir, ctx.config.voiceover.alignment_dir);\n await mkdir(audioDir, { recursive: true });\n await mkdir(alignmentDir, { recursive: true });\n\n if (!(await fileExists(manifestPath))) {\n return {\n stage: 'voiceover',\n skipped: true,\n reason: `manifest.json not found at ${manifestPath} — run the script stage first`,\n durationMs: Date.now() - start,\n };\n }\n\n let manifest: Manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`voiceover stage: ${err.message}`);\n }\n throw err;\n }\n\n const vo = ctx.config.voiceover;\n const elevenSpec = resolveElevenLabsConfigOrNull(ctx);\n const voSpeed = elevenSpec?.speed ?? 1.0;\n const forced = ctx.forced.has('voiceover');\n const tailPaddingSec = vo.tail_padding_ms / 1000;\n const master = masterPaths(audioDir, alignmentDir);\n const alignmentStrategy = resolveAlignmentStrategy(ctx);\n const provider = resolveTTSProvider(ctx);\n\n // Provider doesn't return alignment AND user requires it → fail fast.\n if (!provider.supportsAlignment && alignmentStrategy === 'required') {\n throw new Error(\n `voiceover stage: provider '${provider.name}' does not return alignment data, ` +\n `but voiceover.alignment_strategy is 'required'. Either switch providers (elevenlabs) ` +\n `or set alignment_strategy: best_effort in demo.yaml.`,\n );\n }\n\n // Non-aligned providers take the per-segment fallback path — one TTS call\n // per segment, concatenated. Skips master-alignment work entirely.\n if (!provider.supportsAlignment) {\n return await runBestEffortPath({\n ctx,\n manifest,\n provider,\n audioDir,\n alignmentDir,\n tailPaddingSec,\n forced,\n start,\n manifestPath,\n voSpeed,\n });\n }\n\n // 1. Synthesize the master VO (one TTS call), or reuse cache.\n const masterCached =\n (await fileExists(master.rawAudio)) && (await fileExists(master.alignment));\n if (forced || !masterCached) {\n logger.event({\n stage: 'voiceover',\n status: 'synthesizing_master',\n provider: provider.name,\n segments: manifest.segments.length,\n });\n try {\n const fullText = buildFullScript(manifest.segments);\n const result = await provider.synthesize({ text: fullText });\n if (!result.alignment) {\n // provider.supportsAlignment said true but didn't return any — surface as error.\n throw new TTSProviderError(\n `provider ${provider.name} advertised supportsAlignment but returned no alignment data`,\n provider.name,\n );\n }\n await writeFile(master.rawAudio, result.audio);\n await writeMasterAlignment(master.alignment, result.alignment);\n logger.event({\n stage: 'voiceover',\n status: 'master_written',\n path: master.rawAudio,\n duration: result.durationSeconds.toFixed(2),\n chars: result.charactersSynthesized,\n });\n } catch (err) {\n if (err instanceof TTSProviderError) {\n throw new Error(`voiceover stage: master synthesis failed — ${err.message}`);\n }\n throw err;\n }\n } else {\n logger.event({\n stage: 'voiceover',\n status: 'reusing_master',\n path: master.rawAudio,\n });\n }\n\n // 2. Load master alignment, locate each segment's window.\n const alignment = await loadMasterAlignment(master.alignment);\n if (!alignment) {\n throw new Error(`voiceover stage: failed to load master alignment at ${master.alignment}`);\n }\n let windows: SegmentWindow[];\n try {\n windows = locateSegmentWindows(manifest.segments, alignment);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(`voiceover stage: ${cause}`);\n }\n\n // 3. Compute midpoint boundaries so each segment slice absorbs half of the\n // silence on either side. Concatenating the slices reproduces the master\n // bit-for-bit (modulo ffmpeg re-encode), preserving model-generated pauses.\n const masterDuration = await ffprobeDuration(master.rawAudio);\n const boundaries = computeSliceBoundaries(windows, masterDuration);\n\n // 4. Slice master per segment, write per-segment alignment.\n const artifacts: SegmentArtifact[] = [];\n for (let i = 0; i < manifest.segments.length; i++) {\n const segment = manifest.segments[i]!;\n const window = windows[i]!;\n const boundary = boundaries[i]!;\n try {\n const artifact = await sliceSegmentFromMaster({\n segment,\n window,\n boundary,\n masterAudioPath: master.rawAudio,\n masterAlignment: alignment,\n operatorAllocated: segment.end - segment.start,\n tailPaddingSec,\n audioDir,\n alignmentDir,\n voSpeed,\n });\n artifacts.push(artifact);\n logger.event({\n stage: 'voiceover',\n status: 'segment_sliced',\n segment: segment.id,\n slice_start: boundary.start_sec.toFixed(2),\n slice_end: boundary.end_sec.toFixed(2),\n natural: artifact.natural_duration_seconds.toFixed(2),\n final: artifact.final_duration_seconds.toFixed(2),\n });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(`voiceover stage: segment ${segment.id}: ${cause}`);\n }\n }\n\n // 4. Rewrite manifest timings to reflect actual VO durations.\n const rewritten = rewriteManifestTimings(manifest, artifacts);\n if (rewritten.changed) {\n await writeManifest(manifestPath, rewritten.manifest);\n stageWarnings.push(\n `manifest timings derived from VO: total_duration ${manifest.total_duration_seconds.toFixed(2)}s → ${rewritten.manifest.total_duration_seconds.toFixed(2)}s`,\n );\n logger.event({\n stage: 'voiceover',\n status: 'manifest_rewritten',\n path: manifestPath,\n new_total: rewritten.manifest.total_duration_seconds,\n });\n }\n\n const summaryPath = join(audioDir, 'voiceover_summary.json');\n const totalCharacters = manifest.segments.reduce((acc, s) => acc + s.vo_line.length, 0);\n await writeFile(\n summaryPath,\n JSON.stringify(\n {\n mode: 'full',\n characters_synthesized: totalCharacters,\n tail_padding_ms: vo.tail_padding_ms,\n master_audio: master.rawAudio,\n master_alignment: master.alignment,\n segments: artifacts,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n const artifactsRecord: Record<string, string> = {\n voiceover_summary: summaryPath,\n master_audio: master.rawAudio,\n master_alignment: master.alignment,\n };\n for (const a of artifacts) {\n artifactsRecord[`audio_${a.segment_id}`] = a.final_path;\n }\n\n return {\n stage: 'voiceover',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: artifactsRecord,\n warnings: [...stageWarnings, ...artifacts.flatMap((a) => a.warnings)],\n meta: {\n mode: 'full',\n segments: artifacts.length,\n characters_synthesized: totalCharacters,\n },\n };\n },\n};\n\ninterface SliceSegmentInput {\n segment: Segment;\n window: SegmentWindow;\n boundary: SliceBoundary;\n masterAudioPath: string;\n masterAlignment: import('../manifest/alignment.js').CharacterAlignment;\n operatorAllocated: number;\n tailPaddingSec: number;\n audioDir: string;\n alignmentDir: string;\n voSpeed: number;\n}\n\nasync function sliceSegmentFromMaster(input: SliceSegmentInput): Promise<SegmentArtifact> {\n const {\n segment,\n window,\n boundary,\n masterAudioPath,\n masterAlignment,\n operatorAllocated,\n audioDir,\n alignmentDir,\n voSpeed,\n } = input;\n const warnings: string[] = [];\n\n // The slice covers boundary.start_sec → boundary.end_sec of the master, which\n // includes this segment's speech plus its half-share of inter-segment silence.\n // No debreath, no pause injection — the master already carries natural pauses.\n const finalPath = join(audioDir, `${segment.id}.mp3`);\n await sliceMasterAudio({\n masterPath: masterAudioPath,\n outputPath: finalPath,\n startSec: boundary.start_sec,\n durationSec: boundary.end_sec - boundary.start_sec,\n });\n\n // Per-segment alignment file with segment-mp3 timings (0 = start of the mp3\n // including any leading silence). Both at_word resolution in record.ts and\n // caption emission rely on this coordinate system.\n const segAlignment = sliceAlignment(masterAlignment, window, boundary);\n const alignmentPath = join(alignmentDir, `${segment.id}.alignment.json`);\n await writeFile(alignmentPath, JSON.stringify(segAlignment, null, 2) + '\\n', 'utf8');\n\n const finalDuration = await ffprobeDuration(finalPath);\n const speechDuration = window.end_time_seconds - window.start_time_seconds;\n const driftAction: SegmentArtifact['drift_action'] =\n Math.abs(finalDuration - operatorAllocated) > 0.05 ? 'auto_extended' : 'kept';\n\n return {\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: speechDuration,\n final_duration_seconds: finalDuration,\n target_duration_seconds: finalDuration,\n characters_synthesized: segment.vo_line.length,\n used_speed: voSpeed,\n drift_action: driftAction,\n pause_strategy: 'master_slice',\n warnings,\n };\n}\n\ninterface RewriteResult {\n manifest: Manifest;\n changed: boolean;\n}\n\nfunction rewriteManifestTimings(manifest: Manifest, artifacts: SegmentArtifact[]): RewriteResult {\n const byId = new Map(artifacts.map((a) => [a.segment_id, a]));\n let cursor = 0;\n let changed = false;\n const newSegments = manifest.segments.map((seg) => {\n const a = byId.get(seg.id);\n const allocated = seg.end - seg.start;\n const actual = a?.final_duration_seconds ?? allocated;\n if (Math.abs(actual - allocated) > 0.01 || Math.abs(seg.start - cursor) > 0.01) {\n changed = true;\n }\n const newStart = cursor;\n const newEnd = cursor + actual;\n cursor = newEnd;\n return { ...seg, start: round(newStart), end: round(newEnd) };\n });\n const newTotal = round(cursor);\n if (Math.abs(newTotal - manifest.total_duration_seconds) > 0.01) changed = true;\n return {\n manifest: { ...manifest, segments: newSegments, total_duration_seconds: newTotal },\n changed,\n };\n}\n\nfunction round(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\ninterface BestEffortPathInput {\n ctx: PipelineContext;\n manifest: Manifest;\n provider: TTSProvider;\n audioDir: string;\n alignmentDir: string;\n tailPaddingSec: number;\n forced: boolean;\n start: number;\n manifestPath: string;\n voSpeed: number;\n}\n\n/**\n * Per-segment synthesis fallback for providers that don't return alignment\n * data. One TTS call per segment; no master alignment to slice from. Captions\n * fall back to whole-segment cues (handled in mux/captions.ts), and at_word\n * action timing degrades to action.at (handled in record.ts:resolveAtForAction).\n */\nasync function runBestEffortPath(input: BestEffortPathInput): Promise<StageResult> {\n const { ctx, manifest, provider, audioDir, tailPaddingSec, forced, start, manifestPath, voSpeed } = input;\n void ctx;\n const stageWarnings: string[] = [\n `alignment_strategy=best_effort: provider '${provider.name}' produces no alignment — captions will be whole-segment cues and at_word will degrade to at-time`,\n ];\n logger.warn(stageWarnings[0]!);\n\n const artifacts: SegmentArtifact[] = [];\n let totalCharacters = 0;\n\n for (const segment of manifest.segments) {\n const finalPath = join(audioDir, `${segment.id}.mp3`);\n if ((await fileExists(finalPath)) && !forced) {\n const existingDuration = await ffprobeDuration(finalPath).catch(\n () => segment.end - segment.start,\n );\n artifacts.push({\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: existingDuration,\n final_duration_seconds: existingDuration,\n target_duration_seconds: existingDuration,\n characters_synthesized: 0,\n used_speed: voSpeed,\n drift_action: 'reused',\n pause_strategy: 'master_slice',\n warnings: [],\n });\n logger.event({ stage: 'voiceover', status: 'reusing', segment: segment.id, path: finalPath });\n continue;\n }\n\n logger.event({\n stage: 'voiceover',\n status: 'synthesizing_segment',\n provider: provider.name,\n segment: segment.id,\n });\n const result = await provider.synthesize({ text: segment.vo_line });\n await writeFile(finalPath, result.audio);\n totalCharacters += result.charactersSynthesized;\n const finalDuration = await ffprobeDuration(finalPath);\n artifacts.push({\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: result.durationSeconds,\n final_duration_seconds: finalDuration,\n target_duration_seconds: finalDuration + tailPaddingSec,\n characters_synthesized: result.charactersSynthesized,\n used_speed: voSpeed,\n drift_action: 'kept',\n pause_strategy: 'master_slice',\n warnings: [],\n });\n logger.event({\n stage: 'voiceover',\n status: 'segment_complete',\n segment: segment.id,\n duration: finalDuration.toFixed(2),\n });\n }\n\n const rewritten = rewriteManifestTimings(manifest, artifacts);\n if (rewritten.changed) {\n await writeManifest(manifestPath, rewritten.manifest);\n stageWarnings.push(\n `manifest timings derived from per-segment VO: total_duration ${manifest.total_duration_seconds.toFixed(2)}s → ${rewritten.manifest.total_duration_seconds.toFixed(2)}s`,\n );\n }\n\n const summaryPath = join(audioDir, 'voiceover_summary.json');\n await writeFile(\n summaryPath,\n JSON.stringify(\n {\n mode: 'per_segment_best_effort',\n provider: provider.name,\n alignment_available: false,\n characters_synthesized: totalCharacters,\n segments: artifacts,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n const artifactsRecord: Record<string, string> = { voiceover_summary: summaryPath };\n for (const a of artifacts) artifactsRecord[`audio_${a.segment_id}`] = a.final_path;\n\n return {\n stage: 'voiceover',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: artifactsRecord,\n warnings: [...stageWarnings, ...artifacts.flatMap((a) => a.warnings)],\n meta: {\n mode: 'best_effort',\n provider: provider.name,\n alignment_available: false,\n segments: artifacts.length,\n characters_synthesized: totalCharacters,\n },\n };\n}\n","import { spawn } from 'node:child_process';\n\nexport type FfmpegErrorCategory =\n | 'oom'\n | 'no_space'\n | 'codec_missing'\n | 'permission'\n | 'unknown';\n\nexport class FfmpegError extends Error {\n override readonly name = 'FfmpegError';\n readonly category: FfmpegErrorCategory;\n constructor(\n message: string,\n readonly exitCode: number | null,\n readonly stderr: string,\n category?: FfmpegErrorCategory,\n ) {\n super(message);\n this.category = category ?? classifyFfmpegStderr(stderr);\n }\n}\n\n/**\n * Pure classifier — pattern-match common failure modes in ffmpeg/x264 stderr\n * so callers can attach actionable remediation hints.\n */\nexport function classifyFfmpegStderr(stderr: string): FfmpegErrorCategory {\n if (/malloc|out of memory|cannot allocate/i.test(stderr)) return 'oom';\n if (/no space left|ENOSPC|disk full/i.test(stderr)) return 'no_space';\n if (/unknown encoder|encoder not found|libx264 not found/i.test(stderr)) return 'codec_missing';\n if (/EACCES|permission denied/i.test(stderr)) return 'permission';\n return 'unknown';\n}\n\n/**\n * Build an actionable hint to append to an ffmpeg failure message based on its\n * category. Caller injects width/height/workDir context where relevant.\n */\nexport function ffmpegHintFor(\n category: FfmpegErrorCategory,\n ctx?: { width?: number; height?: number; workDir?: string },\n): string {\n switch (category) {\n case 'oom': {\n const cur = ctx?.width && ctx?.height ? ` (currently ${ctx.width}x${ctx.height})` : '';\n return `x264 ran out of working memory${cur}. Try lowering output.resolution to 1280x720, or set SHOWRUNNER_FFMPEG_THREADS=1 to use a single encoder thread.`;\n }\n case 'no_space':\n return `Disk full${ctx?.workDir ? ` at ${ctx.workDir}` : ''}. Free up space and re-run.`;\n case 'codec_missing':\n return `Your ffmpeg build is missing libx264. Reinstall ffmpeg with --enable-libx264 (or via your package manager's \"ffmpeg-full\" variant).`;\n case 'permission':\n return `Permission denied. Check write access on the output directory.`;\n case 'unknown':\n return '';\n }\n}\n\nexport interface RunOptions {\n bin?: string;\n args: string[];\n captureStderr?: boolean;\n /** Inject `-threads N` before the output path. Useful for memory-constrained encodes. */\n threads?: number;\n /** Context for error hint rendering (resolution, work dir). */\n hintContext?: { width?: number; height?: number; workDir?: string };\n}\n\nexport async function runFfmpeg(opts: RunOptions): Promise<{ stderr: string }> {\n const bin = opts.bin ?? 'ffmpeg';\n const args =\n opts.threads !== undefined\n ? injectThreadsArg(opts.args, opts.threads)\n : opts.args;\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(bin, args, { stdio: ['ignore', 'ignore', 'pipe'] });\n let stderr = '';\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code === 0) {\n resolveRun({ stderr });\n } else {\n const category = classifyFfmpegStderr(stderr);\n const hint = ffmpegHintFor(category, opts.hintContext);\n const hintLine = hint ? `\\n→ ${hint}` : '';\n rejectRun(\n new FfmpegError(\n `${bin} exited ${code}${hintLine}\\n${stderr.slice(-2000)}`,\n code,\n stderr,\n category,\n ),\n );\n }\n });\n });\n}\n\n/**\n * Insert `-threads N` immediately before the output path (last arg). Idempotent\n * if the input already contained `-threads`.\n */\nfunction injectThreadsArg(args: string[], threads: number): string[] {\n if (args.includes('-threads')) return args;\n // Output path is conventionally the last positional arg in ffmpeg invocations.\n return [...args.slice(0, -1), '-threads', String(threads), args[args.length - 1]!];\n}\n\n/**\n * Get the duration of an audio buffer by piping it through ffprobe via stdin.\n * Avoids the tmpfile dance for short clips returned directly from a TTS API.\n */\nexport async function ffprobeDurationFromStdin(buf: Buffer): Promise<number> {\n const bin = 'ffprobe';\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(\n bin,\n ['-i', 'pipe:0', '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv=p=0'],\n { stdio: ['pipe', 'pipe', 'pipe'] },\n );\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code !== 0) {\n rejectRun(new FfmpegError(`${bin} exited ${code}: ${stderr.slice(-500)}`, code, stderr));\n return;\n }\n const trimmed = stdout.trim();\n const n = Number.parseFloat(trimmed);\n if (Number.isNaN(n)) {\n rejectRun(new FfmpegError(`${bin} returned unparseable duration: ${trimmed}`, code, stderr));\n } else {\n resolveRun(n);\n }\n });\n child.stdin.write(buf);\n child.stdin.end();\n });\n}\n\nexport async function ffprobeDuration(path: string): Promise<number> {\n const bin = 'ffprobe';\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(\n bin,\n ['-i', path, '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv=p=0'],\n { stdio: ['ignore', 'pipe', 'pipe'] },\n );\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code !== 0) {\n rejectRun(new FfmpegError(`${bin} exited ${code}: ${stderr.slice(-500)}`, code, stderr));\n return;\n }\n const trimmed = stdout.trim();\n const n = Number.parseFloat(trimmed);\n if (Number.isNaN(n)) {\n rejectRun(new FfmpegError(`${bin} returned unparseable duration: ${trimmed}`, code, stderr));\n } else {\n resolveRun(n);\n }\n });\n });\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { logger } from '../util/logger.js';\nimport { runFfmpeg } from './ffmpeg.js';\nimport type { Segment } from '../manifest/schema.js';\nimport type { CharacterAlignment } from '../manifest/alignment.js';\n\nexport interface SegmentWindow {\n segment_id: string;\n start_time_seconds: number;\n end_time_seconds: number;\n start_char_index: number;\n end_char_index: number;\n}\n\nexport interface BreakPolicy {\n /** Default pause between segments, in seconds. */\n betweenSegments: number;\n /** Pause around fade_in / fade_out transitions. */\n fadeBoundary: number;\n}\n\nconst DEFAULT_BREAK_POLICY: BreakPolicy = {\n betweenSegments: 0.45,\n fadeBoundary: 0.75,\n};\n\n/**\n * Build the master script that gets sent as a single ElevenLabs call. Segments\n * are joined with `<break time=\"X.Xs\"/>` SSML tags so the TTS engine renders\n * one continuous take with model-generated pauses between segments — preserving\n * prosody, breath, and natural intonation across the entire demo. Slicing back\n * into per-segment files happens against the rendered audio, at midpoints\n * inside each break, so concatenation reproduces the master.\n */\nexport function buildFullScript(segments: Segment[], policy: BreakPolicy = DEFAULT_BREAK_POLICY): string {\n const parts: string[] = [];\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]!;\n if (i > 0) {\n const prev = segments[i - 1]!;\n const fade = prev.transition === 'fade_out' || seg.transition === 'fade_in';\n const dur = fade ? policy.fadeBoundary : policy.betweenSegments;\n parts.push(`<break time=\"${dur.toFixed(2)}s\"/>`);\n }\n parts.push(seg.vo_line.trim());\n }\n return parts.join(' ');\n}\n\n/**\n * Walk the alignment.characters array and identify, for each segment, the\n * [start, end] character indices that correspond to its vo_line. We match by\n * comparing collapsed-whitespace prefixes — robust to small drift between the\n * exact text we sent and what ElevenLabs reports back in the alignment.\n */\nexport function locateSegmentWindows(\n segments: Segment[],\n alignment: CharacterAlignment,\n): SegmentWindow[] {\n const windows: SegmentWindow[] = [];\n let cursor = 0;\n for (const seg of segments) {\n const target = seg.vo_line.trim();\n if (target.length === 0) {\n windows.push({\n segment_id: seg.id,\n start_time_seconds: cursor < alignment.character_start_times_seconds.length\n ? alignment.character_start_times_seconds[cursor] ?? 0\n : 0,\n end_time_seconds: cursor < alignment.character_end_times_seconds.length\n ? alignment.character_end_times_seconds[cursor] ?? 0\n : 0,\n start_char_index: cursor,\n end_char_index: cursor,\n });\n continue;\n }\n const startIdx = findSegmentStart(alignment.characters, target, cursor);\n if (startIdx === -1) {\n throw new Error(\n `Could not locate segment \"${seg.id}\" in master alignment (starting search at index ${cursor}). ` +\n `First 80 chars of expected text: ${JSON.stringify(target.slice(0, 80))}`,\n );\n }\n const endIdx = findSegmentEnd(alignment.characters, target, startIdx);\n if (endIdx === -1) {\n throw new Error(\n `Located start of segment \"${seg.id}\" at index ${startIdx} but could not find its end.`,\n );\n }\n windows.push({\n segment_id: seg.id,\n start_time_seconds: alignment.character_start_times_seconds[startIdx] ?? 0,\n end_time_seconds: alignment.character_end_times_seconds[endIdx] ?? 0,\n start_char_index: startIdx,\n end_char_index: endIdx,\n });\n cursor = endIdx + 1;\n }\n return windows;\n}\n\n/**\n * Find the index in `chars` where `target` begins, starting search at `from`.\n * Tolerates whitespace differences (consecutive whitespace in either string is\n * treated as a single space).\n */\nfunction findSegmentStart(chars: string[], target: string, from: number): number {\n const normTarget = collapseWhitespace(target);\n const firstTargetChar = normTarget[0]!;\n for (let i = from; i < chars.length; i++) {\n const c = chars[i]!;\n if (c.toLowerCase() !== firstTargetChar.toLowerCase()) continue;\n if (matchesAt(chars, i, normTarget)) return i;\n }\n return -1;\n}\n\nfunction findSegmentEnd(chars: string[], target: string, startIdx: number): number {\n // Walk forward from startIdx, matching against target with whitespace tolerance.\n let ti = 0;\n let ci = startIdx;\n const normTarget = collapseWhitespace(target);\n while (ti < normTarget.length && ci < chars.length) {\n const tc = normTarget[ti]!;\n const cc = chars[ci]!;\n if (tc === ' ') {\n // Consume one or more whitespace chars in source\n if (isWs(cc)) {\n while (ci < chars.length && isWs(chars[ci]!)) ci++;\n ti++;\n continue;\n }\n // Target wants space but source doesn't — abort\n return -1;\n }\n if (cc.toLowerCase() === tc.toLowerCase()) {\n ti++;\n ci++;\n continue;\n }\n if (isWs(cc)) {\n // skip extra whitespace in source\n ci++;\n continue;\n }\n return -1;\n }\n return ti === normTarget.length ? ci - 1 : -1;\n}\n\nfunction matchesAt(chars: string[], from: number, normTarget: string): boolean {\n let ti = 0;\n let ci = from;\n // Quick check: scan PREFIX_CHECK characters\n const PREFIX_CHECK = Math.min(20, normTarget.length);\n while (ti < PREFIX_CHECK && ci < chars.length) {\n const tc = normTarget[ti]!;\n const cc = chars[ci]!;\n if (tc === ' ') {\n if (isWs(cc)) {\n while (ci < chars.length && isWs(chars[ci]!)) ci++;\n ti++;\n continue;\n }\n return false;\n }\n if (cc.toLowerCase() === tc.toLowerCase()) {\n ti++;\n ci++;\n continue;\n }\n if (isWs(cc)) {\n ci++;\n continue;\n }\n return false;\n }\n return ti === PREFIX_CHECK;\n}\n\nfunction collapseWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ');\n}\n\nfunction isWs(ch: string): boolean {\n return ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r';\n}\n\nexport interface SliceBoundary {\n segment_id: string;\n /** Start time in master (seconds). Includes leading silence up to the midpoint of the prior gap. */\n start_sec: number;\n /** End time in master (seconds). Includes trailing silence up to the midpoint of the next gap. */\n end_sec: number;\n}\n\n/**\n * Convert per-segment character windows into mp3 slice boundaries. Each segment\n * absorbs half of the silence on either side of it, so concatenating all slices\n * exactly reproduces the master audio — preserving the model-generated pauses\n * (and the natural breath/prosody around them) instead of replacing them with\n * dead silence.\n */\nexport function computeSliceBoundaries(\n windows: SegmentWindow[],\n masterDurationSec: number,\n): SliceBoundary[] {\n const boundaries: SliceBoundary[] = [];\n for (let i = 0; i < windows.length; i++) {\n const w = windows[i]!;\n const prev = windows[i - 1];\n const next = windows[i + 1];\n const start =\n i === 0\n ? 0\n : (prev!.end_time_seconds + w.start_time_seconds) / 2;\n const end =\n i === windows.length - 1\n ? masterDurationSec\n : (w.end_time_seconds + next!.start_time_seconds) / 2;\n boundaries.push({ segment_id: w.segment_id, start_sec: start, end_sec: end });\n }\n return boundaries;\n}\n\n/**\n * Slice a single segment out of the master mp3 with a clean re-encode so cut\n * boundaries land on frame edges. Re-encode is fast for ~5s clips and avoids\n * the keyframe glitches `-c copy` would introduce.\n */\nexport async function sliceMasterAudio(opts: {\n masterPath: string;\n outputPath: string;\n startSec: number;\n durationSec: number;\n}): Promise<void> {\n await runFfmpeg({\n args: [\n '-y',\n '-ss',\n opts.startSec.toFixed(3),\n '-i',\n opts.masterPath,\n '-t',\n Math.max(0.1, opts.durationSec).toFixed(3),\n '-c:a',\n 'libmp3lame',\n '-q:a',\n '4',\n opts.outputPath,\n ],\n });\n}\n\n/**\n * Build a per-segment alignment file by slicing the master alignment and\n * shifting all timestamps into segment-mp3-file time. The mp3 starts at\n * `boundary.start_sec` in the master, so subtracting that gives times that are\n * relative to the segment's mp3 file (i.e. include the leading silence before\n * the speech starts). This is what both record.ts (at_word resolution) and\n * captions.ts (cue scheduling) need.\n */\nexport function sliceAlignment(\n master: CharacterAlignment,\n window: SegmentWindow,\n boundary: SliceBoundary,\n): CharacterAlignment {\n const start = window.start_char_index;\n const end = window.end_char_index;\n const t0 = boundary.start_sec;\n return {\n characters: master.characters.slice(start, end + 1),\n character_start_times_seconds: master.character_start_times_seconds\n .slice(start, end + 1)\n .map((t) => t - t0),\n character_end_times_seconds: master.character_end_times_seconds\n .slice(start, end + 1)\n .map((t) => t - t0),\n };\n}\n\nexport async function loadMasterAlignment(path: string): Promise<CharacterAlignment | null> {\n try {\n const raw = await readFile(path, 'utf8');\n return JSON.parse(raw) as CharacterAlignment;\n } catch {\n return null;\n }\n}\n\nexport async function writeMasterAlignment(\n path: string,\n alignment: CharacterAlignment,\n): Promise<void> {\n await writeFile(path, JSON.stringify(alignment) + '\\n', 'utf8');\n logger.debug(`Wrote master alignment to ${path}`);\n}\n\nexport interface MasterPaths {\n rawAudio: string;\n alignment: string;\n}\n\nexport function masterPaths(audioDir: string, alignmentDir: string): MasterPaths {\n return {\n rawAudio: join(audioDir, '_master.raw.mp3'),\n alignment: join(alignmentDir, '_master.alignment.json'),\n };\n}\n","import type { CharacterAlignment } from '../../manifest/alignment.js';\n\nexport interface TTSSynthesisRequest {\n text: string;\n /** Provider-specific voice id; falls back to whatever the provider was constructed with. */\n voice?: string;\n /** Playback speed multiplier (provider-dependent; safe range typically 0.85–1.15). */\n speed?: number;\n}\n\nexport interface TTSSynthesisResult {\n audio: Buffer;\n /** Character-level timing data. Optional — only ElevenLabs `with_timestamps` returns this today. */\n alignment?: CharacterAlignment;\n durationSeconds: number;\n charactersSynthesized: number;\n}\n\nexport interface TTSProvider {\n /** Provider name for logging/diagnostics. */\n readonly name: string;\n /** True if this provider returns character-level alignment data. */\n readonly supportsAlignment: boolean;\n synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult>;\n}\n\nexport class TTSProviderError extends Error {\n override readonly name = 'TTSProviderError';\n constructor(\n message: string,\n readonly providerName: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n","import { request } from 'undici';\nimport { logger } from '../util/logger.js';\n\nconst BASE_URL = 'https://api.elevenlabs.io';\n\nexport interface VoiceSettings {\n stability: number;\n similarity_boost: number;\n style: number;\n use_speaker_boost: boolean;\n speed: number;\n}\n\nexport interface SynthesisRequest {\n voiceId: string;\n modelId: string;\n text: string;\n voiceSettings: VoiceSettings;\n apiKey: string;\n}\n\nexport interface WithTimestampsResponse {\n audio_base64: string;\n alignment: {\n characters: string[];\n character_start_times_seconds: number[];\n character_end_times_seconds: number[];\n };\n}\n\nexport interface SynthesisResult {\n audio: Buffer;\n alignment?: WithTimestampsResponse['alignment'];\n durationSeconds: number;\n charactersSynthesized: number;\n}\n\nexport class ElevenLabsError extends Error {\n override readonly name = 'ElevenLabsError';\n constructor(\n message: string,\n readonly status: number,\n readonly body: string,\n ) {\n super(message);\n }\n}\n\nconst MAX_ATTEMPTS = 3;\n\nexport async function synthesizeWithTimestamps(req: SynthesisRequest): Promise<SynthesisResult> {\n const url = `${BASE_URL}/v1/text-to-speech/${encodeURIComponent(req.voiceId)}/with-timestamps`;\n const body = {\n text: req.text,\n model_id: req.modelId,\n voice_settings: req.voiceSettings,\n };\n\n const responseJson = await postWithRetry(url, body, req.apiKey, 'json');\n const parsed = responseJson as WithTimestampsResponse;\n if (\n typeof parsed.audio_base64 !== 'string' ||\n !parsed.alignment ||\n !Array.isArray(parsed.alignment.character_end_times_seconds)\n ) {\n throw new ElevenLabsError(\n 'ElevenLabs with_timestamps response shape unexpected',\n 200,\n JSON.stringify(parsed).slice(0, 500),\n );\n }\n\n const audio = Buffer.from(parsed.audio_base64, 'base64');\n const endTimes = parsed.alignment.character_end_times_seconds;\n const durationSeconds = endTimes.length > 0 ? (endTimes[endTimes.length - 1] ?? 0) : 0;\n\n return {\n audio,\n alignment: parsed.alignment,\n durationSeconds,\n charactersSynthesized: req.text.length,\n };\n}\n\nexport async function synthesizeBasic(req: SynthesisRequest): Promise<Omit<SynthesisResult, 'durationSeconds'>> {\n const url = `${BASE_URL}/v1/text-to-speech/${encodeURIComponent(req.voiceId)}`;\n const body = {\n text: req.text,\n model_id: req.modelId,\n voice_settings: req.voiceSettings,\n };\n\n const audio = (await postWithRetry(url, body, req.apiKey, 'binary')) as Buffer;\n return {\n audio,\n charactersSynthesized: req.text.length,\n };\n}\n\nasync function postWithRetry(\n url: string,\n body: unknown,\n apiKey: string,\n responseMode: 'json' | 'binary',\n): Promise<unknown> {\n let lastError: ElevenLabsError | undefined;\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n return await postOnce(url, body, apiKey, responseMode);\n } catch (err) {\n if (!(err instanceof ElevenLabsError)) throw err;\n lastError = err;\n const retriable = err.status === 429 || err.status >= 500;\n if (!retriable || attempt === MAX_ATTEMPTS) break;\n const backoffMs = Math.min(8000, 500 * 2 ** (attempt - 1));\n logger.warn(`ElevenLabs ${err.status} on attempt ${attempt}, retrying in ${backoffMs}ms`);\n await sleep(backoffMs);\n }\n }\n throw lastError ?? new ElevenLabsError('ElevenLabs request failed', 0, '');\n}\n\nasync function postOnce(\n url: string,\n body: unknown,\n apiKey: string,\n responseMode: 'json' | 'binary',\n): Promise<unknown> {\n const res = await request(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: responseMode === 'json' ? 'application/json' : 'audio/mpeg',\n 'xi-api-key': apiKey,\n },\n body: JSON.stringify(body),\n });\n\n if (res.statusCode >= 400) {\n const errBody = await res.body.text();\n throw new ElevenLabsError(\n `ElevenLabs ${res.statusCode}: ${errBody.slice(0, 300)}`,\n res.statusCode,\n errBody,\n );\n }\n\n if (responseMode === 'json') {\n return await res.body.json();\n }\n const buf = Buffer.from(await res.body.arrayBuffer());\n return buf;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));\n}\n","import { synthesizeWithTimestamps } from '../../voiceover/elevenlabs.js';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface ElevenLabsProviderConfig {\n apiKey: string;\n voiceId: string;\n modelId: string;\n stability: number;\n similarityBoost: number;\n style: number;\n useSpeakerBoost: boolean;\n speed: number;\n}\n\nexport class ElevenLabsTTSProvider implements TTSProvider {\n readonly name = 'elevenlabs';\n readonly supportsAlignment = true;\n\n constructor(private readonly cfg: ElevenLabsProviderConfig) {\n if (!cfg.apiKey) {\n throw new TTSProviderError(\n 'ElevenLabsTTSProvider: apiKey is required',\n 'elevenlabs',\n );\n }\n }\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n const result = await synthesizeWithTimestamps({\n voiceId: req.voice ?? this.cfg.voiceId,\n modelId: this.cfg.modelId,\n text: req.text,\n voiceSettings: {\n stability: this.cfg.stability,\n similarity_boost: this.cfg.similarityBoost,\n style: this.cfg.style,\n use_speaker_boost: this.cfg.useSpeakerBoost,\n speed: req.speed ?? this.cfg.speed,\n },\n apiKey: this.cfg.apiKey,\n });\n return {\n audio: result.audio,\n alignment: result.alignment,\n durationSeconds: result.durationSeconds,\n charactersSynthesized: result.charactersSynthesized,\n };\n }\n}\n","import OpenAI from 'openai';\nimport { ffprobeDurationFromStdin } from '../../voiceover/ffmpeg.js';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface OpenAITTSProviderConfig {\n apiKey: string;\n /** Voice id, e.g. 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'. */\n voice: string;\n /** Model, e.g. 'tts-1', 'tts-1-hd', or 'gpt-4o-mini-tts'. */\n model: string;\n /** Override the API base (Azure / OpenRouter / etc). */\n baseURL?: string;\n}\n\nexport class OpenAITTSProvider implements TTSProvider {\n readonly name = 'openai';\n readonly supportsAlignment = false;\n\n private readonly client: OpenAI;\n\n constructor(private readonly cfg: OpenAITTSProviderConfig) {\n if (!cfg.apiKey) {\n throw new TTSProviderError(\n 'OpenAITTSProvider: apiKey is required',\n 'openai',\n );\n }\n this.client = new OpenAI({ apiKey: cfg.apiKey, baseURL: cfg.baseURL });\n }\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n let response;\n try {\n response = await this.client.audio.speech.create({\n model: this.cfg.model,\n voice: (req.voice ?? this.cfg.voice) as 'alloy',\n input: req.text,\n response_format: 'mp3',\n speed: req.speed ?? 1.0,\n });\n } catch (err) {\n throw new TTSProviderError(\n `OpenAI TTS call failed: ${err instanceof Error ? err.message : String(err)}`,\n 'openai',\n err,\n );\n }\n const arrayBuffer = await response.arrayBuffer();\n const audio = Buffer.from(arrayBuffer);\n const durationSeconds = await ffprobeDurationFromStdin(audio);\n return {\n audio,\n // OpenAI TTS does not return character/word alignment.\n alignment: undefined,\n durationSeconds,\n charactersSynthesized: req.text.length,\n };\n }\n}\n","import { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface CustomTTSProviderConfig {\n modulePath: string;\n configDir: string;\n options?: Record<string, unknown>;\n}\n\n/**\n * Loads an operator-supplied module that default-exports either a TTSProvider\n * directly or a factory function. Same shape as CustomLLMProvider.\n */\nexport class CustomTTSProvider implements TTSProvider {\n readonly name = 'custom';\n // We can't know up-front whether the custom provider supports alignment.\n // Default to false; the actual provider it loads can advertise its own.\n readonly supportsAlignment = false;\n\n private inner: Promise<TTSProvider> | null = null;\n constructor(private readonly cfg: CustomTTSProviderConfig) {}\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n const provider = await this.load();\n return provider.synthesize(req);\n }\n\n private async load(): Promise<TTSProvider> {\n if (this.inner) return this.inner;\n this.inner = (async () => {\n const absPath = isAbsolute(this.cfg.modulePath)\n ? this.cfg.modulePath\n : resolve(this.cfg.configDir, this.cfg.modulePath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(absPath).href)) as { default?: unknown };\n } catch (err) {\n throw new TTSProviderError(\n `Failed to load custom TTS module at ${absPath}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'custom',\n err,\n );\n }\n const exp = mod.default ?? mod;\n if (typeof exp === 'function') {\n const built = await (exp as (o?: unknown) => Promise<TTSProvider> | TTSProvider)(\n this.cfg.options,\n );\n if (!isTTSProvider(built)) {\n throw new TTSProviderError(\n `Custom TTS module at ${absPath} returned a value that is not a TTSProvider (missing synthesize)`,\n 'custom',\n );\n }\n return built;\n }\n if (isTTSProvider(exp)) return exp;\n throw new TTSProviderError(\n `Custom TTS module at ${absPath} must default-export a TTSProvider or a factory function`,\n 'custom',\n );\n })();\n return this.inner;\n }\n}\n\nfunction isTTSProvider(v: unknown): v is TTSProvider {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as { synthesize?: unknown }).synthesize === 'function'\n );\n}\n","import type { TTSProvider } from './types.js';\nimport { TTSProviderError } from './types.js';\nimport { ElevenLabsTTSProvider } from './elevenlabs.js';\nimport { OpenAITTSProvider } from './openai.js';\nimport { CustomTTSProvider } from './custom.js';\n\nexport interface ElevenLabsTTSSpec {\n name: 'elevenlabs';\n voice_id: string;\n model: string;\n api_key_env: string;\n endpoint?: 'with_timestamps' | 'basic';\n stability: number;\n similarity_boost: number;\n style: number;\n use_speaker_boost: boolean;\n speed: number;\n}\n\nexport interface OpenAITTSSpec {\n name: 'openai';\n voice: string;\n model: string;\n api_key_env: string;\n base_url?: string;\n}\n\nexport interface CustomTTSSpec {\n name: 'custom';\n module_path: string;\n options?: Record<string, unknown>;\n}\n\nexport type TTSProviderSpec = ElevenLabsTTSSpec | OpenAITTSSpec | CustomTTSSpec;\n\nexport interface CreateTTSContext {\n configDir: string;\n}\n\nexport function createTTSProvider(spec: TTSProviderSpec, ctx: CreateTTSContext): TTSProvider {\n switch (spec.name) {\n case 'elevenlabs': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new TTSProviderError(\n `TTS provider 'elevenlabs' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'elevenlabs',\n );\n }\n return new ElevenLabsTTSProvider({\n apiKey,\n voiceId: spec.voice_id,\n modelId: spec.model,\n stability: spec.stability,\n similarityBoost: spec.similarity_boost,\n style: spec.style,\n useSpeakerBoost: spec.use_speaker_boost,\n speed: spec.speed,\n });\n }\n case 'openai': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new TTSProviderError(\n `TTS provider 'openai' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'openai',\n );\n }\n return new OpenAITTSProvider({\n apiKey,\n voice: spec.voice,\n model: spec.model,\n baseURL: spec.base_url,\n });\n }\n case 'custom':\n return new CustomTTSProvider({\n modulePath: spec.module_path,\n configDir: ctx.configDir,\n options: spec.options,\n });\n }\n}\n\n/**\n * Narrowing helper: return the ElevenLabs sub-config when that's the configured\n * provider, otherwise null. Used by call sites that need to read voice_id etc.\n * without unwrapping the full discriminated union everywhere.\n */\nexport function getElevenLabsSpec(spec: TTSProviderSpec): ElevenLabsTTSSpec | null {\n return spec.name === 'elevenlabs' ? spec : null;\n}\n","import type { PipelineContext } from '../../pipeline/types.js';\nimport type { TTSProvider } from './types.js';\nimport {\n createTTSProvider,\n getElevenLabsSpec,\n type ElevenLabsTTSSpec,\n type TTSProviderSpec,\n} from './factory.js';\nimport type { TTSProviderConfig } from '../../config/schema.js';\n\nconst PROVIDER_CACHE = new WeakMap<PipelineContext, TTSProvider>();\n\n/**\n * Build (or fetch the cached) TTSProvider for this run.\n *\n * Reads from `ctx.providers.tts` when pre-wired by the pipeline, otherwise\n * constructs lazily from `ctx.config.voiceover.provider`. Caching is per-ctx\n * so repeated calls within a stage share the same provider instance.\n */\nexport function resolveTTSProvider(ctx: PipelineContext): TTSProvider {\n const pre = (ctx as PipelineContext & { providers?: { tts?: TTSProvider } }).providers;\n if (pre?.tts) return pre.tts;\n\n const cached = PROVIDER_CACHE.get(ctx);\n if (cached) return cached;\n\n const spec = configToSpec(ctx.config.voiceover.provider);\n const provider = createTTSProvider(spec, { configDir: ctx.configDir });\n PROVIDER_CACHE.set(ctx, provider);\n return provider;\n}\n\nexport type AlignmentStrategy = 'required' | 'best_effort';\n\nexport function resolveAlignmentStrategy(ctx: PipelineContext): AlignmentStrategy {\n return ctx.config.voiceover.alignment_strategy ?? 'required';\n}\n\n/**\n * Narrowing helper for legacy ElevenLabs-only call sites (e.g. `voiceover.ts`\n * reads `vo.speed` for the \"used_speed\" metadata field). Returns the\n * ElevenLabs sub-spec when configured, otherwise null.\n */\nexport function resolveElevenLabsConfigOrNull(ctx: PipelineContext): ElevenLabsTTSSpec | null {\n const spec = configToSpec(ctx.config.voiceover.provider);\n return getElevenLabsSpec(spec);\n}\n\nfunction configToSpec(cfg: TTSProviderConfig): TTSProviderSpec {\n switch (cfg.name) {\n case 'elevenlabs':\n return {\n name: 'elevenlabs',\n voice_id: cfg.voice_id,\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n endpoint: cfg.endpoint,\n stability: cfg.stability,\n similarity_boost: cfg.similarity_boost,\n style: cfg.style,\n use_speaker_boost: cfg.use_speaker_boost,\n speed: cfg.speed,\n };\n case 'openai':\n return {\n name: 'openai',\n voice: cfg.voice,\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.base_url !== undefined && { base_url: cfg.base_url }),\n };\n case 'custom':\n return {\n name: 'custom',\n module_path: cfg.module_path,\n ...(cfg.options !== undefined && { options: cfg.options }),\n };\n }\n}\n","import { mkdir, rm, rename } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { ffprobeDuration } from '../voiceover/ffmpeg.js';\nimport { normalizeVideo } from '../mux/normalize.js';\nimport { prepareSegmentVideo, readSlicePlan } from '../mux/slice.js';\nimport { muxSegment } from '../mux/segmentMux.js';\nimport { concatSegments } from '../mux/concat.js';\nimport { applyBackgroundMusic, fileExists, renderCard } from '../mux/branding.js';\nimport { emitCaptions } from '../mux/captions.js';\nimport {\n assertEnoughDisk,\n computeThreadCap,\n formatBytes,\n getFreeDiskBytes,\n getFreeMemoryBytes,\n} from '../util/resources.js';\n\nexport const muxStage: Stage = {\n name: 'mux',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const videoDir = resolve(ctx.configDir, ctx.config.recording.output_dir);\n const audioDir = resolve(ctx.configDir, ctx.config.voiceover.output_dir);\n const masterWebm = resolve(videoDir, 'master.webm');\n const slicePlanPath = resolve(videoDir, 'slice_plan.json');\n const outputPath = resolveOutput(ctx.config.output.output_path, ctx.configDir);\n\n const forced = ctx.forced.has('mux');\n if ((await fileExists(outputPath)) && !forced) {\n logger.event({ stage: 'mux', status: 'reusing', path: outputPath });\n return {\n stage: 'mux',\n skipped: true,\n reason: 'output file already present',\n durationMs: Date.now() - start,\n artifacts: { output: outputPath },\n };\n }\n\n for (const [label, path] of [\n ['manifest.json', manifestPath],\n ['master.webm', masterWebm],\n ['slice_plan.json', slicePlanPath],\n ] as const) {\n if (!(await fileExists(path))) {\n return {\n stage: 'mux',\n skipped: true,\n reason: `${label} not found at ${path} — run upstream stages first`,\n durationMs: Date.now() - start,\n };\n }\n }\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`mux stage: ${err.message}`);\n }\n throw err;\n }\n\n const slicePlan = await readSlicePlan(slicePlanPath);\n\n for (const seg of manifest.segments) {\n const audio = join(audioDir, `${seg.id}.mp3`);\n if (!(await fileExists(audio))) {\n return {\n stage: 'mux',\n skipped: true,\n reason: `audio for segment \"${seg.id}\" not found at ${audio} — run voiceover stage first`,\n durationMs: Date.now() - start,\n };\n }\n }\n\n const workDir = resolve(ctx.configDir, '.showrunner-cache', 'mux');\n await mkdir(workDir, { recursive: true });\n\n const fps = ctx.config.output.fps;\n const [widthStr, heightStr] = ctx.config.output.resolution.split('x');\n const width = Number.parseInt(widthStr!, 10);\n const height = Number.parseInt(heightStr!, 10);\n const quality = ctx.config.output.quality;\n logger.event({ stage: 'mux', status: 'quality', preset: quality });\n\n // Preflight: RAM headroom drives a per-encode thread cap; disk space gets\n // a sanity check on the workDir (rough estimate: 50 MB per segment + 200 MB\n // for the normalized master + final mp4 headroom).\n const freeMem = getFreeMemoryBytes();\n const freeDisk = await getFreeDiskBytes(workDir);\n const threads = computeThreadCap({ width, height, fps, quality, freeMemBytes: freeMem });\n const estDiskNeed = (manifest.segments.length * 50 + 200) * 1024 * 1024;\n logger.event({\n stage: 'mux',\n status: 'preflight',\n free_mem: formatBytes(freeMem),\n free_disk: formatBytes(freeDisk),\n threads,\n est_disk_need: formatBytes(estDiskNeed),\n });\n await assertEnoughDisk(workDir, estDiskNeed, 'mux workDir');\n\n logger.event({ stage: 'mux', status: 'normalizing_master' });\n const normalizedMaster = join(workDir, 'master.mp4');\n await normalizeVideo({\n inputPath: masterWebm,\n outputPath: normalizedMaster,\n fps,\n width,\n height,\n quality,\n threads,\n });\n\n const segmentPaths: string[] = [];\n\n if (ctx.config.output.branding.title_card?.enabled) {\n const tc = ctx.config.output.branding.title_card;\n const titlePath = join(workDir, '_title.mp4');\n await renderCard({\n outputPath: titlePath,\n width,\n height,\n fps,\n durationSeconds: tc.duration_seconds,\n text: tc.text,\n textColor: tc.text_color,\n backgroundColor: tc.background_color,\n fontPath: tc.font ? resolveMaybe(tc.font, ctx.configDir) : undefined,\n fontSize: tc.font_size,\n logoPath: tc.logo ? resolveMaybe(tc.logo, ctx.configDir) : undefined,\n logoPosition: tc.logo_position,\n quality,\n });\n segmentPaths.push(titlePath);\n logger.event({ stage: 'mux', status: 'title_card_rendered', path: titlePath });\n }\n\n for (const seg of manifest.segments) {\n logger.event({ stage: 'mux', status: 'segment_prepare', segment: seg.id });\n const videoSource = await prepareSegmentVideo({\n id: seg.id,\n videoDir,\n workDir,\n normalizedMasterPath: normalizedMaster,\n slicePlan,\n fps,\n width,\n height,\n quality,\n });\n\n const finalSeg = join(workDir, `${seg.id}.final.mp4`);\n await muxSegment({\n videoPath: videoSource.path,\n audioPath: join(audioDir, `${seg.id}.mp3`),\n outputPath: finalSeg,\n fps,\n width,\n height,\n transition: seg.transition,\n quality,\n });\n segmentPaths.push(finalSeg);\n logger.event({\n stage: 'mux',\n status: 'segment_muxed',\n segment: seg.id,\n source: videoSource.source,\n });\n }\n\n if (ctx.config.output.branding.outro_card?.enabled) {\n const oc = ctx.config.output.branding.outro_card;\n const outroPath = join(workDir, '_outro.mp4');\n await renderCard({\n outputPath: outroPath,\n width,\n height,\n fps,\n durationSeconds: oc.duration_seconds,\n text: oc.text,\n textColor: '#FFFFFF',\n backgroundColor: '#0F172A',\n fontSize: 36,\n quality,\n });\n segmentPaths.push(outroPath);\n logger.event({ stage: 'mux', status: 'outro_card_rendered', path: outroPath });\n }\n\n const concatPath = join(workDir, 'stitched.mp4');\n logger.event({ stage: 'mux', status: 'concat', inputs: segmentPaths.length });\n await concatSegments({\n segmentPaths,\n workDir,\n outputPath: concatPath,\n });\n\n let finalSource = concatPath;\n const music = ctx.config.output.background_music;\n if (music?.path) {\n const musicPath = resolveMaybe(music.path, ctx.configDir);\n if (await fileExists(musicPath)) {\n const mixed = join(workDir, 'mixed.mp4');\n logger.event({ stage: 'mux', status: 'background_music', path: musicPath });\n await applyBackgroundMusic({\n inputPath: concatPath,\n outputPath: mixed,\n musicPath,\n volumeDb: music.volume_db,\n quality,\n });\n finalSource = mixed;\n } else {\n warnings.push(`background_music.path not found at ${musicPath} — skipping mix`);\n }\n }\n\n await mkdir(dirname(outputPath), { recursive: true });\n let finalOutputPath = outputPath;\n if (await fileExists(outputPath)) {\n try {\n await rm(outputPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code ?? '';\n if (code === 'EBUSY' || code === 'EPERM') {\n const ext = outputPath.endsWith('.mp4') ? '.mp4' : '';\n const stem = outputPath.slice(0, outputPath.length - ext.length);\n const stamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .slice(0, 19);\n finalOutputPath = `${stem}-${stamp}${ext}`;\n warnings.push(\n `existing output ${outputPath} is locked (likely open in a player); wrote new MP4 to ${finalOutputPath} instead`,\n );\n logger.warn(\n `existing output locked; writing to ${finalOutputPath} (close the player to reuse the canonical filename)`,\n );\n } else {\n throw err;\n }\n }\n }\n await rename(finalSource, finalOutputPath);\n\n const finalDuration = await ffprobeDuration(finalOutputPath);\n\n const captionsCfg = ctx.config.output.captions;\n const captionPaths: string[] = [];\n if (captionsCfg.enabled) {\n const alignmentDir = resolve(ctx.configDir, ctx.config.voiceover.alignment_dir);\n const titleCardOffset = ctx.config.output.branding.title_card?.enabled\n ? ctx.config.output.branding.title_card.duration_seconds\n : 0;\n const outputBase = finalOutputPath.replace(/\\.mp4$/i, '');\n try {\n const written = await emitCaptions({\n manifest,\n alignmentDir,\n slicePlan,\n outputBase,\n format: captionsCfg.format,\n titleCardOffset,\n });\n captionPaths.push(...written);\n for (const p of written) {\n logger.event({ stage: 'mux', status: 'captions_written', path: p });\n }\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n warnings.push(`caption emission failed: ${cause}`);\n }\n }\n\n return {\n stage: 'mux',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: { output: finalOutputPath, captions: captionPaths.join(',') || undefined } as Record<\n string,\n string | undefined\n > as Record<string, string>,\n warnings,\n meta: {\n duration_seconds: finalDuration,\n segments: manifest.segments.length,\n had_title_card: !!ctx.config.output.branding.title_card?.enabled,\n had_outro_card: !!ctx.config.output.branding.outro_card?.enabled,\n captions: captionPaths,\n },\n };\n },\n};\n\nfunction resolveOutput(p: string, configDir: string): string {\n return isAbsolute(p) ? p : resolve(configDir, p);\n}\n\nfunction resolveMaybe(p: string, configDir: string): string {\n return isAbsolute(p) ? p : resolve(configDir, p);\n}\n","export type QualityPreset = 'draft' | 'standard' | 'high';\n\nexport interface ResolvedQuality {\n /** ffmpeg `-crf` (lower is better; 18–28 is the useful range for libx264). */\n crf: number;\n /** ffmpeg `-preset` (slower = smaller file). */\n preset: 'veryfast' | 'medium' | 'slow';\n /** ffmpeg `-b:a` audio bitrate. */\n audioBitrate: string;\n}\n\n/**\n * Map a human quality knob to ffmpeg encoder params.\n *\n * draft fast iterations: ~5x smaller, visibly soft\n * standard shipping default (matches the previous hardcoded values)\n * high crisp text + smooth motion; ~2x file size, ~3x encode time\n */\nexport function resolveQuality(preset: QualityPreset): ResolvedQuality {\n switch (preset) {\n case 'draft':\n return { crf: 28, preset: 'veryfast', audioBitrate: '128k' };\n case 'high':\n return { crf: 18, preset: 'slow', audioBitrate: '256k' };\n case 'standard':\n default:\n return { crf: 20, preset: 'medium', audioBitrate: '192k' };\n }\n}\n","import { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface NormalizeOptions {\n inputPath: string;\n outputPath: string;\n fps: number;\n width: number;\n height: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function normalizeVideo(opts: NormalizeOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const scaleFilter =\n `scale=${opts.width}:${opts.height}:force_original_aspect_ratio=decrease,` +\n `pad=${opts.width}:${opts.height}:(ow-iw)/2:(oh-ih)/2:color=black,` +\n `setsar=1,format=yuv420p`;\n\n await runFfmpeg({\n args: [\n '-y',\n '-i',\n opts.inputPath,\n '-vf',\n scaleFilter,\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-an',\n opts.outputPath,\n ],\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { normalizeVideo } from './normalize.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nconst sliceSegmentSchema = z.object({\n id: z.string(),\n t_start: z.number(),\n t_end: z.number(),\n status: z.enum(['ok', 'failed']),\n failure_reason: z.string().optional(),\n failure_screenshots: z.array(z.string()).default([]),\n warnings: z.array(z.string()).optional(),\n trace_path: z.string().optional(),\n});\n\nexport const slicePlanSchema = z.object({\n recording_path: z.string(),\n recording_started_at: z.string(),\n segments: z.array(sliceSegmentSchema),\n});\n\nexport type SlicePlan = z.infer<typeof slicePlanSchema>;\n\nexport async function readSlicePlan(path: string): Promise<SlicePlan> {\n const raw = await readFile(path, 'utf8');\n return slicePlanSchema.parse(JSON.parse(raw));\n}\n\nexport interface SliceSegmentInput {\n id: string;\n videoDir: string;\n workDir: string;\n normalizedMasterPath: string;\n slicePlan: SlicePlan;\n fps: number;\n width: number;\n height: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport interface SegmentVideoSource {\n segment_id: string;\n source: 'rerun' | 'master_slice';\n path: string;\n duration_hint: number;\n}\n\nexport async function prepareSegmentVideo(input: SliceSegmentInput): Promise<SegmentVideoSource> {\n const q = resolveQuality(input.quality ?? 'standard');\n const rerunWebm = join(input.videoDir, `${input.id}.webm`);\n const rerunMeta = join(input.videoDir, `${input.id}.rerun.json`);\n if ((await fileExists(rerunWebm)) && (await fileExists(rerunMeta))) {\n const out = join(input.workDir, `${input.id}.mp4`);\n await normalizeVideo({\n inputPath: rerunWebm,\n outputPath: out,\n fps: input.fps,\n width: input.width,\n height: input.height,\n quality: input.quality,\n threads: input.threads,\n });\n return {\n segment_id: input.id,\n source: 'rerun',\n path: out,\n duration_hint: 0,\n };\n }\n\n const slice = input.slicePlan.segments.find((s) => s.id === input.id);\n if (!slice) {\n throw new Error(\n `slice_plan.json has no entry for segment \"${input.id}\". Re-run the record stage.`,\n );\n }\n\n const out = join(input.workDir, `${input.id}.mp4`);\n const duration = slice.t_end - slice.t_start;\n await runFfmpeg({\n args: [\n '-y',\n '-ss',\n slice.t_start.toFixed(3),\n '-i',\n input.normalizedMasterPath,\n '-t',\n duration.toFixed(3),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(input.fps),\n '-g',\n String(input.fps),\n '-an',\n out,\n ],\n threads: input.threads,\n hintContext: { width: input.width, height: input.height },\n });\n return {\n segment_id: input.id,\n source: 'master_slice',\n path: out,\n duration_hint: duration,\n };\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport type { Transition } from '../manifest/schema.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface SegmentMuxOptions {\n videoPath: string;\n audioPath: string;\n outputPath: string;\n fps: number;\n width: number;\n height: number;\n transition: Transition;\n quality?: QualityPreset;\n threads?: number;\n}\n\nconst FADE_IN_DURATION_S = 0.5;\nconst FADE_OUT_DURATION_S = 0.5;\n\nexport async function muxSegment(opts: SegmentMuxOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const videoFilters: string[] = [];\n if (opts.transition === 'fade_in') {\n videoFilters.push(`fade=t=in:st=0:d=${FADE_IN_DURATION_S}`);\n } else if (opts.transition === 'fade_out') {\n videoFilters.push(`fade=t=out:st=0:d=${FADE_OUT_DURATION_S}`);\n }\n\n const args: string[] = ['-y', '-i', opts.videoPath, '-i', opts.audioPath];\n if (videoFilters.length > 0) {\n args.push('-vf', videoFilters.join(','));\n }\n args.push(\n '-map',\n '0:v:0',\n '-map',\n '1:a:0',\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n '-shortest',\n opts.outputPath,\n );\n await runFfmpeg({\n args,\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n","import { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\n\nexport interface ConcatOptions {\n segmentPaths: string[];\n workDir: string;\n outputPath: string;\n}\n\nexport async function concatSegments(opts: ConcatOptions): Promise<void> {\n const listPath = join(opts.workDir, 'concat_list.txt');\n const body = opts.segmentPaths\n .map((p) => `file '${escapeForConcat(p)}'`)\n .join('\\n') + '\\n';\n await writeFile(listPath, body, 'utf8');\n\n await runFfmpeg({\n args: [\n '-y',\n '-f',\n 'concat',\n '-safe',\n '0',\n '-i',\n listPath,\n '-c',\n 'copy',\n opts.outputPath,\n ],\n });\n}\n\nfunction escapeForConcat(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/'/g, \"'\\\\''\");\n}\n","import { stat } from 'node:fs/promises';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface CardOptions {\n outputPath: string;\n width: number;\n height: number;\n fps: number;\n durationSeconds: number;\n text: string;\n textColor: string;\n backgroundColor: string;\n fontPath?: string;\n fontSize: number;\n logoPath?: string;\n logoPosition?: 'top_left' | 'top_center' | 'top_right';\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function renderCard(opts: CardOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const fontDirective = opts.fontPath\n ? `fontfile=${escapeFilterPath(opts.fontPath)}:`\n : '';\n const escapedText = escapeFilterText(opts.text);\n const drawText =\n `drawtext=${fontDirective}` +\n `text=${escapedText}:` +\n `fontsize=${opts.fontSize}:` +\n `fontcolor=${ffmpegColor(opts.textColor)}:` +\n `x=(w-text_w)/2:` +\n `y=(h-text_h)/2`;\n\n const args: string[] = [\n '-y',\n '-f',\n 'lavfi',\n '-i',\n `color=c=${ffmpegColor(opts.backgroundColor)}:s=${opts.width}x${opts.height}:r=${opts.fps}:d=${opts.durationSeconds}`,\n '-f',\n 'lavfi',\n '-i',\n `anullsrc=channel_layout=stereo:sample_rate=44100`,\n ];\n\n if (opts.logoPath) {\n args.push('-i', opts.logoPath);\n const overlayXY = logoOverlayPosition(opts.logoPosition ?? 'top_center');\n args.push(\n '-filter_complex',\n `[0:v]${drawText}[bg];[bg][2:v]overlay=${overlayXY}[v]`,\n '-map',\n '[v]',\n );\n } else {\n args.push('-vf', drawText, '-map', '0:v');\n }\n\n args.push(\n '-map',\n '1:a',\n '-t',\n String(opts.durationSeconds),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n opts.outputPath,\n );\n\n await runFfmpeg({\n args,\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n\nexport interface BackgroundMusicOptions {\n inputPath: string;\n outputPath: string;\n musicPath: string;\n volumeDb: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function applyBackgroundMusic(opts: BackgroundMusicOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const volumeFactor = Math.pow(10, opts.volumeDb / 20);\n const filterComplex =\n `[1:a]volume=${volumeFactor.toFixed(4)},aloop=loop=-1:size=2e9[bg];` +\n `[0:a][bg]amix=inputs=2:duration=first:dropout_transition=0:normalize=0[a]`;\n await runFfmpeg({\n args: [\n '-y',\n '-i',\n opts.inputPath,\n '-i',\n opts.musicPath,\n '-filter_complex',\n filterComplex,\n '-map',\n '0:v',\n '-map',\n '[a]',\n '-c:v',\n 'copy',\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n '-shortest',\n opts.outputPath,\n ],\n threads: opts.threads,\n });\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction escapeFilterText(text: string): string {\n return text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/:/g, '\\\\:')\n .replace(/,/g, '\\\\,');\n}\n\nfunction escapeFilterPath(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/:/g, '\\\\\\\\:');\n}\n\nfunction ffmpegColor(value: string): string {\n if (value.startsWith('#')) {\n return `0x${value.slice(1)}`;\n }\n return value;\n}\n\nfunction logoOverlayPosition(pos: 'top_left' | 'top_center' | 'top_right'): string {\n switch (pos) {\n case 'top_left':\n return 'x=24:y=24';\n case 'top_right':\n return 'x=W-w-24:y=24';\n case 'top_center':\n default:\n return 'x=(W-w)/2:y=24';\n }\n}\n","import { writeFile } from 'node:fs/promises';\nimport { loadAlignment, type CharacterAlignment } from '../manifest/alignment.js';\nimport type { Manifest } from '../manifest/schema.js';\nimport type { SlicePlan } from './slice.js';\nimport { logger } from '../util/logger.js';\n\nconst MAX_CUE_CHARS = 42;\nconst MAX_CUE_SECONDS = 3;\n\nexport interface Cue {\n index: number;\n startSec: number;\n endSec: number;\n text: string;\n}\n\nexport interface EmitCaptionsOptions {\n manifest: Manifest;\n alignmentDir: string;\n slicePlan: SlicePlan;\n /** Output path stem (without extension). `.srt` and/or `.vtt` are appended. */\n outputBase: string;\n format: 'srt' | 'vtt' | 'both';\n /**\n * Seconds added to every cue to account for any pre-roll (e.g. the title card).\n * Slice_plan timestamps are in master.webm time; the final mp4 has title card\n * + outro card glued on the ends. The caller passes the title card duration here.\n */\n titleCardOffset?: number;\n}\n\nexport async function emitCaptions(opts: EmitCaptionsOptions): Promise<string[]> {\n const cues: Cue[] = [];\n const titleOffset = opts.titleCardOffset ?? 0;\n let cueIndex = 1;\n\n for (const seg of opts.manifest.segments) {\n const slice = opts.slicePlan.segments.find((s) => s.id === seg.id);\n if (slice && slice.status !== 'ok') continue;\n\n // The manifest is rewritten by the voiceover stage so segment.start/end\n // reflect the audio-concat timeline used by mux. Final-mp4 time =\n // title_card_duration + manifest segment.start. The slice_plan's t_start\n // lives in master.webm coordinates (which include the pre-segment recording\n // offset) and is wrong for the final mp4 — don't use it here.\n const segmentStartInFinalMp4 = titleOffset + seg.start;\n const segmentEndInFinalMp4 = titleOffset + seg.end;\n\n const alignmentPath = `${opts.alignmentDir}/${seg.id}.alignment.json`;\n const alignment = await loadAlignment(alignmentPath);\n if (!alignment) {\n logger.warn(`captions: no alignment for segment ${seg.id} — falling back to whole-segment cue`);\n cues.push({\n index: cueIndex++,\n startSec: segmentStartInFinalMp4,\n endSec: segmentEndInFinalMp4,\n text: collapse(seg.vo_line),\n });\n continue;\n }\n\n // Per-segment alignment now uses segment-mp3 time (0 = segment mp3 start,\n // including any leading silence before speech). Adding segmentStartInFinalMp4\n // gives the absolute time in the final mp4.\n const segCues = chunkAlignmentToCues(alignment, segmentStartInFinalMp4);\n for (const c of segCues) {\n cues.push({ ...c, index: cueIndex++ });\n }\n }\n\n const written: string[] = [];\n if (opts.format === 'srt' || opts.format === 'both') {\n const path = `${opts.outputBase}.srt`;\n await writeFile(path, renderSrt(cues), 'utf8');\n written.push(path);\n }\n if (opts.format === 'vtt' || opts.format === 'both') {\n const path = `${opts.outputBase}.vtt`;\n await writeFile(path, renderVtt(cues), 'utf8');\n written.push(path);\n }\n return written;\n}\n\nexport function chunkAlignmentToCues(\n alignment: CharacterAlignment,\n segmentStartSec: number,\n): Cue[] {\n const cues: Cue[] = [];\n const chars = alignment.characters;\n const starts = alignment.character_start_times_seconds;\n const ends = alignment.character_end_times_seconds;\n if (chars.length === 0) return cues;\n\n let cueStart = starts[0]!;\n let cueChars: string[] = [];\n let lastBoundaryIdx = -1;\n let i = 0;\n\n const pushCue = (endIdx: number): void => {\n const text = cueChars.join('').replace(/\\s+/g, ' ').trim();\n if (text.length === 0) return;\n cues.push({\n index: 0, // assigned by caller\n startSec: segmentStartSec + cueStart,\n endSec: segmentStartSec + ends[endIdx]!,\n text,\n });\n };\n\n while (i < chars.length) {\n cueChars.push(chars[i]!);\n\n const cuTextLen = cueChars.join('').length;\n const cueDuration = ends[i]! - cueStart;\n const atWordBoundary = /\\s/.test(chars[i]!) || /[.,;!?—]/.test(chars[i]!);\n if (atWordBoundary) lastBoundaryIdx = i;\n\n const overChars = cuTextLen >= MAX_CUE_CHARS;\n const overTime = cueDuration >= MAX_CUE_SECONDS;\n\n if ((overChars || overTime) && lastBoundaryIdx > -1) {\n // Split at the last word boundary; keep everything after for the next cue\n const cutAt = lastBoundaryIdx;\n cueChars = cueChars.slice(0, cutAt - i + cueChars.length);\n pushCue(cutAt);\n // Reset for next cue\n cueStart = starts[cutAt + 1] ?? starts[i]!;\n cueChars = [];\n // continue from cutAt + 1\n i = cutAt + 1;\n lastBoundaryIdx = -1;\n continue;\n }\n\n i++;\n }\n\n // Final cue\n if (cueChars.length > 0) {\n pushCue(chars.length - 1);\n }\n\n return cues;\n}\n\nfunction renderSrt(cues: Cue[]): string {\n return cues\n .map((c) => `${c.index}\\n${fmtSrt(c.startSec)} --> ${fmtSrt(c.endSec)}\\n${c.text}\\n`)\n .join('\\n');\n}\n\nfunction renderVtt(cues: Cue[]): string {\n return ['WEBVTT', '', ...cues.map((c) => `${fmtVtt(c.startSec)} --> ${fmtVtt(c.endSec)}\\n${c.text}\\n`)].join(\n '\\n',\n );\n}\n\nfunction fmtSrt(sec: number): string {\n const h = Math.floor(sec / 3600);\n const m = Math.floor((sec % 3600) / 60);\n const s = Math.floor(sec % 60);\n const ms = Math.round((sec - Math.floor(sec)) * 1000);\n return `${pad(h, 2)}:${pad(m, 2)}:${pad(s, 2)},${pad(ms, 3)}`;\n}\n\nfunction fmtVtt(sec: number): string {\n const h = Math.floor(sec / 3600);\n const m = Math.floor((sec % 3600) / 60);\n const s = Math.floor(sec % 60);\n const ms = Math.round((sec - Math.floor(sec)) * 1000);\n return `${pad(h, 2)}:${pad(m, 2)}:${pad(s, 2)}.${pad(ms, 3)}`;\n}\n\nfunction pad(n: number, w: number): string {\n return n.toString().padStart(w, '0');\n}\n\nfunction collapse(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n}\n","import type { ShowrunnerConfig } from '../config/schema.js';\n\nexport const STAGE_NAMES = ['comprehension', 'script', 'voiceover', 'record', 'mux'] as const;\nexport type StageName = (typeof STAGE_NAMES)[number];\n\nexport interface PipelineOverrides {\n /** Force headed recording regardless of `recording.headless` in config. */\n headed?: boolean;\n}\n\nexport interface PipelineContext {\n config: ShowrunnerConfig;\n configPath: string;\n configDir: string;\n runId: string;\n interactive: boolean;\n forced: Set<StageName>;\n overrides: PipelineOverrides;\n}\n\nexport interface StageResult {\n stage: StageName;\n skipped: boolean;\n reason?: string;\n durationMs: number;\n artifacts?: Record<string, string>;\n warnings?: string[];\n meta?: Record<string, unknown>;\n halt?: boolean;\n}\n\nexport interface PipelineOptions {\n stages?: StageName[];\n force?: StageName[];\n interactive?: boolean;\n resume?: boolean;\n dryRun?: boolean;\n json?: boolean;\n overrides?: PipelineOverrides;\n}\n\nexport interface PipelineResult {\n runId: string;\n outputPath: string;\n stages: StageResult[];\n buildManifestPath: string;\n}\n\nexport interface Stage {\n name: StageName;\n run(ctx: PipelineContext): Promise<StageResult>;\n}\n"],"mappings":"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","names":["mkdir","writeFile","dirname","resolve","resolve","resolve","stat","writeFile","resolve","readFile","z","readFile","readFile","dirname","z","readFile","dirname","mkdir","writeFile","dirname","mkdir","readFile","writeFile","dirname","z","z","DEFAULT_MAX_TOKENS","DEFAULT_MAX_TOKENS","mkdir","readFile","stat","writeFile","zodToJsonSchema","stat","isAbsolute","resolve","isAbsolute","resolve","stat","zodToJsonSchema","mkdir","writeFile","fileExists","readFile","stat","resolve","isAbsolute","resolve","isAbsolute","resolve","resolve","fileExists","writeFile","stat","mkdir","stat","writeFile","dirname","resolve","mkdir","join","resolve","chromium","firefox","webkit","readFile","readFile","isAbsolute","resolve","pathToFileURL","isAbsolute","resolve","pathToFileURL","readFile","mkdir","dirname","join","state","join","mkdir","dirname","browserMap","chromium","firefox","webkit","resolve","join","mkdir","resolve","fileExists","mkdir","dirname","writeFile","stat","mkdir","stat","writeFile","join","resolve","spawn","readFile","writeFile","join","readFile","writeFile","join","sleep","OpenAI","OpenAI","isAbsolute","resolve","pathToFileURL","isAbsolute","resolve","pathToFileURL","configToSpec","resolve","mkdir","fileExists","writeFile","join","stat","mkdir","rename","dirname","isAbsolute","join","resolve","readFile","stat","join","z","z","readFile","join","fileExists","out","stat","writeFile","join","join","writeFile","stat","fileExists","stat","writeFile","writeFile","resolve","fileExists","join","mkdir","dirname","rename","isAbsolute","resolve","dirname","mkdir","writeFile"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts","../src/pipeline/run.ts","../src/util/logger.ts","../src/util/runId.ts","../src/stages/comprehension.ts","../src/stages/script.ts","../src/productModel/io.ts","../src/productModel/schema.ts","../src/manifest/io.ts","../src/manifest/schema.ts","../src/manifest/playwrightCodegen.ts","../src/manifest/voScript.ts","../src/providers/llm/withRetry.ts","../src/providers/llm/types.ts","../src/scriptGen/prompts.ts","../src/scriptGen/validateSelectors.ts","../src/scriptGen/generate.ts","../src/scriptGen/domPreflight.ts","../src/recording/selectorHeuristic.ts","../src/providers/llm/anthropic.ts","../src/providers/llm/openai.ts","../src/providers/llm/agentBridge.ts","../src/recording/lifecycle.ts","../src/providers/llm/custom.ts","../src/providers/llm/factory.ts","../src/providers/llm/resolveFromContext.ts","../src/stages/record.ts","../src/recording/record.ts","../src/manifest/alignment.ts","../src/recording/auth.ts","../src/recording/actions.ts","../src/recording/cursorOverlay.ts","../src/recording/selector.ts","../src/util/resources.ts","../src/stages/voiceover.ts","../src/voiceover/ffmpeg.ts","../src/voiceover/fullVo.ts","../src/providers/tts/types.ts","../src/voiceover/elevenlabs.ts","../src/providers/tts/elevenlabs.ts","../src/providers/tts/openai.ts","../src/providers/tts/custom.ts","../src/providers/tts/factory.ts","../src/providers/tts/resolveFromContext.ts","../src/stages/mux.ts","../src/mux/quality.ts","../src/mux/normalize.ts","../src/mux/slice.ts","../src/mux/segmentMux.ts","../src/mux/concat.ts","../src/mux/branding.ts","../src/mux/captions.ts","../src/pipeline/types.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { resolve, dirname, isAbsolute } from 'node:path';\nimport yaml from 'js-yaml';\nimport { z } from 'zod';\nimport { showrunnerConfigSchema, type ShowrunnerConfig } from './schema.js';\n\nexport class ConfigError extends Error {\n override readonly name = 'ConfigError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n readonly configPath?: string,\n ) {\n super(message);\n }\n}\n\nexport interface LoadedConfig {\n config: ShowrunnerConfig;\n configPath: string;\n configDir: string;\n}\n\nexport async function loadConfig(configPath: string): Promise<LoadedConfig> {\n const absPath = isAbsolute(configPath) ? configPath : resolve(process.cwd(), configPath);\n let raw: string;\n try {\n raw = await readFile(absPath, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ConfigError(`Failed to read config at ${absPath}: ${cause}`, undefined, absPath);\n }\n\n let parsed: unknown;\n try {\n parsed = yaml.load(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ConfigError(`Invalid YAML in ${absPath}: ${cause}`, undefined, absPath);\n }\n\n return validateConfig(parsed, absPath);\n}\n\nexport function validateConfig(input: unknown, configPath?: string): LoadedConfig {\n const normalized = normalizeLegacyConfig(input);\n const result = showrunnerConfigSchema.safeParse(normalized);\n if (!result.success) {\n throw new ConfigError(\n formatZodError(result.error),\n result.error.issues,\n configPath,\n );\n }\n return {\n config: result.data,\n configPath: configPath ?? '',\n configDir: configPath ? dirname(configPath) : process.cwd(),\n };\n}\n\nconst ELEVENLABS_FIELD_KEYS = [\n 'voice_id',\n 'model',\n 'stability',\n 'similarity_boost',\n 'style',\n 'use_speaker_boost',\n 'speed',\n 'api_key_env',\n 'endpoint',\n] as const;\n\n/**\n * Reshape pre-v1.1 configs into the discriminated-union shape introduced in B3.\n *\n * Pre-v1.1:\n * voiceover:\n * provider: elevenlabs # string\n * voice_id: ... # flat ElevenLabs fields\n * api_key_env: ...\n *\n * Post-v1.1:\n * voiceover:\n * provider:\n * name: elevenlabs\n * voice_id: ...\n * api_key_env: ...\n *\n * Triggered when `voiceover.provider` is missing (defaulted to elevenlabs) OR\n * a string equal to 'elevenlabs'. Modern configs whose `voiceover.provider`\n * is already an object pass through untouched.\n */\nexport function normalizeLegacyConfig(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input;\n const cfg = { ...(input as Record<string, unknown>) };\n const vo = cfg.voiceover as Record<string, unknown> | undefined;\n if (!vo) return cfg;\n\n const provider = vo.provider;\n const isLegacy =\n provider === undefined ||\n provider === 'elevenlabs' ||\n (typeof provider === 'string' && provider === 'elevenlabs');\n if (!isLegacy) return cfg;\n\n const elevenSpec: Record<string, unknown> = { name: 'elevenlabs' };\n for (const key of ELEVENLABS_FIELD_KEYS) {\n if (vo[key] !== undefined) elevenSpec[key] = vo[key];\n }\n\n const cleaned: Record<string, unknown> = { ...vo };\n for (const key of ELEVENLABS_FIELD_KEYS) delete cleaned[key];\n cleaned.provider = elevenSpec;\n\n cfg.voiceover = cleaned;\n return cfg;\n}\n\nfunction formatZodError(error: z.ZodError): string {\n const lines = error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';\n return ` ${path}: ${issue.message}`;\n });\n return `Config validation failed:\\n${lines.join('\\n')}`;\n}\n","import { z } from 'zod';\n\nconst projectSchema = z.object({\n name: z.string().min(1),\n product_model: z.string().optional(),\n /**\n * Path to the product's codebase, resolved relative to demo.yaml's directory.\n * Used by `understand --agent` to anchor the agent's exploration.\n * Defaults to `..` because the canonical scaffold layout places the\n * Showrunner project inside or beside the product directory.\n */\n codebase_root: z.string().optional(),\n});\n\nconst comprehensionSourceSchema = z.object({\n type: z.enum(['prd', 'readme', 'codebase', 'openapi', 'changelog', 'custom']),\n path: z.string(),\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n});\n\nconst comprehensionSchema = z.object({\n mode: z.enum(['documents', 'interactive']).default('documents'),\n sources: z.array(comprehensionSourceSchema).default([]),\n});\n\nconst scriptSchema = z.object({\n style: z.string().default('matter-of-fact'),\n duration_target_seconds: z.number().int().positive().default(90),\n highlight_features: z.array(z.string()).default([]),\n vo_review_gate: z.boolean().default(false),\n});\n\nconst viewportSchema = z.object({\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nconst stateSchema = z\n .object({\n seed_script: z.string().optional(),\n reset_script: z.string().optional(),\n teardown_script: z.string().optional(),\n })\n .default({});\n\nconst authSetupScriptSchema = z.object({\n type: z.literal('setup_script'),\n path: z.string(),\n});\n\nconst authSessionSchema = z.object({\n type: z.literal('session'),\n cookies_file: z.string(),\n local_storage_file: z.string().optional(),\n});\n\nconst authFormFieldSchema = z.object({\n selector: z.string(),\n env: z.string(),\n});\n\nconst authFormSchema = z.object({\n type: z.literal('form'),\n login_url: z.string(),\n fields: z.object({\n email: authFormFieldSchema,\n password: authFormFieldSchema,\n }),\n submit_selector: z.string(),\n success_url_pattern: z.string(),\n timeout_ms: z.number().int().positive().default(5000),\n});\n\nconst authSchema = z.discriminatedUnion('type', [\n authSetupScriptSchema,\n authSessionSchema,\n authFormSchema,\n]);\n\nconst recordingSchema = z.object({\n target_url: z.string().url(),\n viewport: viewportSchema.default({ width: 1920, height: 1080 }),\n browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),\n headless: z.boolean().default(false),\n output_dir: z.string().default('./segments/video'),\n trace_dir: z.string().default('./segments/traces'),\n cursor_highlight: z.boolean().default(true),\n cursor_min_motion_ms: z.number().int().nonnegative().default(180),\n cursor_max_motion_ms: z.number().int().nonnegative().default(700),\n cursor_post_arrival_ms: z.number().int().nonnegative().default(100),\n cursor_speed_factor: z.number().positive().default(1.0),\n cursor_chain_mode: z.enum(['strict', 'smart']).default('strict'),\n segment_buffer_ms: z.number().int().nonnegative().default(200),\n preflight: z.boolean().default(true),\n state: stateSchema,\n auth: authSchema.optional(),\n});\n\nconst postProcessSchema = z\n .object({\n debreath: z.boolean().default(true),\n })\n .default({ debreath: true });\n\nconst pausePlacementSchema = z\n .object({\n strategy: z.enum(['action_boundaries', 'trailing']).default('trailing'),\n min_silence_ms: z.number().int().nonnegative().default(250),\n snap_window_ms: z.number().int().nonnegative().default(1200),\n })\n .default({});\n\nconst elevenLabsTTSSchema = z.object({\n name: z.literal('elevenlabs'),\n voice_id: z.string().min(1),\n model: z.string().default('eleven_multilingual_v2'),\n api_key_env: z.string().default('ELEVENLABS_API_KEY'),\n endpoint: z.enum(['with_timestamps', 'basic']).default('with_timestamps'),\n stability: z.number().min(0).max(1).default(0.55),\n similarity_boost: z.number().min(0).max(1).default(0.75),\n style: z.number().min(0).max(1).default(0.0),\n use_speaker_boost: z.boolean().default(true),\n speed: z.number().min(0.85).max(1.15).default(1.0),\n});\n\nconst openaiTTSSchema = z.object({\n name: z.literal('openai'),\n voice: z.string().default('alloy'),\n model: z.string().default('tts-1-hd'),\n api_key_env: z.string().default('OPENAI_API_KEY'),\n base_url: z.string().optional(),\n});\n\nconst customTTSSchema = z.object({\n name: z.literal('custom'),\n module_path: z.string(),\n options: z.record(z.unknown()).optional(),\n});\n\nconst ttsProviderSchema = z.discriminatedUnion('name', [\n elevenLabsTTSSchema,\n openaiTTSSchema,\n customTTSSchema,\n]);\n\nconst voiceoverSchema = z.object({\n provider: ttsProviderSchema,\n alignment_strategy: z.enum(['required', 'best_effort']).default('required'),\n output_dir: z.string().default('./segments/audio'),\n alignment_dir: z.string().default('./segments/alignment'),\n duration_drift_threshold_pct: z.number().nonnegative().default(15),\n drift_strategy: z.enum(['adjust_timing', 'resynthesize']).default('adjust_timing'),\n tail_padding_ms: z.number().int().nonnegative().default(500),\n post_process: postProcessSchema,\n pause_placement: pausePlacementSchema,\n});\n\nconst anthropicLLMSchema = z.object({\n provider: z.literal('anthropic'),\n model: z.string().default('claude-opus-4-7'),\n api_key_env: z.string().default('ANTHROPIC_API_KEY'),\n max_tokens: z.number().int().positive().optional(),\n});\n\nconst openaiLLMSchema = z.object({\n provider: z.literal('openai'),\n model: z.string().default('gpt-4o'),\n api_key_env: z.string().default('OPENAI_API_KEY'),\n max_tokens: z.number().int().positive().optional(),\n base_url: z.string().optional(),\n});\n\nconst agentBridgeLLMSchema = z.object({\n provider: z.literal('agent_bridge'),\n bridge: z.object({\n mode: z.enum(['spawn', 'file_poll']).default('spawn'),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n request_dir: z.string().optional(),\n poll_interval_ms: z.number().int().positive().optional(),\n timeout_ms: z.number().int().positive().optional(),\n }),\n});\n\nconst customLLMSchema = z.object({\n provider: z.literal('custom'),\n module_path: z.string(),\n options: z.record(z.unknown()).optional(),\n});\n\nconst llmProviderConfigSchema = z.discriminatedUnion('provider', [\n anthropicLLMSchema,\n openaiLLMSchema,\n agentBridgeLLMSchema,\n customLLMSchema,\n]);\n\nconst llmSchema = z\n .object({\n default: llmProviderConfigSchema.default({\n provider: 'anthropic',\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n }),\n overrides: z\n .object({\n comprehension: llmProviderConfigSchema.optional(),\n script: llmProviderConfigSchema.optional(),\n instrument: llmProviderConfigSchema.optional(),\n })\n .optional(),\n })\n .default({\n default: {\n provider: 'anthropic',\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n },\n });\n\nconst titleCardSchema = z.object({\n enabled: z.boolean().default(true),\n text: z.string(),\n duration_seconds: z.number().positive().default(2),\n font: z.string().optional(),\n font_size: z.number().int().positive().default(48),\n text_color: z.string().default('#FFFFFF'),\n background_color: z.string().default('#0F172A'),\n logo: z.string().optional(),\n logo_position: z.enum(['top_left', 'top_center', 'top_right']).default('top_center'),\n});\n\nconst outroCardSchema = z.object({\n enabled: z.boolean().default(true),\n text: z.string(),\n duration_seconds: z.number().positive().default(2),\n});\n\nconst brandingSchema = z\n .object({\n title_card: titleCardSchema.optional(),\n outro_card: outroCardSchema.optional(),\n })\n .default({});\n\nconst backgroundMusicSchema = z.object({\n path: z.string(),\n volume_db: z.number().default(-22),\n});\n\nconst captionsSchema = z\n .object({\n enabled: z.boolean().default(false),\n format: z.enum(['srt', 'vtt', 'both']).default('srt'),\n })\n .default({});\n\nconst outputSchema = z.object({\n format: z.literal('mp4').default('mp4'),\n resolution: z\n .string()\n .regex(/^\\d+x\\d+$/, 'Expected WIDTHxHEIGHT (e.g. 1920x1080)')\n .default('1920x1080'),\n fps: z.number().int().positive().default(30),\n codec_video: z.string().default('h264'),\n codec_audio: z.string().default('aac'),\n quality: z.enum(['draft', 'standard', 'high']).default('standard'),\n branding: brandingSchema,\n background_music: backgroundMusicSchema.optional(),\n captions: captionsSchema,\n output_path: z.string().default('./output/demo_final.mp4'),\n});\n\nexport const showrunnerConfigSchema = z.object({\n project: projectSchema,\n comprehension: comprehensionSchema.default({ mode: 'documents', sources: [] }),\n script: scriptSchema.default({}),\n recording: recordingSchema,\n voiceover: voiceoverSchema,\n llm: llmSchema,\n output: outputSchema.default({}),\n});\n\nexport type ShowrunnerConfig = z.infer<typeof showrunnerConfigSchema>;\nexport type ComprehensionConfig = z.infer<typeof comprehensionSchema>;\nexport type ScriptConfig = z.infer<typeof scriptSchema>;\nexport type RecordingConfig = z.infer<typeof recordingSchema>;\nexport type VoiceoverConfig = z.infer<typeof voiceoverSchema>;\nexport type OutputConfig = z.infer<typeof outputSchema>;\nexport type AuthConfig = z.infer<typeof authSchema>;\nexport type TTSProviderConfig = z.infer<typeof ttsProviderSchema>;\nexport type ElevenLabsTTSConfig = z.infer<typeof elevenLabsTTSSchema>;\nexport type OpenAITTSConfig = z.infer<typeof openaiTTSSchema>;\nexport type LLMConfig = z.infer<typeof llmSchema>;\nexport type LLMProviderConfig = z.infer<typeof llmProviderConfigSchema>;\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport type { LoadedConfig } from '../config/loader.js';\nimport { logger } from '../util/logger.js';\nimport { generateRunId } from '../util/runId.js';\nimport { comprehensionStage } from '../stages/comprehension.js';\nimport { scriptStage } from '../stages/script.js';\nimport { recordStage } from '../stages/record.js';\nimport { voiceoverStage } from '../stages/voiceover.js';\nimport { muxStage } from '../stages/mux.js';\nimport {\n STAGE_NAMES,\n type PipelineContext,\n type PipelineOptions,\n type PipelineResult,\n type Stage,\n type StageName,\n type StageResult,\n} from './types.js';\n\nexport class PipelineStageError extends Error {\n override readonly name = 'PipelineStageError';\n constructor(\n readonly stage: StageName,\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n\nconst STAGES_BY_NAME: Record<StageName, Stage> = {\n comprehension: comprehensionStage,\n script: scriptStage,\n record: recordStage,\n voiceover: voiceoverStage,\n mux: muxStage,\n};\n\nexport async function run(\n loaded: LoadedConfig,\n options: PipelineOptions = {},\n): Promise<PipelineResult> {\n const runId = generateRunId();\n const interactive = options.interactive ?? true;\n const forced = new Set<StageName>(options.force ?? []);\n const enabled = resolveEnabledStages(options.stages);\n\n const ctx: PipelineContext = {\n config: loaded.config,\n configPath: loaded.configPath,\n configDir: loaded.configDir,\n runId,\n interactive,\n forced,\n overrides: options.overrides ?? {},\n };\n\n logger.event({ stage: 'pipeline', status: 'start', runId, stages: [...enabled] });\n\n const results: StageResult[] = [];\n for (const name of STAGE_NAMES) {\n if (!enabled.has(name)) {\n logger.event({ stage: name, status: 'disabled' });\n continue;\n }\n if (options.dryRun && (name === 'record' || name === 'voiceover' || name === 'mux')) {\n logger.event({ stage: name, status: 'dry-run' });\n results.push({\n stage: name,\n skipped: true,\n reason: 'dry-run',\n durationMs: 0,\n });\n continue;\n }\n const stage = STAGES_BY_NAME[name];\n let result: StageResult;\n try {\n result = await stage.run(ctx);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logger.event({ stage: name, status: 'failed', error: message });\n throw new PipelineStageError(name, message, err);\n }\n results.push(result);\n logger.event({\n stage: name,\n status: result.skipped ? 'skipped' : 'complete',\n durationMs: result.durationMs,\n reason: result.reason,\n });\n if (result.halt) {\n logger.event({\n stage: 'pipeline',\n status: 'halted',\n runId,\n by: name,\n reason: result.reason,\n });\n break;\n }\n }\n\n const outputPath = resolve(ctx.configDir, ctx.config.output.output_path);\n const buildManifestPath = resolve(dirname(outputPath), 'build_manifest.json');\n await writeBuildManifest(buildManifestPath, {\n runId,\n outputPath,\n results,\n config: loaded,\n });\n\n logger.event({ stage: 'pipeline', status: 'done', runId, buildManifest: buildManifestPath });\n\n return {\n runId,\n outputPath,\n stages: results,\n buildManifestPath,\n };\n}\n\nfunction resolveEnabledStages(filter: StageName[] | undefined): Set<StageName> {\n if (!filter || filter.length === 0) return new Set(STAGE_NAMES);\n return new Set(filter);\n}\n\ninterface BuildManifestPayload {\n runId: string;\n outputPath: string;\n results: StageResult[];\n config: LoadedConfig;\n}\n\nasync function writeBuildManifest(path: string, payload: BuildManifestPayload): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const stages: Record<string, unknown> = {};\n for (const r of payload.results) {\n stages[r.stage] = {\n skipped: r.skipped,\n reason: r.reason,\n duration_ms: r.durationMs,\n warnings: r.warnings,\n };\n }\n const manifest = {\n run_id: payload.runId,\n generated_at: new Date().toISOString(),\n output_file: payload.outputPath,\n inputs: {\n config: payload.config.configPath,\n },\n stages,\n warnings: payload.results.flatMap((r) => r.warnings ?? []),\n };\n await writeFile(path, JSON.stringify(manifest, null, 2) + '\\n', 'utf8');\n}\n","type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\ninterface LoggerState {\n level: LogLevel;\n json: boolean;\n}\n\nconst state: LoggerState = {\n level: (process.env['SHOWRUNNER_LOG_LEVEL'] as LogLevel) ?? 'info',\n json: false,\n};\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[state.level];\n}\n\nfunction emit(level: LogLevel, message: string, fields?: Record<string, unknown>): void {\n if (!shouldLog(level)) return;\n if (state.json) {\n const payload = { level, msg: message, ts: new Date().toISOString(), ...fields };\n process.stdout.write(JSON.stringify(payload) + '\\n');\n } else {\n const prefix = `[showrunner] `;\n const suffix = fields ? ' ' + JSON.stringify(fields) : '';\n const stream = level === 'error' || level === 'warn' ? process.stderr : process.stdout;\n stream.write(prefix + message + suffix + '\\n');\n }\n}\n\nexport const logger = {\n setLevel(level: LogLevel): void {\n state.level = level;\n },\n setJson(json: boolean): void {\n state.json = json;\n },\n isJson(): boolean {\n return state.json;\n },\n debug(message: string, fields?: Record<string, unknown>): void {\n emit('debug', message, fields);\n },\n info(message: string, fields?: Record<string, unknown>): void {\n emit('info', message, fields);\n },\n warn(message: string, fields?: Record<string, unknown>): void {\n emit('warn', message, fields);\n },\n error(message: string, fields?: Record<string, unknown>): void {\n emit('error', message, fields);\n },\n event(payload: Record<string, unknown>): void {\n if (state.json) {\n process.stdout.write(JSON.stringify({ ...payload, ts: new Date().toISOString() }) + '\\n');\n } else if (shouldLog('info')) {\n const { stage, status, ...rest } = payload as { stage?: string; status?: string } & Record<\n string,\n unknown\n >;\n const head = `[${stage ?? '?'}/${status ?? '?'}]`;\n const tail = Object.keys(rest).length > 0 ? ' ' + JSON.stringify(rest) : '';\n process.stdout.write(head + tail + '\\n');\n }\n },\n};\n","import { randomBytes } from 'node:crypto';\n\nexport function generateRunId(date: Date = new Date()): string {\n const y = date.getUTCFullYear();\n const m = String(date.getUTCMonth() + 1).padStart(2, '0');\n const d = String(date.getUTCDate()).padStart(2, '0');\n const suffix = randomBytes(3).toString('hex');\n return `sr-${y}${m}${d}-${suffix}`;\n}\n","import { stat } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\n\nexport const comprehensionStage: Stage = {\n name: 'comprehension',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const modelPath = resolve(\n ctx.configDir,\n ctx.config.project.product_model ?? './product_model.json',\n );\n\n const exists = await fileExists(modelPath);\n const forced = ctx.forced.has('comprehension');\n\n if (exists && !forced) {\n logger.event({\n stage: 'comprehension',\n status: 'skipped',\n reason: 'product_model.json already present',\n path: modelPath,\n });\n return {\n stage: 'comprehension',\n skipped: true,\n reason: 'product_model.json already present',\n durationMs: Date.now() - start,\n artifacts: { product_model: modelPath },\n };\n }\n\n logger.event({ stage: 'comprehension', status: 'pending' });\n logger.warn('Comprehension stage is not yet implemented — placeholder run.');\n\n return {\n stage: 'comprehension',\n skipped: true,\n reason: 'not yet implemented',\n durationMs: Date.now() - start,\n warnings: ['comprehension stage is a stub'],\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { stat, writeFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readProductModel, ProductModelError } from '../productModel/io.js';\nimport { readManifest, writeManifest } from '../manifest/io.js';\nimport { writePlaywrightSpec, writePlaywrightPreviewSpec } from '../manifest/playwrightCodegen.js';\nimport { writeVoScript } from '../manifest/voScript.js';\nimport { generateManifest, ManifestGenerationError } from '../scriptGen/generate.js';\nimport { scrapeSelectorInventory, type SelectorInventoryItem } from '../scriptGen/domPreflight.js';\nimport { resolveLLMProviderForStage } from '../providers/llm/resolveFromContext.js';\n\nconst LOCK_FILENAME = '.showrunner-lock';\n\nexport const scriptStage: Stage = {\n name: 'script',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const specPath = resolve(ctx.configDir, './scripts/playwright_demo.ts');\n const previewSpecPath = resolve(ctx.configDir, './scripts/playwright_demo.spec.ts');\n const voScriptPath = resolve(ctx.configDir, './scripts/vo_script.txt');\n const lockPath = resolve(ctx.configDir, LOCK_FILENAME);\n const productModelPath = resolve(\n ctx.configDir,\n ctx.config.project.product_model ?? './product_model.json',\n );\n\n const manifestExists = await fileExists(manifestPath);\n const forced = ctx.forced.has('script');\n\n let manifest;\n if (manifestExists && !forced) {\n logger.event({\n stage: 'script',\n status: 'reusing',\n reason: 'manifest.json present',\n path: manifestPath,\n });\n manifest = await readManifest(manifestPath);\n } else {\n if (!(await fileExists(productModelPath))) {\n return {\n stage: 'script',\n skipped: true,\n reason: `product_model.json not found at ${productModelPath} — run \\`showrunner understand\\` or restore the file`,\n durationMs: Date.now() - start,\n };\n }\n\n let productModel;\n try {\n productModel = await readProductModel(productModelPath);\n } catch (err) {\n if (err instanceof ProductModelError) {\n throw new Error(`script stage: ${err.message}`);\n }\n throw err;\n }\n\n // DOM preflight — scrape the live target so the LLM can't hallucinate selectors.\n // Failure is non-fatal; degrade gracefully to LLM-only generation.\n let selectorInventory: SelectorInventoryItem[] | undefined;\n try {\n logger.event({\n stage: 'script',\n status: 'dom_preflight',\n target_url: ctx.config.recording.target_url,\n });\n selectorInventory = await scrapeSelectorInventory({\n targetUrl: ctx.config.recording.target_url,\n recording: ctx.config.recording,\n });\n logger.event({\n stage: 'script',\n status: 'dom_preflight_done',\n inventory_size: selectorInventory.length,\n });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n warnings.push(`DOM preflight failed: ${cause} — falling back to LLM-only selector generation`);\n logger.warn(`DOM preflight failed: ${cause}`);\n }\n\n logger.event({ stage: 'script', status: 'generating', source: productModelPath });\n try {\n const provider = resolveLLMProviderForStage(ctx, 'script');\n manifest = await generateManifest({\n productModel,\n scriptConfig: ctx.config.script,\n provider,\n selectorInventory,\n });\n } catch (err) {\n if (err instanceof ManifestGenerationError) {\n throw new Error(`script stage: ${err.message}`);\n }\n throw err;\n }\n await writeManifest(manifestPath, manifest);\n logger.event({\n stage: 'script',\n status: 'manifest_written',\n path: manifestPath,\n segments: manifest.segments.length,\n });\n }\n\n const codegenInputs = {\n manifest,\n recording: ctx.config.recording,\n targetUrl: ctx.config.recording.target_url,\n videoDir: resolve(ctx.configDir, ctx.config.recording.output_dir),\n traceDir: resolve(ctx.configDir, ctx.config.recording.trace_dir),\n };\n await writePlaywrightSpec(specPath, codegenInputs);\n await writePlaywrightPreviewSpec(previewSpecPath, codegenInputs);\n await writeVoScript(voScriptPath, manifest, { projectName: ctx.config.project.name });\n logger.event({ stage: 'script', status: 'spec_written', path: specPath });\n logger.event({ stage: 'script', status: 'preview_spec_written', path: previewSpecPath });\n logger.event({ stage: 'script', status: 'vo_script_written', path: voScriptPath });\n\n if (ctx.config.script.vo_review_gate && ctx.interactive) {\n await writeFile(\n lockPath,\n JSON.stringify(\n {\n run_id: ctx.runId,\n stage: 'script',\n reason: 'vo_review_gate',\n vo_script_path: voScriptPath,\n created_at: new Date().toISOString(),\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n logger.warn(\n `VO review gate engaged. Edit ${voScriptPath}, then run \\`showrunner approve-vo --config ${ctx.configPath}\\` to resume.`,\n );\n return {\n stage: 'script',\n skipped: false,\n reason: 'paused for vo_review_gate',\n durationMs: Date.now() - start,\n artifacts: {\n manifest: manifestPath,\n playwright_spec: specPath,\n playwright_preview_spec: previewSpecPath,\n vo_script: voScriptPath,\n lock: lockPath,\n },\n warnings,\n meta: { gate: 'vo_review_gate', segments: manifest.segments.length },\n halt: true,\n };\n }\n\n if (ctx.config.script.vo_review_gate && !ctx.interactive) {\n warnings.push('vo_review_gate is true in config but --no-interactive disabled it');\n }\n\n return {\n stage: 'script',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: {\n manifest: manifestPath,\n playwright_spec: specPath,\n playwright_preview_spec: previewSpecPath,\n vo_script: voScriptPath,\n },\n warnings,\n meta: { segments: manifest.segments.length },\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { productModelSchema, type ProductModel } from './schema.js';\n\nexport class ProductModelError extends Error {\n override readonly name = 'ProductModelError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n ) {\n super(message);\n }\n}\n\nexport async function readProductModel(path: string): Promise<ProductModel> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ProductModelError(`Failed to read product model at ${path}: ${cause}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ProductModelError(`Invalid JSON in ${path}: ${cause}`);\n }\n const result = productModelSchema.safeParse(parsed);\n if (!result.success) {\n const lines = result.error.issues.map((i) => {\n const p = i.path.length > 0 ? i.path.join('.') : '<root>';\n return ` ${p}: ${i.message}`;\n });\n throw new ProductModelError(\n `Product model failed validation:\\n${lines.join('\\n')}`,\n result.error.issues,\n );\n }\n return result.data;\n}\n","import { z } from 'zod';\n\nconst coreFlowSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n steps: z.array(z.string()).default([]),\n entry_url: z.string().optional(),\n});\n\nconst demoRecommendationSchema = z.object({\n suggested_flows: z.array(z.string()).default([]),\n suggested_duration_seconds: z.number().int().positive().default(90),\n});\n\nexport const productModelSchema = z.object({\n product_name: z.string().min(1),\n tagline: z.string().default(''),\n primary_user: z.string().default(''),\n confidence: z.enum(['high', 'medium', 'low']).default('medium'),\n source: z.enum(['documents', 'interactive']).default('documents'),\n generated_at: z.string().default(() => new Date().toISOString()),\n core_flows: z.array(coreFlowSchema).default([]),\n key_features: z.array(z.string()).default([]),\n demo_recommendation: demoRecommendationSchema.default({\n suggested_flows: [],\n suggested_duration_seconds: 90,\n }),\n});\n\nexport type ProductModel = z.infer<typeof productModelSchema>;\nexport type CoreFlow = z.infer<typeof coreFlowSchema>;\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { z } from 'zod';\nimport { manifestSchema, type Manifest } from './schema.js';\n\nexport class ManifestError extends Error {\n override readonly name = 'ManifestError';\n constructor(\n message: string,\n readonly issues?: z.ZodIssue[],\n ) {\n super(message);\n }\n}\n\nexport async function readManifest(path: string): Promise<Manifest> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ManifestError(`Failed to read manifest at ${path}: ${cause}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ManifestError(`Invalid JSON in manifest ${path}: ${cause}`);\n }\n return parseManifest(parsed);\n}\n\nexport function parseManifest(input: unknown): Manifest {\n const result = manifestSchema.safeParse(input);\n if (!result.success) {\n const lines = result.error.issues.map((i) => {\n const path = i.path.length > 0 ? i.path.join('.') : '<root>';\n return ` ${path}: ${i.message}`;\n });\n throw new ManifestError(`Manifest failed validation:\\n${lines.join('\\n')}`, result.error.issues);\n }\n return result.data;\n}\n\nexport async function writeManifest(path: string, manifest: Manifest): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(manifest, null, 2) + '\\n', 'utf8');\n}\n","import { z } from 'zod';\n\nconst atField = {\n at: z.number().nonnegative().optional(),\n at_word: z.string().min(1).optional(),\n at_occurrence: z.number().int().positive().optional(),\n};\n\nconst selectorField = z.union([z.string().min(1), z.array(z.string().min(1)).nonempty()]);\nexport type SelectorSpec = z.infer<typeof selectorField>;\n\nconst idleAction = z.object({ type: z.literal('idle'), ...atField });\nconst clickAction = z.object({ type: z.literal('click'), selector: selectorField, ...atField });\nconst fillAction = z.object({\n type: z.literal('fill'),\n selector: selectorField,\n value: z.string(),\n ...atField,\n});\nconst typeAction = z.object({\n type: z.literal('type'),\n selector: selectorField,\n value: z.string(),\n ...atField,\n});\nconst hoverAction = z.object({ type: z.literal('hover'), selector: selectorField, ...atField });\nconst scrollAction = z.object({\n type: z.literal('scroll'),\n selector: selectorField,\n direction: z.enum(['up', 'down']),\n ...atField,\n});\nconst navigateAction = z.object({ type: z.literal('navigate'), url: z.string(), ...atField });\nconst waitForAction = z.object({ type: z.literal('wait_for'), selector: selectorField, ...atField });\nconst waitForUrlAction = z.object({\n type: z.literal('wait_for_url'),\n pattern: z.string(),\n ...atField,\n});\nconst waitAction = z.object({\n type: z.literal('wait'),\n ms: z.number().int().nonnegative(),\n ...atField,\n});\nconst assertVisibleAction = z.object({\n type: z.literal('assert_visible'),\n selector: selectorField,\n ...atField,\n});\nconst pressAction = z.object({\n type: z.literal('press'),\n key: z.string(),\n selector: selectorField.optional(),\n ...atField,\n});\nconst customAction = z.object({ type: z.literal('custom'), js: z.string(), ...atField });\n\nexport const actionSchema = z.discriminatedUnion('type', [\n idleAction,\n clickAction,\n fillAction,\n typeAction,\n hoverAction,\n scrollAction,\n navigateAction,\n waitForAction,\n waitForUrlAction,\n waitAction,\n assertVisibleAction,\n pressAction,\n customAction,\n]);\n\nconst transitionSchema = z\n .enum(['cut', 'fade', 'fade_in', 'fade_out', 'dissolve'])\n .default('cut');\n\nexport const segmentSchema = z\n .object({\n id: z.string().min(1),\n label: z.string().min(1),\n start: z.number().nonnegative(),\n end: z.number().positive(),\n vo_line: z.string(),\n actions: z.array(actionSchema).default([{ type: 'idle' }]),\n transition: transitionSchema,\n })\n .refine((s) => s.end > s.start, {\n message: 'segment.end must be greater than segment.start',\n path: ['end'],\n });\n\nexport const manifestSchema = z\n .object({\n total_duration_seconds: z.number().positive(),\n generated_from: z.string().default('product_model.json'),\n segments: z.array(segmentSchema).min(1),\n })\n .superRefine((m, ctx) => {\n for (let i = 1; i < m.segments.length; i++) {\n const prev = m.segments[i - 1]!;\n const cur = m.segments[i]!;\n if (cur.start < prev.end - 1e-6) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['segments', i, 'start'],\n message: `segment \"${cur.id}\" starts before previous segment \"${prev.id}\" ends`,\n });\n }\n }\n const lastEnd = m.segments[m.segments.length - 1]!.end;\n if (Math.abs(lastEnd - m.total_duration_seconds) > 0.5) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['total_duration_seconds'],\n message: `total_duration_seconds (${m.total_duration_seconds}) does not match last segment end (${lastEnd})`,\n });\n }\n });\n\nexport type Manifest = z.infer<typeof manifestSchema>;\nexport type Segment = z.infer<typeof segmentSchema>;\nexport type Action = z.infer<typeof actionSchema>;\nexport type Transition = z.infer<typeof transitionSchema>;\n\nexport const ACTION_TYPES = [\n 'idle',\n 'click',\n 'fill',\n 'type',\n 'hover',\n 'scroll',\n 'navigate',\n 'wait_for',\n 'wait_for_url',\n 'wait',\n 'assert_visible',\n 'press',\n 'custom',\n] as const;\nexport type ActionType = (typeof ACTION_TYPES)[number];\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { Action, Manifest, Segment, SelectorSpec } from './schema.js';\nimport type { RecordingConfig } from '../config/schema.js';\n\nexport interface CodegenInputs {\n manifest: Manifest;\n recording: RecordingConfig;\n targetUrl: string;\n videoDir: string;\n traceDir: string;\n}\n\nconst HEADER = `// scripts/playwright_demo.ts\n// GENERATED FILE — DO NOT EDIT DIRECTLY.\n// Regenerated from scripts/manifest.json on every \\`showrunner run\\`.\n// Edit the manifest instead, then re-run the script stage.\n`;\n\nexport function renderPlaywrightSpec(inputs: CodegenInputs): string {\n const { manifest, recording, targetUrl, videoDir, traceDir } = inputs;\n\n const launchLines = [\n `import { chromium, firefox, webkit, type BrowserContext } from 'playwright-core';`,\n `import { mkdirSync } from 'node:fs';`,\n ``,\n `const VIDEO_DIR = ${JSON.stringify(videoDir)};`,\n `const TRACE_DIR = ${JSON.stringify(traceDir)};`,\n `const TARGET_URL = ${JSON.stringify(targetUrl)};`,\n `const STORAGE_STATE = process.env['SHOWRUNNER_STORAGE_STATE'] ?? undefined;`,\n ``,\n `mkdirSync(VIDEO_DIR, { recursive: true });`,\n `mkdirSync(TRACE_DIR, { recursive: true });`,\n ``,\n `const browserMap = { chromium, firefox, webkit } as const;`,\n `const browser = await browserMap[${JSON.stringify(recording.browser)}].launch({ headless: ${recording.headless} });`,\n `const context = await browser.newContext({`,\n ` viewport: { width: ${recording.viewport.width}, height: ${recording.viewport.height} },`,\n ` recordVideo: { dir: VIDEO_DIR, size: { width: ${recording.viewport.width}, height: ${recording.viewport.height} } },`,\n ` storageState: STORAGE_STATE,`,\n `});`,\n ``,\n `await context.tracing.start({ screenshots: true, snapshots: true, sources: true });`,\n ``,\n `const page = await context.newPage();`,\n `await page.goto(TARGET_URL);`,\n ``,\n `function logMarker(kind: 'start' | 'end', segment: string, t: number): void {`,\n ` process.stdout.write(JSON.stringify({ event: 'segment_' + kind, segment, t, wall_ms: Date.now() }) + '\\\\n');`,\n `}`,\n ``,\n `async function runSegment(ctx: BrowserContext, id: string, runner: () => Promise<void>): Promise<void> {`,\n ` await ctx.tracing.startChunk({ title: id });`,\n ` const t0 = performance.now();`,\n ` logMarker('start', id, t0);`,\n ` try {`,\n ` await runner();`,\n ` } finally {`,\n ` logMarker('end', id, performance.now());`,\n ` await ctx.tracing.stopChunk({ path: \\`\\${TRACE_DIR}/\\${id}.zip\\` });`,\n ` }`,\n `}`,\n ];\n\n const segmentBlocks = manifest.segments.map((s) => renderSegmentBlock(s)).join('\\n');\n\n const tail = [\n `await context.close();`,\n `await browser.close();`,\n `process.stdout.write(JSON.stringify({ event: 'recording_complete' }) + '\\\\n');`,\n ];\n\n return [HEADER, launchLines.join('\\n'), '', segmentBlocks, tail.join('\\n'), ''].join('\\n');\n}\n\nfunction renderSegmentBlock(seg: Segment): string {\n const head = `// segment: ${seg.id} (${formatRange(seg.start, seg.end)}) — ${seg.label}`;\n const actionLines = seg.actions.map((a) => ` ${renderAction(a)}`).join('\\n');\n return [\n head,\n `await runSegment(context, ${JSON.stringify(seg.id)}, async () => {`,\n actionLines || ' // no actions',\n `});`,\n ``,\n ].join('\\n');\n}\n\nfunction flattenSelector(sel: SelectorSpec): string {\n return Array.isArray(sel) ? sel.join(', ') : sel;\n}\n\nfunction renderAction(action: Action): string {\n switch (action.type) {\n case 'idle':\n return '/* idle — camera holds */';\n case 'click':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().click();`;\n case 'fill':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().fill(${JSON.stringify(action.value)});`;\n case 'type':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().pressSequentially(${JSON.stringify(action.value)});`;\n case 'hover':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().hover();`;\n case 'scroll': {\n const dy = action.direction === 'down' ? 'el.scrollHeight' : '-el.scrollHeight';\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().evaluate((el) => { el.scrollTop = ${dy}; });`;\n }\n case 'navigate':\n return `await page.goto(${JSON.stringify(action.url)});`;\n case 'wait_for':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().waitFor({ state: 'attached' });`;\n case 'wait_for_url':\n return `await page.waitForURL(${JSON.stringify(action.pattern)});`;\n case 'wait':\n return `await page.waitForTimeout(${action.ms});`;\n case 'assert_visible':\n return `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().waitFor({ state: 'visible' });`;\n case 'press':\n return action.selector\n ? `await page.locator(${JSON.stringify(flattenSelector(action.selector))}).first().press(${JSON.stringify(action.key)});`\n : `await page.keyboard.press(${JSON.stringify(action.key)});`;\n case 'custom':\n return `await page.evaluate(async () => { ${action.js} });`;\n }\n}\n\nfunction formatRange(start: number, end: number): string {\n return `${start.toFixed(2)}s – ${end.toFixed(2)}s`;\n}\n\nexport async function writePlaywrightSpec(path: string, inputs: CodegenInputs): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderPlaywrightSpec(inputs), 'utf8');\n}\n\nconst PREVIEW_HEADER = `// scripts/playwright_demo.spec.ts\n// GENERATED FILE — DO NOT EDIT DIRECTLY.\n// Lightweight @playwright/test wrapper used by \\`showrunner preview\\` (UI Mode).\n// Mirrors playwright_demo.ts but inside test() so Playwright's runner can drive it.\n`;\n\nexport function renderPlaywrightPreviewSpec(inputs: CodegenInputs): string {\n const { manifest, recording, targetUrl } = inputs;\n const segmentBlocks = manifest.segments\n .map((s) => {\n const head = ` // segment: ${s.id} (${formatRange(s.start, s.end)}) — ${s.label}`;\n const lines = s.actions.map((a) => ` ${renderAction(a)}`).join('\\n');\n return [head, lines || ' // no actions', ''].join('\\n');\n })\n .join('\\n');\n\n const usesExpect = manifest.segments.some((s) =>\n s.actions.some((a) => a.type === 'assert_visible'),\n );\n const playwrightImport = usesExpect\n ? `import { test, expect } from '@playwright/test';`\n : `import { test } from '@playwright/test';`;\n\n const body = [\n playwrightImport,\n ``,\n `test('preview', async ({ page }) => {`,\n ` test.setTimeout(120_000);`,\n ` await page.setViewportSize({ width: ${recording.viewport.width}, height: ${recording.viewport.height} });`,\n ` await page.goto(${JSON.stringify(targetUrl)});`,\n ``,\n segmentBlocks,\n `});`,\n ``,\n ];\n\n return [PREVIEW_HEADER, body.join('\\n')].join('\\n');\n}\n\nexport async function writePlaywrightPreviewSpec(\n path: string,\n inputs: CodegenInputs,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderPlaywrightPreviewSpec(inputs), 'utf8');\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { Manifest } from './schema.js';\n\nexport interface VoScriptOptions {\n projectName: string;\n generatedAt?: Date;\n}\n\nexport function renderVoScript(manifest: Manifest, opts: VoScriptOptions): string {\n const date = (opts.generatedAt ?? new Date()).toISOString().slice(0, 10);\n const lines: string[] = [\n `# Showrunner VO Script — ${opts.projectName}`,\n `# Total duration: ${formatDuration(manifest.total_duration_seconds)}`,\n `# Generated: ${date}`,\n ``,\n `# Edit the VO text below. Do not change the [m:ss] timestamps or line order.`,\n `# Re-run \\`showrunner approve-vo\\` to merge your edits back into the manifest.`,\n ``,\n ];\n for (const seg of manifest.segments) {\n lines.push(`[${formatTimestamp(seg.start)}] ${seg.vo_line}`);\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport async function writeVoScript(\n path: string,\n manifest: Manifest,\n opts: VoScriptOptions,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderVoScript(manifest, opts), 'utf8');\n}\n\nexport class VoScriptMergeError extends Error {\n override readonly name = 'VoScriptMergeError';\n}\n\ninterface ParsedLine {\n start: number;\n text: string;\n raw: string;\n lineNumber: number;\n}\n\nconst LINE_PATTERN = /^\\[(\\d+):(\\d{1,2})\\]\\s?(.*)$/;\n\nexport function parseVoScript(content: string): ParsedLine[] {\n const out: ParsedLine[] = [];\n const rawLines = content.split(/\\r?\\n/);\n for (let i = 0; i < rawLines.length; i++) {\n const raw = rawLines[i]!;\n const trimmed = raw.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n const match = LINE_PATTERN.exec(trimmed);\n if (!match) {\n throw new VoScriptMergeError(\n `Line ${i + 1} doesn't match \\`[m:ss] text\\` format: ${JSON.stringify(raw)}`,\n );\n }\n const minutes = Number(match[1]);\n const seconds = Number(match[2]);\n if (seconds >= 60) {\n throw new VoScriptMergeError(`Line ${i + 1}: seconds must be < 60`);\n }\n out.push({\n start: minutes * 60 + seconds,\n text: (match[3] ?? '').trim(),\n raw,\n lineNumber: i + 1,\n });\n }\n return out;\n}\n\nexport function mergeVoScript(manifest: Manifest, content: string): Manifest {\n const parsed = parseVoScript(content);\n if (parsed.length !== manifest.segments.length) {\n throw new VoScriptMergeError(\n `VO script has ${parsed.length} line(s); manifest has ${manifest.segments.length} segment(s). ` +\n `Adding or removing lines is not supported — regenerate the script via \\`showrunner run --force script\\`.`,\n );\n }\n const merged: Manifest = {\n ...manifest,\n segments: manifest.segments.map((seg, i) => {\n const line = parsed[i]!;\n if (Math.abs(line.start - seg.start) > 0.5) {\n throw new VoScriptMergeError(\n `Line ${line.lineNumber} timestamp [${formatTimestamp(line.start)}] does not match ` +\n `segment \"${seg.id}\" start (${formatTimestamp(seg.start)}). ` +\n `Did you reorder or retime lines? Regenerate via \\`showrunner run --force script\\`.`,\n );\n }\n return { ...seg, vo_line: line.text };\n }),\n };\n return merged;\n}\n\nexport async function readAndMergeVoScript(path: string, manifest: Manifest): Promise<Manifest> {\n const content = await readFile(path, 'utf8');\n return mergeVoScript(manifest, content);\n}\n\nfunction formatTimestamp(totalSeconds: number): string {\n const m = Math.floor(totalSeconds / 60);\n const s = Math.floor(totalSeconds - m * 60);\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n return formatTimestamp(totalSeconds);\n}\n","import { z, type ZodTypeAny } from 'zod';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface WithRetryOptions<S extends ZodTypeAny> extends GenerateStructuredOptions<S> {\n /**\n * Build the follow-up user prompt when the first attempt fails to validate\n * or parse. Receives the prior error text so the model can correct itself.\n * If undefined, no retry happens.\n */\n retryRenderer?: (errorText: string, previousUserPrompt: string) => string;\n}\n\n/**\n * Two-attempt structured generation. Provider does single-shot; this helper\n * captures schema-validation failures and re-prompts with the error context.\n * Most call sites that benefit from this are the manifest + product-model\n * generators (the ones whose schemas are complex enough that first-pass output\n * occasionally drifts). Single-shot call sites (like `instrument`) skip this\n * helper and call provider.generateStructured directly.\n */\nexport async function generateWithRetry<S extends ZodTypeAny>(\n provider: LLMProvider,\n opts: WithRetryOptions<S>,\n): Promise<z.infer<S>> {\n try {\n return await provider.generateStructured(opts);\n } catch (err) {\n const errText = formatErrorText(err);\n if (!opts.retryRenderer) {\n throw err;\n }\n logger.warn('Structured generation failed on first attempt; retrying with error feedback', {\n error: errText.slice(0, 200),\n });\n const retryPrompt = opts.retryRenderer(errText, opts.userPrompt);\n try {\n return await provider.generateStructured({ ...opts, userPrompt: retryPrompt });\n } catch (secondErr) {\n const secondErrText = formatErrorText(secondErr);\n throw new LLMProviderError(\n `Structured generation failed after one retry. Last error:\\n${secondErrText.slice(0, 2000)}`,\n 'unknown',\n secondErr,\n );\n }\n }\n}\n\nfunction formatErrorText(err: unknown): string {\n if (err instanceof z.ZodError) return err.message;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n","import type { z, ZodTypeAny } from 'zod';\n\nexport interface GenerateStructuredOptions<S extends ZodTypeAny> {\n systemPrompt: string;\n userPrompt: string;\n schema: S;\n /**\n * Hint for providers that need a schema name (OpenAI's json_schema format\n * requires one). Defaults to \"output\" if a provider needs one and none given.\n */\n schemaName?: string;\n /** Soft ceiling on output tokens; provider may interpret loosely. */\n maxTokens?: number;\n}\n\nexport interface LLMProvider {\n /** Single-shot structured generation. Retry/feedback lives at the call layer. */\n generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>>;\n}\n\nexport class LLMProviderError extends Error {\n override readonly name = 'LLMProviderError';\n constructor(\n message: string,\n readonly providerName: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n","import type { ProductModel } from '../productModel/schema.js';\nimport type { ScriptConfig } from '../config/schema.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\n\nexport const MANIFEST_GENERATOR_SYSTEM_PROMPT = `You are Showrunner's manifest generator. You produce a JSON manifest that drives an automated product-demo recording pipeline. The manifest you emit is the single source of truth for timing, on-screen actions, and voiceover lines.\n\n# What you produce\n\nA JSON object matching this shape:\n\n- \\`total_duration_seconds\\`: number, total demo length\n- \\`generated_from\\`: string, set to \"product_model.json\"\n- \\`segments\\`: an ordered, contiguous array of segment objects\n\nEach segment has:\n- \\`id\\`: kebab-case identifier (e.g. \"navigate-tests\")\n- \\`label\\`: human-readable title\n- \\`start\\`, \\`end\\`: seconds from demo start. Segments are contiguous (next.start === prev.end).\n- \\`vo_line\\`: spoken voiceover for this segment. Write it like a person would say it.\n- \\`actions\\`: array of UI actions to perform. See the table below.\n- \\`transition\\`: one of \"cut\", \"fade\", \"fade_in\", \"fade_out\", \"dissolve\". Use \"fade_in\" on the first segment.\n\n# Supported action types (use only these)\n\n| type | required fields | meaning |\n|---|---|---|\n| idle | — | no interaction; camera holds |\n| click | selector | click an element |\n| fill | selector, value | clear and type into an input |\n| type | selector, value | type without clearing (appends) |\n| hover | selector | hover over an element |\n| scroll | selector, direction (\"up\" or \"down\") | scroll inside an element |\n| navigate | url | full navigation to a URL |\n| wait_for | selector | wait until the element is visible |\n| wait_for_url | pattern | wait until URL matches a glob pattern |\n| wait | ms | explicit pause |\n| assert_visible | selector | assert element exists, fail segment if not |\n| custom | js | inline JavaScript executed in page context (fallback only) |\n\n# Selector hierarchy (most → least resilient)\n\n1. \\`[data-testid=\"...\"]\\` attributes — prefer these whenever the product model mentions them\n2. ARIA role + accessible name — use Playwright-style selectors like \\`role=button[name=\"Save\"]\\`\n3. Text content — \\`text=Save changes\\`\n4. CSS selectors — only as a last resort\n\nIf a \"Live DOM selector inventory\" section is provided, treat it as ground truth:\n- Every \\`selector\\` you emit for click/fill/type/hover/scroll/wait_for/assert_visible MUST appear **verbatim** in that list. Copy the \\`selector\\` string character-for-character — don't paraphrase, don't translate to a different selector format, don't merge or split.\n- For \\`:has-text(\"...\")\\` selectors specifically, the text inside the quotes must be the inventory entry's \\`visibleText\\` field **exactly**, including punctuation, arrows (→), and capitalization.\n- If the inventory can't satisfy a step (e.g. the page lacks a \"Pricing\" link), prefer dropping the action, using \\`wait\\`, or picking a related inventory entry — never invent a selector from product-model wording.\n\n**CSS class-name rules (when you do use a CSS path):** Do not include class names with bracketed values like \\`.max-w-[1280px]\\`, \\`.bg-[#abc]\\`, \\`.text-[20px]\\` — these are Tailwind shorthand, not legal CSS. Playwright will reject them with a SyntaxError. If a class is unstable or bracket-laden, walk up to the parent or use a different selector family entirely.\n\nIf no inventory is provided AND the product model does not specify selectors, infer plausible \\`data-testid\\` values from the flow step language (e.g. step \"Click New Test\" → \\`[data-testid='btn-new-test']\\`). Mark these as inferred in your reasoning if asked, but do not annotate the JSON itself.\n\n# Timing guidance\n\n- Aim for the script config's \\`duration_target_seconds\\`. Distribute it across segments by how much screen-time each step needs.\n- Intro segment: ~6–10s. Outro segment: ~4–8s.\n- A click-only step needs ~3–5s of screen time. A fill+submit cycle needs ~6–12s.\n- Make sure the final segment's \\`end\\` equals \\`total_duration_seconds\\`.\n\n# Voiceover guidance\n\n- Tone follows the script config's \\`style\\` field.\n- One \\`vo_line\\` per segment. Write spoken English — contractions are fine, but avoid filler.\n- Length should fit roughly inside the segment duration at conversational pace (~2.5 words per second). Slightly under is better than over.\n- Highlight the features named in the script config when possible.\n\n# Output discipline\n\n- Emit JSON only. No prose, no markdown fences.\n- All segment start/end times are floats in seconds.\n- segments[i].start === segments[i-1].end (contiguous).\n- segments[0].start === 0.\n`;\n\nexport function renderManifestUserPrompt(\n productModel: ProductModel,\n scriptConfig: ScriptConfig,\n selectorInventory?: SelectorInventoryItem[],\n): string {\n const parts = [\n 'Generate a manifest for the product described below.',\n '',\n '## Script configuration',\n `- style: ${scriptConfig.style}`,\n `- duration_target_seconds: ${scriptConfig.duration_target_seconds}`,\n `- highlight_features: ${\n scriptConfig.highlight_features.length === 0\n ? '(none specified — choose them yourself from the product model)'\n : JSON.stringify(scriptConfig.highlight_features)\n }`,\n '',\n '## Product model',\n '```json',\n JSON.stringify(productModel, null, 2),\n '```',\n ];\n if (selectorInventory && selectorInventory.length > 0) {\n parts.push(\n '',\n '## Live DOM selector inventory',\n `Scraped from the target URL. Use ONLY selectors from this list. ${selectorInventory.length} entries:`,\n '```json',\n JSON.stringify(selectorInventory, null, 2),\n '```',\n );\n }\n return parts.join('\\n');\n}\n\nexport function renderRetryPrompt(\n productModel: ProductModel,\n scriptConfig: ScriptConfig,\n validationError: string,\n selectorInventory?: SelectorInventoryItem[],\n): string {\n return [\n renderManifestUserPrompt(productModel, scriptConfig, selectorInventory),\n '',\n '## Previous attempt failed validation',\n 'Your previous response did not pass validation. Fix these issues and emit a corrected manifest:',\n '```',\n validationError,\n '```',\n ].join('\\n');\n}\n","import type { Action, Manifest } from '../manifest/schema.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\n\nexport interface SelectorViolation {\n segmentId: string;\n actionIndex: number;\n actionType: Action['type'];\n selector: string;\n reason: 'invalid_css_brackets' | 'not_in_inventory';\n hint?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n violations: SelectorViolation[];\n}\n\n/**\n * Tailwind class names with arbitrary-value brackets (e.g. `max-w-[1280px]`,\n * `bg-[#abc123]`) are common in modern CSS but are NOT legal CSS selectors —\n * Playwright will reject them with a SyntaxError. The LLM occasionally\n * synthesizes these when it walks up the DOM tree to build a fallback path.\n *\n * Match `.foo-[anything]` or `.foo[anything]` inside a CSS path segment.\n * (We don't ban legit attribute selectors like `[data-testid=\"x\"]` — those\n * stand alone, not glued to a class name.)\n */\nconst BRACKET_IN_CLASS_RE = /\\.[a-z0-9_-]+\\[[^\\]]+\\]/i;\n\nexport function validateManifestSelectors(\n manifest: Manifest,\n inventory: SelectorInventoryItem[],\n): ValidationResult {\n const inventorySet = new Set(inventory.map((i) => i.selector));\n const violations: SelectorViolation[] = [];\n\n for (const segment of manifest.segments) {\n for (let i = 0; i < segment.actions.length; i++) {\n const action = segment.actions[i]!;\n const selectors = extractSelectors(action);\n for (const sel of selectors) {\n if (BRACKET_IN_CLASS_RE.test(sel)) {\n violations.push({\n segmentId: segment.id,\n actionIndex: i,\n actionType: action.type,\n selector: sel,\n reason: 'invalid_css_brackets',\n hint:\n `Tailwind arbitrary-value classes like \\`.max-w-[1280px]\\` are not legal CSS selectors. ` +\n `Drop the bracket class from the path, or pick an inventory entry instead.`,\n });\n continue;\n }\n if (!inventorySet.has(sel)) {\n violations.push({\n segmentId: segment.id,\n actionIndex: i,\n actionType: action.type,\n selector: sel,\n reason: 'not_in_inventory',\n hint: 'This selector was not in the live DOM inventory. Pick one from the inventory list.',\n });\n }\n }\n }\n }\n\n return { ok: violations.length === 0, violations };\n}\n\nfunction extractSelectors(action: Action): string[] {\n // Actions without selectors (idle, navigate, wait, wait_for_url, custom) → skip\n switch (action.type) {\n case 'idle':\n case 'navigate':\n case 'wait':\n case 'wait_for_url':\n case 'custom':\n return [];\n case 'press':\n return action.selector ? toArray(action.selector) : [];\n default:\n return toArray(action.selector);\n }\n}\n\nfunction toArray(sel: string | readonly string[]): string[] {\n return typeof sel === 'string' ? [sel] : [...sel];\n}\n\n/**\n * Render a remediation prompt the LLM can use to fix a manifest whose\n * selectors didn't pass `validateManifestSelectors`.\n */\nexport function renderSelectorRemediation(violations: SelectorViolation[]): string {\n const lines: string[] = [\n 'Your previous manifest passed schema validation but its selectors are not usable:',\n '',\n ];\n for (const v of violations) {\n lines.push(\n `- Segment \"${v.segmentId}\", action ${v.actionIndex} (${v.actionType}): selector \\`${v.selector}\\` — ${v.reason}.`,\n );\n if (v.hint) lines.push(` ${v.hint}`);\n }\n lines.push('');\n lines.push(\n 'Re-emit the manifest. Every click/fill/type/hover/scroll/wait_for/assert_visible selector MUST appear verbatim in the live DOM selector inventory section above. For `:has-text` selectors, copy the `visibleText` field from the matching inventory entry exactly.',\n );\n return lines.join('\\n');\n}\n","import { parseManifest, ManifestError } from '../manifest/io.js';\nimport { manifestSchema, type Manifest } from '../manifest/schema.js';\nimport type { ProductModel } from '../productModel/schema.js';\nimport type { ScriptConfig } from '../config/schema.js';\nimport { logger } from '../util/logger.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\nimport { generateWithRetry } from '../providers/llm/withRetry.js';\nimport type { SelectorInventoryItem } from './domPreflight.js';\nimport {\n MANIFEST_GENERATOR_SYSTEM_PROMPT,\n renderManifestUserPrompt,\n renderRetryPrompt,\n} from './prompts.js';\nimport {\n renderSelectorRemediation,\n validateManifestSelectors,\n} from './validateSelectors.js';\n\nconst DEFAULT_MAX_TOKENS = 16000;\n\nexport interface GenerateManifestOptions {\n productModel: ProductModel;\n scriptConfig: ScriptConfig;\n provider: LLMProvider;\n selectorInventory?: SelectorInventoryItem[];\n}\n\nexport class ManifestGenerationError extends Error {\n override readonly name = 'ManifestGenerationError';\n}\n\nexport async function generateManifest(opts: GenerateManifestOptions): Promise<Manifest> {\n logger.debug('Generating manifest via LLM provider');\n try {\n const parsed = await generateWithRetry(opts.provider, {\n systemPrompt: MANIFEST_GENERATOR_SYSTEM_PROMPT,\n userPrompt: renderManifestUserPrompt(\n opts.productModel,\n opts.scriptConfig,\n opts.selectorInventory,\n ),\n schema: manifestSchema,\n schemaName: 'manifest',\n maxTokens: DEFAULT_MAX_TOKENS,\n retryRenderer: (errorText) =>\n renderRetryPrompt(\n opts.productModel,\n opts.scriptConfig,\n errorText,\n opts.selectorInventory,\n ),\n });\n\n let manifest: Manifest;\n try {\n manifest = parseManifest(parsed);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new ManifestGenerationError(`Manifest validation failed: ${err.message}`);\n }\n throw err;\n }\n\n // Post-validation: only if we have an inventory to compare against. With\n // no inventory the manifest's selectors are best-effort regardless.\n if (opts.selectorInventory && opts.selectorInventory.length > 0) {\n const check = validateManifestSelectors(manifest, opts.selectorInventory);\n if (!check.ok) {\n logger.warn(\n `manifest selector check failed: ${check.violations.length} violation(s) — retrying with remediation`,\n { violations: check.violations.length },\n );\n for (const v of check.violations.slice(0, 5)) {\n logger.debug(` ${v.segmentId}/${v.actionIndex}: ${v.reason} — ${v.selector}`);\n }\n\n const remediationUserPrompt = [\n renderManifestUserPrompt(opts.productModel, opts.scriptConfig, opts.selectorInventory),\n '',\n renderSelectorRemediation(check.violations),\n ].join('\\n');\n\n const retryResult = await opts.provider.generateStructured({\n systemPrompt: MANIFEST_GENERATOR_SYSTEM_PROMPT,\n userPrompt: remediationUserPrompt,\n schema: manifestSchema,\n schemaName: 'manifest',\n maxTokens: DEFAULT_MAX_TOKENS,\n });\n\n let retried: Manifest;\n try {\n retried = parseManifest(retryResult);\n } catch (err) {\n // Retry returned schema-invalid output — fall back to the first manifest\n // (violations and all). The record stage will warn per-failed-action\n // rather than crashing the whole pipeline.\n logger.warn(\n `selector-remediation retry returned schema-invalid output — keeping original manifest`,\n { error: err instanceof Error ? err.message : String(err) },\n );\n return manifest;\n }\n\n const recheck = validateManifestSelectors(retried, opts.selectorInventory);\n if (recheck.ok) {\n logger.event({ stage: 'script', status: 'selector_retry_resolved', segments: retried.segments.length });\n } else {\n logger.warn(\n `selector-remediation retry still has ${recheck.violations.length} violation(s) — accepting anyway`,\n { remaining: recheck.violations.length },\n );\n }\n return retried;\n }\n }\n\n return manifest;\n } catch (err) {\n if (err instanceof ManifestGenerationError) throw err;\n throw new ManifestGenerationError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { chromium, firefox, webkit } from 'playwright-core';\nimport type { RecordingConfig } from '../config/schema.js';\nimport { SELECTOR_FOR_FN_SOURCE } from '../recording/selectorHeuristic.js';\nimport { logger } from '../util/logger.js';\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport interface SelectorInventoryItem {\n tag: string;\n selector: string;\n visibleText?: string;\n role?: string;\n dataTestid?: string;\n name?: string;\n placeholder?: string;\n ariaLabel?: string;\n href?: string;\n}\n\nexport interface ScrapeOptions {\n targetUrl: string;\n recording: RecordingConfig;\n /** Network-idle ceiling. Falls back to load if it never fires. Default 3000ms. */\n networkIdleTimeoutMs?: number;\n /** Hard navigation timeout. Default 15000ms. */\n navigationTimeoutMs?: number;\n /** Maximum items returned (truncates from the end). Default 200. */\n maxItems?: number;\n}\n\n/**\n * Launches Playwright once, navigates to the target, and snapshots the\n * actionable DOM into a flat selector inventory. The LLM in the `script`\n * stage uses this as ground truth so it can't hallucinate selectors.\n *\n * Failure is non-fatal — caller should treat a thrown error as \"skip preflight\n * and fall back to LLM-only generation,\" logging a warning.\n */\nexport async function scrapeSelectorInventory(\n opts: ScrapeOptions,\n): Promise<SelectorInventoryItem[]> {\n const networkIdleMs = opts.networkIdleTimeoutMs ?? 3000;\n const navigationMs = opts.navigationTimeoutMs ?? 15000;\n const maxItems = opts.maxItems ?? 200;\n\n const browser = await browserMap[opts.recording.browser].launch({ headless: true });\n try {\n const context = await browser.newContext({\n viewport: {\n width: opts.recording.viewport.width,\n height: opts.recording.viewport.height,\n },\n });\n const page = await context.newPage();\n page.setDefaultNavigationTimeout(navigationMs);\n await page.goto(opts.targetUrl, { waitUntil: 'load' });\n try {\n await page.waitForLoadState('networkidle', { timeout: networkIdleMs });\n } catch {\n logger.debug('domPreflight: networkidle did not fire within budget — proceeding');\n }\n\n const items = (await page.evaluate(\n buildScrapeScript(SELECTOR_FOR_FN_SOURCE, maxItems),\n )) as SelectorInventoryItem[];\n\n await context.close();\n return items;\n } finally {\n await browser.close();\n }\n}\n\n/**\n * Build the in-page scrape script as a string. Returning the function body as\n * a string lets us reuse the shared SELECTOR_FOR_FN_SOURCE and sidesteps the\n * tsconfig DOM-lib issue (the host project doesn't include DOM types).\n */\nfunction buildScrapeScript(selectorSource: string, maxItems: number): string {\n return `(() => {\n ${selectorSource}\n\n var QUERY = 'button, a, input, textarea, select, summary, label, h1, h2, h3, [role=button], [role=link], [role=textbox], [data-testid], [data-test-id]';\n var nodes = Array.from(document.querySelectorAll(QUERY));\n var out = [];\n var seen = new Set();\n\n for (var i = 0; i < nodes.length; i++) {\n var el = nodes[i];\n if (!el || el.nodeType !== 1) continue;\n var rect = el.getBoundingClientRect();\n var styles = window.getComputedStyle(el);\n var visible = rect.width > 0 && rect.height > 0 && styles.visibility !== 'hidden' && styles.display !== 'none' && styles.opacity !== '0';\n if (!visible) continue;\n\n var selector = selectorFor(el);\n if (!selector) continue;\n if (seen.has(selector)) continue;\n seen.add(selector);\n\n var item = { tag: el.tagName.toLowerCase(), selector: selector };\n var rawText = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (rawText) item.visibleText = rawText.slice(0, 80);\n var role = el.getAttribute('role');\n if (role) item.role = role;\n var tid = el.getAttribute('data-testid') || el.getAttribute('data-test-id');\n if (tid) item.dataTestid = tid;\n var name = el.getAttribute('name');\n if (name) item.name = name;\n var placeholder = el.getAttribute('placeholder');\n if (placeholder) item.placeholder = placeholder;\n var aria = el.getAttribute('aria-label');\n if (aria) item.ariaLabel = aria;\n if (el.tagName === 'A' && el.href) item.href = el.href;\n out.push(item);\n if (out.length >= ${maxItems}) break;\n }\n return out;\n })()`;\n}\n","/**\n * The selector-preference heuristic used by `record-actions` (in-page event\n * capture) and `script` stage's DOM preflight (DOM scrape for selector inventory).\n *\n * Preference order:\n * 1. [data-testid=\"...\"]\n * 2. <tag>[name=\"...\"] for INPUT/TEXTAREA/SELECT\n * 3. <tag>[placeholder=\"...\"]\n * 4. [aria-label=\"...\"]\n * 5. #id (when id looks stable, not hash-like)\n * 6. <tag>:has-text(\"...\") for BUTTON/A/SUMMARY/LABEL with visible text\n * 7. Minimal CSS path (tag.class:nth-of-type, walked up to 5 levels)\n *\n * This module exports the function body as a string so it can be embedded\n * verbatim inside `page.evaluate` / `addInitScript` payloads (which can't\n * import from outside the page context).\n */\n\nexport const SELECTOR_FOR_FN_SOURCE = `\nfunction escapeAttr(v) {\n return String(v).replace(/\"/g, '\\\\\\\\\"');\n}\n\nfunction looksUnstable(s) {\n // hash-like ids and classnames are unstable. Examples:\n // \"css-1a2b3c\" - emotion/styled-components\n // \"x_abc123\" - generic\n // \"__variable_3eb911\" - Next.js compiled font/CSS variables\n // \"1a2b3c4d5e6f\" - bare hex hash\n // The leading \"_*\" tolerates one or more underscores at the start.\n return /^_*[a-z]+[-_][a-f0-9]{6,}$/i.test(s) || /^[a-zA-Z]?[a-f0-9]{8,}$/.test(s);\n}\n\nfunction selectorFor(el) {\n if (!el || el.nodeType !== 1) return null;\n const testid = el.getAttribute('data-testid') || el.getAttribute('data-test-id');\n if (testid) return '[data-testid=\"' + escapeAttr(testid) + '\"]';\n\n const name = el.getAttribute('name');\n if (name && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT')) {\n return el.tagName.toLowerCase() + '[name=\"' + escapeAttr(name) + '\"]';\n }\n\n const placeholder = el.getAttribute('placeholder');\n if (placeholder) return el.tagName.toLowerCase() + '[placeholder=\"' + escapeAttr(placeholder) + '\"]';\n\n const aria = el.getAttribute('aria-label');\n if (aria) return '[aria-label=\"' + escapeAttr(aria) + '\"]';\n\n if (el.id && !looksUnstable(el.id)) return '#' + el.id;\n\n const textTags = new Set(['BUTTON', 'A', 'SUMMARY', 'LABEL']);\n if (textTags.has(el.tagName)) {\n const text = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (text.length > 0 && text.length <= 64) {\n return el.tagName.toLowerCase() + ':has-text(\"' + escapeAttr(text) + '\")';\n }\n }\n\n const parts = [];\n let node = el;\n while (node && node.nodeType === 1 && parts.length < 5) {\n let part = node.tagName.toLowerCase();\n if (node.id && !looksUnstable(node.id)) {\n parts.unshift('#' + node.id);\n break;\n }\n const cls = (node.className || '').toString().split(/\\\\s+/).filter((c) => c && !looksUnstable(c));\n if (cls.length > 0) part += '.' + cls[0];\n const parent = node.parentElement;\n if (parent) {\n const same = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (same.length > 1) {\n const idx = same.indexOf(node) + 1;\n part += ':nth-of-type(' + idx + ')';\n }\n }\n parts.unshift(part);\n node = parent;\n }\n return parts.join(' > ');\n}\n`;\n","import Anthropic from '@anthropic-ai/sdk';\nimport { zodOutputFormat } from '@anthropic-ai/sdk/helpers/zod';\nimport type { ParsedMessage } from '@anthropic-ai/sdk/lib/parser';\nimport type { z, ZodTypeAny } from 'zod';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface AnthropicProviderConfig {\n apiKey: string;\n model: string;\n /** Default max_tokens when the call site doesn't override. */\n maxTokens?: number;\n}\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nexport class AnthropicLLMProvider implements LLMProvider {\n private readonly client: Anthropic;\n private readonly model: string;\n private readonly defaultMaxTokens: number;\n\n constructor(cfg: AnthropicProviderConfig) {\n if (!cfg.apiKey) {\n throw new LLMProviderError(\n 'AnthropicLLMProvider: apiKey is required',\n 'anthropic',\n );\n }\n this.client = new Anthropic({ apiKey: cfg.apiKey });\n this.model = cfg.model;\n this.defaultMaxTokens = cfg.maxTokens ?? DEFAULT_MAX_TOKENS;\n }\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const response = await this.client.messages.parse({\n model: this.model,\n max_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n thinking: { type: 'adaptive' as const },\n system: [\n {\n type: 'text' as const,\n text: opts.systemPrompt,\n cache_control: { type: 'ephemeral' as const },\n },\n ],\n output_config: { format: zodOutputFormat(opts.schema) },\n messages: [{ role: 'user', content: opts.userPrompt }],\n });\n\n return extractAndValidate(response, opts.schema);\n }\n}\n\nfunction extractAndValidate<S extends ZodTypeAny>(\n response: ParsedMessage<unknown>,\n schema: S,\n): z.infer<S> {\n if (response.parsed_output !== undefined && response.parsed_output !== null) {\n return schema.parse(response.parsed_output);\n }\n const text = response.content\n .filter((b): b is Anthropic.Messages.TextBlock => b.type === 'text')\n .map((b) => b.text)\n .join('\\n')\n .trim();\n throw new LLMProviderError(\n text.length > 0\n ? `Anthropic returned no parseable structured output. Raw text:\\n${text.slice(0, 2000)}`\n : 'Anthropic returned an empty response with no parseable output.',\n 'anthropic',\n );\n}\n","import OpenAI from 'openai';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { z, ZodTypeAny } from 'zod';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface OpenAIProviderConfig {\n apiKey: string;\n model: string;\n /** Default max output tokens. */\n maxTokens?: number;\n /** Override the API base (Azure / OpenRouter / etc). */\n baseURL?: string;\n}\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\n/**\n * Uses the OpenAI chat-completions API with `response_format: json_schema`\n * for native structured-output validation. Falls back to `json_object` mode\n * (free-form JSON + post-parse) when the schema is rejected (some Zod\n * constructs OpenAI's strict mode can't validate — discriminated unions,\n * deeply-nested z.record, etc).\n */\nexport class OpenAILLMProvider implements LLMProvider {\n private readonly client: OpenAI;\n private readonly model: string;\n private readonly defaultMaxTokens: number;\n\n constructor(cfg: OpenAIProviderConfig) {\n if (!cfg.apiKey) {\n throw new LLMProviderError(\n 'OpenAILLMProvider: apiKey is required',\n 'openai',\n );\n }\n this.client = new OpenAI({ apiKey: cfg.apiKey, baseURL: cfg.baseURL });\n this.model = cfg.model;\n this.defaultMaxTokens = cfg.maxTokens ?? DEFAULT_MAX_TOKENS;\n }\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const jsonSchema = patchSchemaForStrict(\n zodToJsonSchema(opts.schema, opts.schemaName ?? 'output'),\n );\n const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [\n { role: 'system', content: opts.systemPrompt },\n { role: 'user', content: opts.userPrompt },\n ];\n\n try {\n const response = await this.client.chat.completions.create({\n model: this.model,\n max_completion_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n messages,\n response_format: {\n type: 'json_schema',\n json_schema: {\n name: opts.schemaName ?? 'output',\n schema: jsonSchema as Record<string, unknown>,\n strict: true,\n },\n },\n });\n const raw = response.choices[0]?.message?.content ?? '';\n const parsed = safeJsonParse(raw);\n return opts.schema.parse(parsed);\n } catch (err) {\n // OpenAI rejects some schema shapes outright. Fall back to free-form\n // JSON output + post-parse via Zod.\n if (!isSchemaRejection(err)) throw wrap(err);\n logger.warn('OpenAI rejected the json_schema; falling back to json_object mode', {\n cause: err instanceof Error ? err.message : String(err),\n });\n const response = await this.client.chat.completions.create({\n model: this.model,\n max_completion_tokens: opts.maxTokens ?? this.defaultMaxTokens,\n messages: [\n {\n role: 'system',\n content: `${opts.systemPrompt}\\n\\nRespond with a single JSON object that matches the schema described in the user message. Do not include any prose.`,\n },\n { role: 'user', content: opts.userPrompt },\n ],\n response_format: { type: 'json_object' },\n });\n const raw = response.choices[0]?.message?.content ?? '';\n const parsed = safeJsonParse(raw);\n return opts.schema.parse(parsed);\n }\n }\n}\n\nfunction isSchemaRejection(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const msg = (err as { message?: string }).message ?? '';\n return /Invalid schema|response_format|json_schema/i.test(msg);\n}\n\nfunction wrap(err: unknown): LLMProviderError {\n return new LLMProviderError(\n `OpenAI call failed: ${err instanceof Error ? err.message : String(err)}`,\n 'openai',\n err,\n );\n}\n\nfunction safeJsonParse(raw: string): unknown {\n const trimmed = raw.trim();\n if (!trimmed) {\n throw new LLMProviderError('OpenAI returned empty content', 'openai');\n }\n try {\n return JSON.parse(trimmed);\n } catch {\n // Some models still wrap output in a fence even when asked not to.\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)```/.exec(trimmed);\n if (fenced && fenced[1]) return JSON.parse(fenced[1].trim());\n throw new LLMProviderError(\n `OpenAI content was not valid JSON. First 500 chars:\\n${trimmed.slice(0, 500)}`,\n 'openai',\n );\n }\n}\n\n/**\n * OpenAI's strict json_schema rejects schemas that don't set\n * `additionalProperties: false` on every object node. Walk the tree and patch.\n */\nfunction patchSchemaForStrict(schema: unknown): unknown {\n if (Array.isArray(schema)) return schema.map(patchSchemaForStrict);\n if (schema && typeof schema === 'object') {\n const obj = { ...(schema as Record<string, unknown>) };\n if (obj['type'] === 'object' && obj['additionalProperties'] === undefined) {\n obj['additionalProperties'] = false;\n }\n for (const k of Object.keys(obj)) {\n obj[k] = patchSchemaForStrict(obj[k]);\n }\n return obj;\n }\n return schema;\n}\n","import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { z, ZodTypeAny } from 'zod';\nimport { runCommandCapture } from '../../recording/lifecycle.js';\nimport { logger } from '../../util/logger.js';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport type AgentBridgeMode = 'spawn' | 'file_poll';\n\nexport interface AgentBridgeSpawnConfig {\n mode: 'spawn';\n /** Default `claude` */\n command: string;\n /** Default `['-p', '--output-format', 'json']` (Claude CLI headless mode). */\n args: string[];\n /** Kill the subprocess after this many ms. Default 300000 (5 minutes). */\n timeoutMs?: number;\n /** Run the child process in this directory. */\n cwd?: string;\n}\n\nexport interface AgentBridgeFilePollConfig {\n mode: 'file_poll';\n /** Directory where request files are written and response files are awaited. */\n requestDir: string;\n /** Polling interval (ms). Default 500. */\n pollIntervalMs?: number;\n /** Give up after this many ms. Default 600000 (10 minutes). */\n timeoutMs?: number;\n}\n\nexport type AgentBridgeConfig = AgentBridgeSpawnConfig | AgentBridgeFilePollConfig;\n\nconst FENCED_JSON = /```(?:json)?\\s*([\\s\\S]*?)```/;\n\nexport class AgentBridgeLLMProvider implements LLMProvider {\n constructor(private readonly cfg: AgentBridgeConfig) {}\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const jsonSchema = zodToJsonSchema(opts.schema, opts.schemaName ?? 'output');\n const prompt = renderBridgePrompt(opts.systemPrompt, opts.userPrompt, jsonSchema);\n\n let rawResponse: string;\n if (this.cfg.mode === 'spawn') {\n rawResponse = await invokeSpawn(this.cfg, prompt);\n } else {\n rawResponse = await invokeFilePoll(this.cfg, prompt);\n }\n\n const structured = extractJson(rawResponse);\n try {\n return opts.schema.parse(structured);\n } catch (err) {\n throw new LLMProviderError(\n `Agent bridge response did not match the expected schema: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'agent_bridge',\n err,\n );\n }\n }\n}\n\nfunction renderBridgePrompt(systemPrompt: string, userPrompt: string, jsonSchema: unknown): string {\n return [\n 'You are being called via a non-interactive bridge. Your job is to return ONLY a JSON object that conforms to the provided JSON Schema. No prose, no greeting, no markdown — emit just the JSON inside a single ```json fenced block.',\n '',\n '## System instructions for this task',\n systemPrompt,\n '',\n '## JSON Schema your response must satisfy',\n '```json',\n JSON.stringify(jsonSchema, null, 2),\n '```',\n '',\n '## Task',\n userPrompt,\n '',\n 'Respond with exactly one ```json ... ``` block containing the structured output. Do not include any text before or after the fence.',\n ].join('\\n');\n}\n\nasync function invokeSpawn(cfg: AgentBridgeSpawnConfig, prompt: string): Promise<string> {\n const result = await runCommandCapture({\n cmd: cfg.command,\n args: cfg.args,\n cwd: cfg.cwd,\n label: `llm-bridge:${cfg.command}`,\n stdin: prompt,\n timeoutMs: cfg.timeoutMs ?? 300_000,\n });\n if (result.exitCode !== 0) {\n throw new LLMProviderError(\n `Agent bridge command \\`${cfg.command}\\` exited with code ${result.exitCode}\\nstderr:\\n${result.stderr.slice(-2000)}`,\n 'agent_bridge',\n );\n }\n // Claude CLI in --output-format json mode emits a JSON envelope on stdout\n // with a `content` field (and other metadata like total_cost_usd). If we can\n // parse the envelope, prefer the content field; otherwise treat stdout as\n // the raw model output.\n const trimmed = result.stdout.trim();\n if (trimmed.startsWith('{')) {\n try {\n const envelope = JSON.parse(trimmed) as Record<string, unknown>;\n const content = envelope['content'] ?? envelope['result'];\n if (typeof content === 'string') return content;\n } catch {\n // Not a JSON envelope — fall through and treat stdout as raw text.\n }\n }\n return trimmed;\n}\n\nasync function invokeFilePoll(cfg: AgentBridgeFilePollConfig, prompt: string): Promise<string> {\n await mkdir(cfg.requestDir, { recursive: true });\n const id = randomUUID();\n const reqPath = join(cfg.requestDir, `${id}.request.json`);\n const resPath = join(cfg.requestDir, `${id}.response.json`);\n await writeFile(reqPath, JSON.stringify({ id, prompt }, null, 2) + '\\n', 'utf8');\n logger.info('Agent bridge: wrote LLM request, waiting for response', { reqPath, resPath });\n\n const pollInterval = cfg.pollIntervalMs ?? 500;\n const timeout = cfg.timeoutMs ?? 600_000;\n const deadline = Date.now() + timeout;\n\n while (Date.now() < deadline) {\n if (await fileExists(resPath)) {\n const raw = await readFile(resPath, 'utf8');\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const content = parsed['content'] ?? parsed['response'];\n if (typeof content === 'string') return content;\n return raw;\n } catch {\n return raw;\n }\n }\n await sleep(pollInterval);\n }\n\n throw new LLMProviderError(\n `Agent bridge (file_poll) timed out after ${timeout}ms waiting for ${resPath}`,\n 'agent_bridge',\n );\n}\n\nfunction extractJson(raw: string): unknown {\n const fenced = FENCED_JSON.exec(raw);\n if (fenced && fenced[1]) {\n try {\n return JSON.parse(fenced[1].trim());\n } catch {\n // fall through to balanced-brace extraction\n }\n }\n // Find the longest balanced { ... } block.\n const start = raw.indexOf('{');\n const end = raw.lastIndexOf('}');\n if (start === -1 || end <= start) {\n throw new LLMProviderError(\n `Agent bridge response contained no parseable JSON. First 500 chars:\\n${raw.slice(0, 500)}`,\n 'agent_bridge',\n );\n }\n const candidate = raw.slice(start, end + 1);\n try {\n return JSON.parse(candidate);\n } catch (err) {\n throw new LLMProviderError(\n `Agent bridge response had JSON-like text but it didn't parse: ${\n err instanceof Error ? err.message : String(err)\n }\\nFirst 500 chars:\\n${raw.slice(0, 500)}`,\n 'agent_bridge',\n );\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { spawn } from 'node:child_process';\nimport { stat } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { logger } from '../util/logger.js';\n\nexport class LifecycleScriptError extends Error {\n override readonly name = 'LifecycleScriptError';\n constructor(\n message: string,\n readonly script: string,\n readonly exitCode: number | null,\n ) {\n super(message);\n }\n}\n\nexport interface RunScriptOptions {\n scriptPath: string;\n configDir: string;\n env: Record<string, string>;\n label: string;\n}\n\nexport interface RunCommandOptions {\n cmd: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n label: string;\n /** When true, child inherits stdio (for interactive viewers like trace UI). */\n inherit?: boolean;\n}\n\n/**\n * Spawn an external command, prefix stdout/stderr lines with the label, and\n * resolve on exit-code-0 or reject with a LifecycleScriptError. Bypasses any\n * file-existence check — use this for commands like `npx playwright show-trace`\n * where the binary is resolved via the user's PATH.\n */\nexport async function runCommand(opts: RunCommandOptions): Promise<void> {\n const { cmd, args = [], cwd, env = {}, label, inherit = false } = opts;\n logger.debug(`spawn ${label}`, { cmd, args });\n\n await new Promise<void>((resolveRun, rejectRun) => {\n const child = spawn(cmd, args, {\n cwd,\n env: { ...process.env, ...env },\n stdio: inherit ? 'inherit' : ['ignore', 'pipe', 'pipe'],\n shell: process.platform === 'win32',\n });\n\n if (!inherit) {\n const prefix = `[${label}]`;\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (chunk: string) => {\n for (const line of chunk.split(/\\r?\\n/)) {\n if (line.length === 0) continue;\n process.stdout.write(`${prefix} ${line}\\n`);\n }\n });\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (chunk: string) => {\n for (const line of chunk.split(/\\r?\\n/)) {\n if (line.length === 0) continue;\n process.stderr.write(`${prefix} ${line}\\n`);\n }\n });\n }\n\n child.on('error', (err) => {\n rejectRun(\n new LifecycleScriptError(\n `Failed to spawn ${label}: ${err.message}`,\n cmd,\n null,\n ),\n );\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n resolveRun();\n } else {\n rejectRun(\n new LifecycleScriptError(\n `${label} exited with code ${code}`,\n cmd,\n code,\n ),\n );\n }\n });\n });\n}\n\nexport interface RunCommandCaptureOptions {\n cmd: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n /** Text to write to the child's stdin before it's closed. */\n stdin?: string;\n label: string;\n /** Kill the child if it hasn't exited by this deadline (ms). */\n timeoutMs?: number;\n}\n\nexport interface CapturedRunResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/**\n * Spawn an external command, optionally pipe stdin to it, capture stdout +\n * stderr to strings, and return on exit. Unlike `runCommand` this does NOT\n * mirror stdio to the parent process — it's intended for one-shot helpers\n * (LLM agent bridges, ffprobe pipes, version checks) where the caller wants\n * to inspect the output programmatically.\n */\nexport async function runCommandCapture(opts: RunCommandCaptureOptions): Promise<CapturedRunResult> {\n const { cmd, args = [], cwd, env = {}, label, stdin, timeoutMs } = opts;\n logger.debug(`capture ${label}`, { cmd, args });\n\n return await new Promise<CapturedRunResult>((resolveRun, rejectRun) => {\n const child = spawn(cmd, args, {\n cwd,\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: process.platform === 'win32',\n });\n\n let stdout = '';\n let stderr = '';\n let timer: NodeJS.Timeout | undefined;\n\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (chunk: string) => {\n stderr += chunk;\n });\n\n if (timeoutMs && timeoutMs > 0) {\n timer = setTimeout(() => {\n child.kill('SIGTERM');\n rejectRun(\n new LifecycleScriptError(\n `${label} timed out after ${timeoutMs}ms`,\n cmd,\n null,\n ),\n );\n }, timeoutMs);\n }\n\n child.on('error', (err) => {\n if (timer) clearTimeout(timer);\n rejectRun(\n new LifecycleScriptError(\n `Failed to spawn ${label}: ${err.message}`,\n cmd,\n null,\n ),\n );\n });\n\n child.on('exit', (code) => {\n if (timer) clearTimeout(timer);\n resolveRun({ stdout, stderr, exitCode: code ?? -1 });\n });\n\n if (stdin !== undefined && child.stdin) {\n child.stdin.write(stdin);\n child.stdin.end();\n } else if (child.stdin) {\n child.stdin.end();\n }\n });\n}\n\nexport async function runLifecycleScript(opts: RunScriptOptions): Promise<void> {\n const abs = isAbsolute(opts.scriptPath) ? opts.scriptPath : resolve(opts.configDir, opts.scriptPath);\n try {\n await stat(abs);\n } catch {\n throw new LifecycleScriptError(\n `${opts.label} script not found at ${abs}`,\n abs,\n null,\n );\n }\n\n logger.info(`Running ${opts.label} script`, { script: abs });\n\n await runCommand({\n cmd: abs,\n args: [],\n cwd: opts.configDir,\n env: opts.env,\n label: opts.label,\n });\n}\n","import { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { z, ZodTypeAny } from 'zod';\nimport type {\n GenerateStructuredOptions,\n LLMProvider,\n} from './types.js';\nimport { LLMProviderError } from './types.js';\n\nexport interface CustomLLMProviderConfig {\n modulePath: string;\n configDir: string;\n /** Free-form provider options forwarded to the loaded module's factory. */\n options?: Record<string, unknown>;\n}\n\n/**\n * Loads an operator-supplied module that default-exports either an LLMProvider\n * directly or a factory function `(options) => LLMProvider`. The module is\n * resolved relative to `configDir` and cached for the lifetime of the process.\n */\nexport class CustomLLMProvider implements LLMProvider {\n private inner: Promise<LLMProvider> | null = null;\n constructor(private readonly cfg: CustomLLMProviderConfig) {}\n\n async generateStructured<S extends ZodTypeAny>(opts: GenerateStructuredOptions<S>): Promise<z.infer<S>> {\n const provider = await this.load();\n return provider.generateStructured(opts);\n }\n\n private async load(): Promise<LLMProvider> {\n if (this.inner) return this.inner;\n this.inner = (async () => {\n const absPath = isAbsolute(this.cfg.modulePath)\n ? this.cfg.modulePath\n : resolve(this.cfg.configDir, this.cfg.modulePath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(absPath).href)) as { default?: unknown };\n } catch (err) {\n throw new LLMProviderError(\n `Failed to load custom LLM module at ${absPath}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'custom',\n err,\n );\n }\n const exp = mod.default ?? mod;\n if (typeof exp === 'function') {\n const built = await (exp as (o?: unknown) => Promise<LLMProvider> | LLMProvider)(\n this.cfg.options,\n );\n if (!isLLMProvider(built)) {\n throw new LLMProviderError(\n `Custom LLM module at ${absPath} returned a value that is not a LLMProvider (missing generateStructured)`,\n 'custom',\n );\n }\n return built;\n }\n if (isLLMProvider(exp)) return exp;\n throw new LLMProviderError(\n `Custom LLM module at ${absPath} must default-export an LLMProvider or a factory function`,\n 'custom',\n );\n })();\n return this.inner;\n }\n}\n\nfunction isLLMProvider(v: unknown): v is LLMProvider {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as { generateStructured?: unknown }).generateStructured === 'function'\n );\n}\n","import type { LLMProvider } from './types.js';\nimport { LLMProviderError } from './types.js';\nimport { AnthropicLLMProvider } from './anthropic.js';\nimport { OpenAILLMProvider } from './openai.js';\nimport { AgentBridgeLLMProvider, type AgentBridgeConfig } from './agentBridge.js';\nimport { CustomLLMProvider } from './custom.js';\n\nexport interface AnthropicProviderSpec {\n provider: 'anthropic';\n model: string;\n api_key_env: string;\n max_tokens?: number;\n}\n\nexport interface OpenAIProviderSpec {\n provider: 'openai';\n model: string;\n api_key_env: string;\n max_tokens?: number;\n base_url?: string;\n}\n\nexport interface AgentBridgeProviderSpec {\n provider: 'agent_bridge';\n bridge: {\n mode: 'spawn' | 'file_poll';\n command?: string;\n args?: string[];\n cwd?: string;\n request_dir?: string;\n poll_interval_ms?: number;\n timeout_ms?: number;\n };\n}\n\nexport interface CustomProviderSpec {\n provider: 'custom';\n module_path: string;\n options?: Record<string, unknown>;\n}\n\nexport type LLMProviderSpec =\n | AnthropicProviderSpec\n | OpenAIProviderSpec\n | AgentBridgeProviderSpec\n | CustomProviderSpec;\n\nexport interface CreateContext {\n configDir: string;\n}\n\nexport function createLLMProvider(spec: LLMProviderSpec, ctx: CreateContext): LLMProvider {\n switch (spec.provider) {\n case 'anthropic': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new LLMProviderError(\n `LLM provider 'anthropic' configured with api_key_env='${spec.api_key_env}' but that env var is not set. Set it (e.g. in your project .env) or switch to a different provider.`,\n 'anthropic',\n );\n }\n return new AnthropicLLMProvider({\n apiKey,\n model: spec.model,\n maxTokens: spec.max_tokens,\n });\n }\n case 'openai': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new LLMProviderError(\n `LLM provider 'openai' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'openai',\n );\n }\n return new OpenAILLMProvider({\n apiKey,\n model: spec.model,\n maxTokens: spec.max_tokens,\n baseURL: spec.base_url,\n });\n }\n case 'agent_bridge': {\n const bridgeCfg: AgentBridgeConfig =\n spec.bridge.mode === 'file_poll'\n ? {\n mode: 'file_poll',\n requestDir: spec.bridge.request_dir ?? `${ctx.configDir}/.showrunner-cache/llm-bridge`,\n pollIntervalMs: spec.bridge.poll_interval_ms,\n timeoutMs: spec.bridge.timeout_ms,\n }\n : {\n mode: 'spawn',\n command: spec.bridge.command ?? 'claude',\n args: spec.bridge.args ?? ['-p', '--output-format', 'json'],\n cwd: spec.bridge.cwd,\n timeoutMs: spec.bridge.timeout_ms,\n };\n return new AgentBridgeLLMProvider(bridgeCfg);\n }\n case 'custom':\n return new CustomLLMProvider({\n modulePath: spec.module_path,\n configDir: ctx.configDir,\n options: spec.options,\n });\n }\n}\n\nexport type LLMStage = 'comprehension' | 'script' | 'instrument';\n\nexport interface LLMRouter {\n default: LLMProvider;\n forStage(stage: LLMStage): LLMProvider;\n}\n\nexport interface LLMRouterConfig {\n default: LLMProviderSpec;\n overrides?: Partial<Record<LLMStage, LLMProviderSpec>>;\n}\n\nexport function createLLMRouter(cfg: LLMRouterConfig, ctx: CreateContext): LLMRouter {\n // Lazy: only construct each provider on first access. This lets pipelines\n // that run a subset of stages avoid touching the env vars for providers\n // they don't need. Construction failures (missing env var, custom-module\n // import failure) surface when the stage actually tries to use the LLM.\n let cachedDefault: LLMProvider | undefined;\n const getDefault = (): LLMProvider => {\n if (cachedDefault) return cachedDefault;\n cachedDefault = createLLMProvider(cfg.default, ctx);\n return cachedDefault;\n };\n const overrideFactories = new Map<LLMStage, () => LLMProvider>();\n if (cfg.overrides) {\n for (const [stage, spec] of Object.entries(cfg.overrides) as [LLMStage, LLMProviderSpec | undefined][]) {\n if (!spec) continue;\n let cached: LLMProvider | undefined;\n overrideFactories.set(stage, () => {\n if (cached) return cached;\n cached = createLLMProvider(spec, ctx);\n return cached;\n });\n }\n }\n return {\n get default(): LLMProvider {\n return getDefault();\n },\n forStage(stage: LLMStage): LLMProvider {\n const override = overrideFactories.get(stage);\n return override ? override() : getDefault();\n },\n };\n}\n","import type { PipelineContext } from '../../pipeline/types.js';\nimport type { LLMProvider } from './types.js';\nimport { LLMProviderError } from './types.js';\nimport {\n createLLMRouter,\n type LLMProviderSpec,\n type LLMRouter,\n type LLMStage,\n} from './factory.js';\nimport type { LLMProviderConfig } from '../../config/schema.js';\n\n/**\n * Build the LLM router for the current run. Pulls from `ctx.providers.llm`\n * when set (the pipeline pre-wires it for re-use across stages), otherwise\n * lazily constructs one from `ctx.config.llm` and caches via the WeakMap.\n */\nconst ROUTER_CACHE = new WeakMap<PipelineContext, LLMRouter>();\n\nexport function resolveLLMProviderForStage(\n ctx: PipelineContext,\n stage: LLMStage,\n): LLMProvider {\n const router = getRouter(ctx);\n return router.forStage(stage);\n}\n\nexport function resolveDefaultLLMProvider(\n ctxOrConfigDir: PipelineContext | { configDir: string; llm?: import('../../config/schema.js').LLMConfig },\n): LLMProvider {\n // Convenience overload for `understand` / `instrument` commands that don't\n // have a full PipelineContext on hand — they pass `{ configDir, llm }` instead.\n if ('config' in (ctxOrConfigDir as PipelineContext) && (ctxOrConfigDir as PipelineContext).config) {\n return getRouter(ctxOrConfigDir as PipelineContext).default;\n }\n const standalone = ctxOrConfigDir as { configDir: string; llm?: import('../../config/schema.js').LLMConfig };\n const llm = standalone.llm ?? {\n default: { provider: 'anthropic', model: 'claude-opus-4-7', api_key_env: 'ANTHROPIC_API_KEY' },\n };\n const router = createLLMRouter(toRouterConfig(llm), { configDir: standalone.configDir });\n return router.default;\n}\n\nfunction getRouter(ctx: PipelineContext): LLMRouter {\n const pre = (ctx as PipelineContext & { providers?: { llm?: LLMRouter } }).providers;\n if (pre?.llm) return pre.llm;\n\n const cached = ROUTER_CACHE.get(ctx);\n if (cached) return cached;\n\n // ctx.config.llm gets a schema default, but tests sometimes hand-build ctx\n // without going through loadConfig — fall back to the same default rather\n // than throwing here.\n const llm = ctx.config.llm ?? {\n default: {\n provider: 'anthropic' as const,\n model: 'claude-opus-4-7',\n api_key_env: 'ANTHROPIC_API_KEY',\n },\n };\n const router = createLLMRouter(toRouterConfig(llm), { configDir: ctx.configDir });\n ROUTER_CACHE.set(ctx, router);\n return router;\n}\n\nfunction toRouterConfig(llm: import('../../config/schema.js').LLMConfig): {\n default: LLMProviderSpec;\n overrides?: Partial<Record<LLMStage, LLMProviderSpec>>;\n} {\n return {\n default: configToSpec(llm.default),\n overrides: llm.overrides\n ? {\n ...(llm.overrides.comprehension && {\n comprehension: configToSpec(llm.overrides.comprehension),\n }),\n ...(llm.overrides.script && { script: configToSpec(llm.overrides.script) }),\n ...(llm.overrides.instrument && {\n instrument: configToSpec(llm.overrides.instrument),\n }),\n }\n : undefined,\n };\n}\n\nfunction configToSpec(cfg: LLMProviderConfig): LLMProviderSpec {\n // The config shape and the spec shape are aligned by design — same fields,\n // same discriminator. This adapter exists so callers don't import config\n // types into the factory and vice versa.\n switch (cfg.provider) {\n case 'anthropic':\n return {\n provider: 'anthropic',\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.max_tokens !== undefined && { max_tokens: cfg.max_tokens }),\n };\n case 'openai':\n return {\n provider: 'openai',\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.max_tokens !== undefined && { max_tokens: cfg.max_tokens }),\n ...(cfg.base_url !== undefined && { base_url: cfg.base_url }),\n };\n case 'agent_bridge':\n return {\n provider: 'agent_bridge',\n bridge: cfg.bridge,\n };\n case 'custom':\n return {\n provider: 'custom',\n module_path: cfg.module_path,\n ...(cfg.options !== undefined && { options: cfg.options }),\n };\n }\n}\n","import { mkdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport {\n runLifecycleScript,\n LifecycleScriptError,\n} from '../recording/lifecycle.js';\nimport { recordDemo, type SlicePlan } from '../recording/record.js';\nimport { AuthError } from '../recording/auth.js';\nimport {\n assertEnoughDisk,\n estimateMasterWebmBytes,\n formatBytes,\n getFreeDiskBytes,\n} from '../util/resources.js';\n\nexport const recordStage: Stage = {\n name: 'record',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const videoDir = resolve(ctx.configDir, ctx.config.recording.output_dir);\n const masterPath = resolve(videoDir, 'master.webm');\n const slicePlanPath = resolve(videoDir, 'slice_plan.json');\n\n const masterExists = await fileExists(masterPath);\n const forced = ctx.forced.has('record');\n\n if (masterExists && !forced) {\n logger.event({\n stage: 'record',\n status: 'reusing',\n reason: 'master.webm present',\n path: masterPath,\n });\n return {\n stage: 'record',\n skipped: true,\n reason: 'master.webm already present',\n durationMs: Date.now() - start,\n artifacts: { master_video: masterPath, slice_plan: slicePlanPath },\n };\n }\n\n if (!(await fileExists(manifestPath))) {\n return {\n stage: 'record',\n skipped: true,\n reason: `manifest.json not found at ${manifestPath} — run the script stage first`,\n durationMs: Date.now() - start,\n };\n }\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`record stage: ${err.message}`);\n }\n throw err;\n }\n\n const baseEnv = { SHOWRUNNER_RUN_ID: ctx.runId };\n\n if (ctx.config.recording.state.seed_script) {\n try {\n await runLifecycleScript({\n scriptPath: ctx.config.recording.state.seed_script,\n configDir: ctx.configDir,\n env: baseEnv,\n label: 'seed',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n throw new Error(`record stage: seed script failed — ${err.message}`);\n }\n throw err;\n }\n }\n\n // Preflight: estimate the master.webm size against free disk on the video dir.\n const estimatedWebm = estimateMasterWebmBytes({\n durationSec: manifest.total_duration_seconds,\n width: ctx.config.recording.viewport.width,\n height: ctx.config.recording.viewport.height,\n fps: 25, // Playwright records at 25fps regardless of output.fps\n });\n const headroom = Math.ceil(estimatedWebm * 1.5);\n const freeBytes = await getFreeDiskBytes(videoDir);\n logger.event({\n stage: 'record',\n status: 'preflight',\n free_disk: formatBytes(freeBytes),\n estimated_webm: formatBytes(estimatedWebm),\n required: formatBytes(headroom),\n });\n await assertEnoughDisk(videoDir, headroom, 'record video dir');\n\n let slicePlan: SlicePlan;\n let recordError: unknown;\n try {\n slicePlan = await recordDemo({\n recording: ctx.config.recording,\n voiceover: ctx.config.voiceover,\n manifest,\n configDir: ctx.configDir,\n overrides: ctx.overrides,\n });\n } catch (err) {\n recordError = err;\n slicePlan = {\n recording_path: '',\n recording_started_at: new Date().toISOString(),\n segments: [],\n };\n } finally {\n if (ctx.config.recording.state.teardown_script) {\n try {\n await runLifecycleScript({\n scriptPath: ctx.config.recording.state.teardown_script,\n configDir: ctx.configDir,\n env: {\n ...baseEnv,\n SHOWRUNNER_STATUS: recordError ? 'failure' : 'success',\n },\n label: 'teardown',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n warnings.push(`teardown script failed: ${err.message}`);\n logger.warn(`teardown script failed`, { error: err.message });\n } else {\n throw err;\n }\n }\n }\n }\n\n if (recordError) {\n const cause = recordError instanceof Error ? recordError.message : String(recordError);\n if (recordError instanceof AuthError) {\n throw new Error(\n `record stage: auth failed — ${cause}. If a captured session expired, re-run \\`showrunner capture-auth\\`.`,\n );\n }\n throw new Error(`record stage: ${cause}`);\n }\n\n await mkdir(dirname(slicePlanPath), { recursive: true });\n await writeFile(slicePlanPath, JSON.stringify(slicePlan, null, 2) + '\\n', 'utf8');\n\n const failedSegments = slicePlan.segments.filter((s) => s.status === 'failed');\n for (const s of failedSegments) {\n const tail =\n s.failure_screenshots.length > 0\n ? ` (screenshot: ${s.failure_screenshots.join(', ')})`\n : '';\n warnings.push(`segment ${s.id} failed: ${s.failure_reason ?? 'unknown'}${tail}`);\n }\n\n const allScreenshots = slicePlan.segments.flatMap((s) => s.failure_screenshots);\n\n return {\n stage: 'record',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: {\n master_video: slicePlan.recording_path,\n slice_plan: slicePlanPath,\n },\n warnings,\n meta: {\n segments: slicePlan.segments.length,\n failed_segments: failedSegments.length,\n failure_screenshots: allScreenshots,\n },\n };\n },\n};\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { mkdir, rename } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type BrowserContextOptions,\n} from 'playwright-core';\nimport type { RecordingConfig, VoiceoverConfig } from '../config/schema.js';\nimport type { Manifest } from '../manifest/schema.js';\nimport type { PipelineOverrides } from '../pipeline/types.js';\nimport { findWordStartTime, loadAlignment } from '../manifest/alignment.js';\nimport { logger } from '../util/logger.js';\nimport { buildAuthPlan, type AuthPlan } from './auth.js';\nimport { executeAction } from './actions.js';\nimport {\n ensureCursorInstalled,\n installCursorOverlay,\n moveCursor,\n verifyCursorMounted,\n} from './cursorOverlay.js';\nimport {\n isChainedTarget,\n normalizeSelector,\n resolveSelector,\n type SelectorSpec,\n} from './selector.js';\n\nexport interface RecordOptions {\n recording: RecordingConfig;\n voiceover: VoiceoverConfig;\n manifest: Manifest;\n configDir: string;\n overrides?: PipelineOverrides;\n}\n\nexport interface SegmentSlice {\n id: string;\n t_start: number;\n t_end: number;\n status: 'ok' | 'failed';\n failure_reason?: string;\n failure_screenshots: string[];\n warnings: string[];\n trace_path: string;\n}\n\nexport interface SlicePlan {\n recording_path: string;\n recording_started_at: string;\n segments: SegmentSlice[];\n}\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function recordDemo(opts: RecordOptions): Promise<SlicePlan> {\n const { recording, voiceover, manifest, configDir, overrides } = opts;\n const videoDir = resolve(configDir, recording.output_dir);\n const traceDir = resolve(configDir, recording.trace_dir);\n const failureDir = join(traceDir, 'failures');\n const alignmentDir = resolve(configDir, voiceover.alignment_dir);\n await mkdir(videoDir, { recursive: true });\n await mkdir(traceDir, { recursive: true });\n await mkdir(failureDir, { recursive: true });\n\n const headless = overrides?.headed ? false : recording.headless;\n const authPlan = await buildAuthPlan(recording.auth, configDir);\n const browser = await browserMap[recording.browser].launch({ headless });\n\n try {\n const storageState = await resolveStorageState(browser, recording, authPlan);\n\n const contextOptions: BrowserContextOptions = {\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n recordVideo: {\n dir: videoDir,\n size: { width: recording.viewport.width, height: recording.viewport.height },\n },\n storageState,\n };\n const context = await browser.newContext(contextOptions);\n const tRecordingStart = performance.now();\n if (recording.cursor_highlight) {\n await installCursorOverlay(context);\n }\n await context.tracing.start({ screenshots: true, snapshots: true, sources: true });\n\n const page = await context.newPage();\n if (recording.cursor_highlight) {\n page.on('console', (msg) => {\n const text = msg.text();\n if (text.startsWith('[showrunner-cursor]')) {\n logger.debug(`browser: ${text}`);\n }\n });\n }\n const startedAt = new Date();\n await page.goto(recording.target_url);\n if (recording.cursor_highlight) {\n await ensureCursorInstalled(page);\n const mounted = await verifyCursorMounted(page);\n logger.info(`cursor overlay mount check: ${mounted ? 'OK' : 'NOT FOUND'}`);\n }\n\n if (recording.preflight) {\n await preflightSelectors(page, manifest);\n }\n\n const tFirstSegmentStart = performance.now();\n const preSegmentOffsetSec = (tFirstSegmentStart - tRecordingStart) / 1000;\n logger.info(\n `pre-segment recording offset: ${preSegmentOffsetSec.toFixed(2)}s (page.goto + setup) — slice_plan will be offset by this amount`,\n );\n const t0 = tFirstSegmentStart;\n let cursorPos = {\n x: recording.viewport.width / 2,\n y: recording.viewport.height / 2,\n };\n\n const slices: SegmentSlice[] = [];\n\n for (const seg of manifest.segments) {\n await context.tracing.startChunk({ title: seg.id });\n const segStart = (performance.now() - t0) / 1000;\n const tracePath = join(traceDir, `${seg.id}.zip`);\n const warnings: string[] = [];\n const failureScreenshots: string[] = [];\n let failure: string | undefined;\n let lastTargetSelector: SelectorSpec | undefined;\n\n const alignment = await loadAlignment(join(alignmentDir, `${seg.id}.alignment.json`));\n const resolveAtForAction = (action: { at?: number; at_word?: string; at_occurrence?: number }):\n | number\n | undefined => {\n if (action.at_word) {\n if (!alignment) {\n warnings.push(\n `action references at_word=\"${action.at_word}\" but no alignment data found for segment \"${seg.id}\"`,\n );\n return action.at;\n }\n const t = findWordStartTime(alignment, action.at_word, action.at_occurrence ?? 1);\n if (t == null) {\n warnings.push(\n `at_word=\"${action.at_word}\" (occurrence ${action.at_occurrence ?? 1}) not found in VO of segment \"${seg.id}\"`,\n );\n return action.at;\n }\n return t;\n }\n return action.at;\n };\n\n logger.event({ stage: 'record', status: 'segment_start', segment: seg.id, t: segStart });\n\n let actionIndex = -1;\n for (const action of seg.actions) {\n actionIndex++;\n const resolvedAt = resolveAtForAction(action);\n const hasAt = resolvedAt !== undefined;\n const hasSelector =\n 'selector' in action &&\n (typeof action.selector === 'string' || Array.isArray(action.selector));\n const actionSelector: SelectorSpec | undefined = hasSelector\n ? (action as { selector: SelectorSpec }).selector\n : undefined;\n const chainSameTarget = isChainedTarget(\n lastTargetSelector,\n actionSelector,\n recording.cursor_chain_mode,\n );\n let preMovedCursor = false;\n\n if (hasAt && hasSelector && recording.cursor_highlight && !chainSameTarget) {\n const sel = actionSelector!;\n let box: { x: number; y: number; width: number; height: number } | null = null;\n try {\n const locator = await resolveSelector(page, sel, { timeoutMs: 2000 });\n box = await locator.boundingBox({ timeout: 2000 });\n } catch {\n box = null;\n }\n if (box) {\n const targetX = box.x + box.width / 2;\n const targetY = box.y + box.height / 2;\n const distance = Math.hypot(targetX - cursorPos.x, targetY - cursorPos.y);\n const speedFactor = recording.cursor_speed_factor;\n const rawMs = (180 + 0.18 * distance) / speedFactor;\n let motionMs = Math.min(\n recording.cursor_max_motion_ms,\n Math.max(recording.cursor_min_motion_ms, rawMs),\n );\n\n const arrivalAt = resolvedAt!;\n const elapsedNow = (performance.now() - t0) / 1000 - segStart;\n let timeAvailableUntilArrival = arrivalAt - elapsedNow;\n\n if (timeAvailableUntilArrival * 1000 < motionMs) {\n const adjusted = Math.max(\n recording.cursor_min_motion_ms,\n Math.round(timeAvailableUntilArrival * 1000),\n );\n if (adjusted < motionMs) {\n warnings.push(\n `cursor motion for action at ${arrivalAt}s clamped from ${Math.round(motionMs)}ms to ${adjusted}ms — manifest timing tight`,\n );\n }\n motionMs = adjusted;\n timeAvailableUntilArrival = motionMs / 1000;\n }\n\n const motionStartAt = arrivalAt - motionMs / 1000;\n const waitMs = Math.round((motionStartAt - elapsedNow) * 1000);\n if (waitMs > 20) {\n await page.waitForTimeout(waitMs);\n }\n await moveCursor(page, targetX, targetY, motionMs);\n cursorPos = { x: targetX, y: targetY };\n preMovedCursor = true;\n\n const elapsedAfterMove = (performance.now() - t0) / 1000 - segStart;\n const remainingToArrival = arrivalAt - elapsedAfterMove;\n if (remainingToArrival > 0.02) {\n await page.waitForTimeout(Math.round(remainingToArrival * 1000));\n }\n if (recording.cursor_post_arrival_ms > 0) {\n await page.waitForTimeout(recording.cursor_post_arrival_ms);\n }\n } else {\n const elapsedInSeg = (performance.now() - t0) / 1000 - segStart;\n const waitFor = resolvedAt! - elapsedInSeg;\n if (waitFor > 0.02) await page.waitForTimeout(Math.round(waitFor * 1000));\n }\n } else if (hasAt) {\n // chained same-target action, or no-selector action: just wait until at, no cursor ceremony\n const elapsedInSeg = (performance.now() - t0) / 1000 - segStart;\n const waitFor = resolvedAt! - elapsedInSeg;\n if (waitFor > 0.02) await page.waitForTimeout(Math.round(waitFor * 1000));\n if (chainSameTarget) preMovedCursor = true;\n }\n if (actionSelector) lastTargetSelector = actionSelector;\n\n const fireT = (performance.now() - t0) / 1000 - segStart;\n logger.debug(\n `action fire: seg=${seg.id} type=${action.type} resolvedAt=${\n resolvedAt !== undefined ? resolvedAt.toFixed(2) : 'none'\n } elapsed=${fireT.toFixed(2)} chain=${chainSameTarget}`,\n );\n const outcome = await executeAction(page, action, {\n cursorEnabled: recording.cursor_highlight,\n skipCursorPositioning: preMovedCursor,\n failureDir,\n segmentId: seg.id,\n actionIndex,\n });\n if (outcome.status === 'skipped') {\n warnings.push(`${action.type}: ${outcome.reason}`);\n if (outcome.screenshot) failureScreenshots.push(outcome.screenshot);\n logger.warn(`segment ${seg.id} — ${action.type} skipped`, {\n reason: outcome.reason,\n screenshot: outcome.screenshot,\n });\n } else if (outcome.status === 'segment_failed') {\n failure = outcome.reason;\n if (outcome.screenshot) failureScreenshots.push(outcome.screenshot);\n logger.error(`segment ${seg.id} — failed`, {\n reason: outcome.reason,\n screenshot: outcome.screenshot,\n });\n break;\n }\n }\n\n if (recording.segment_buffer_ms > 0) {\n await page.waitForTimeout(recording.segment_buffer_ms);\n }\n\n const allocated = seg.end - seg.start;\n const elapsedInSegment = (performance.now() - t0) / 1000 - segStart;\n const remaining = allocated - elapsedInSegment;\n if (remaining > 0.05) {\n await page.waitForTimeout(Math.round(remaining * 1000));\n } else if (remaining < -0.5) {\n warnings.push(\n `segment took ${elapsedInSegment.toFixed(2)}s but only ${allocated.toFixed(2)}s allocated — manifest timing tight for this segment`,\n );\n }\n\n const segEnd = (performance.now() - t0) / 1000;\n await context.tracing.stopChunk({ path: tracePath });\n\n slices.push({\n id: seg.id,\n t_start: segStart + preSegmentOffsetSec,\n t_end: segEnd + preSegmentOffsetSec,\n status: failure ? 'failed' : 'ok',\n failure_reason: failure,\n failure_screenshots: failureScreenshots,\n warnings,\n trace_path: tracePath,\n });\n\n logger.event({\n stage: 'record',\n status: 'segment_end',\n segment: seg.id,\n t: segEnd,\n outcome: failure ? 'failed' : 'ok',\n warnings: warnings.length,\n });\n }\n\n const videoHandle = page.video();\n await context.close();\n\n let recordingPath = '';\n if (videoHandle) {\n const original = await videoHandle.path();\n const dest = join(videoDir, 'master.webm');\n if (original !== dest) {\n await rename(original, dest);\n }\n recordingPath = dest;\n } else {\n logger.warn('Recording context did not produce a video file — recordVideo may have been ignored');\n }\n\n return {\n recording_path: recordingPath,\n recording_started_at: startedAt.toISOString(),\n segments: slices,\n };\n } finally {\n await browser.close();\n }\n}\n\nasync function resolveStorageState(\n browser: Browser,\n recording: RecordingConfig,\n authPlan: AuthPlan,\n): Promise<BrowserContextOptions['storageState']> {\n if (authPlan.storageState !== undefined) {\n return authPlan.storageState;\n }\n if (!authPlan.postLaunch) {\n return undefined;\n }\n\n logger.info('Running auth setup off-camera before recording');\n const authContext: BrowserContext = await browser.newContext({\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n });\n try {\n const authPage = await authContext.newPage();\n await authPage.goto(recording.target_url);\n await authPlan.postLaunch(authPage);\n return await authContext.storageState();\n } finally {\n await authContext.close();\n }\n}\n\nexport class PreflightError extends Error {\n override readonly name = 'PreflightError';\n constructor(\n readonly failures: { segment: string; actionIndex: number; selectors: string[] }[],\n ) {\n const lines = failures.map(\n (f) => ` - ${f.segment}#${f.actionIndex} → [${f.selectors.join(' | ')}]`,\n );\n super(\n `Pre-flight check failed — ${failures.length} selector(s) did not resolve on ${\n failures[0]?.segment ? `the live target page` : 'the page'\n }:\\n${lines.join('\\n')}\\n\\nFix the manifest selectors, or set recording.preflight: false to skip this check.`,\n );\n }\n}\n\n/**\n * Pre-flight checks the *first segment's* selector-bearing actions against the\n * just-loaded target page. This catches the common \"URL changed / page didn't\n * load / class renamed\" failure modes without false-positiving on selectors that\n * only become available after intermediate navigations or clicks. Deeper\n * selectors fail at action time with the resolver's full diagnostic.\n */\nasync function preflightSelectors(page: import('playwright-core').Page, manifest: Manifest): Promise<void> {\n const firstSeg = manifest.segments[0];\n if (!firstSeg) return;\n\n // Give SPAs a beat to hydrate before probing — best-effort.\n try {\n await page.waitForLoadState('networkidle', { timeout: 3000 });\n } catch {\n // pages with long-poll connections never reach networkidle; carry on\n }\n\n const checks: { segment: string; actionIndex: number; sel: SelectorSpec }[] = [];\n for (let i = 0; i < firstSeg.actions.length; i++) {\n const a = firstSeg.actions[i]!;\n if ('selector' in a && a.selector !== undefined) {\n checks.push({ segment: firstSeg.id, actionIndex: i, sel: a.selector as SelectorSpec });\n }\n }\n\n const failures: { segment: string; actionIndex: number; selectors: string[] }[] = [];\n for (const c of checks) {\n const candidates = normalizeSelector(c.sel);\n let resolved = false;\n for (const cand of candidates) {\n try {\n await page.locator(cand).first().waitFor({ state: 'attached', timeout: 3000 });\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved) {\n failures.push({ segment: c.segment, actionIndex: c.actionIndex, selectors: candidates });\n }\n }\n\n if (failures.length > 0) {\n throw new PreflightError(failures);\n }\n logger.info('pre-flight selector check: first-segment anchors resolved', {\n checks: checks.length,\n });\n}\n","import { readFile } from 'node:fs/promises';\n\nexport interface CharacterAlignment {\n characters: string[];\n character_start_times_seconds: number[];\n character_end_times_seconds: number[];\n}\n\nexport async function loadAlignment(path: string): Promise<CharacterAlignment | null> {\n try {\n const raw = await readFile(path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<CharacterAlignment>;\n if (\n Array.isArray(parsed.characters) &&\n Array.isArray(parsed.character_start_times_seconds) &&\n Array.isArray(parsed.character_end_times_seconds)\n ) {\n return parsed as CharacterAlignment;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Locate the start-time (relative to the segment's audio start) of a target word\n * within the synthesized VO. Returns null if alignment is missing, the word can't\n * be found, or the requested occurrence doesn't exist.\n */\nexport function findWordStartTime(\n alignment: CharacterAlignment,\n word: string,\n occurrence: number = 1,\n): number | null {\n if (!word || occurrence < 1) return null;\n const haystack = alignment.characters.join('').toLowerCase();\n const target = word.toLowerCase();\n const wordBoundary = /\\w/.test(target[0]!) || /\\w/.test(target[target.length - 1]!);\n const escaped = target.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = wordBoundary\n ? new RegExp(`(?<![a-z0-9])${escaped}(?![a-z0-9])`, 'g')\n : new RegExp(escaped, 'g');\n\n let found = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(haystack)) !== null) {\n found++;\n if (found === occurrence) {\n const charIdx = match.index;\n const t = alignment.character_start_times_seconds[charIdx];\n return typeof t === 'number' ? t : null;\n }\n if (match.index === pattern.lastIndex) pattern.lastIndex++; // empty-match guard\n }\n return null;\n}\n","import { readFile } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { Page, BrowserContextOptions } from 'playwright-core';\n\ntype StorageState = BrowserContextOptions['storageState'];\nimport type { AuthConfig } from '../config/schema.js';\nimport { logger } from '../util/logger.js';\n\nexport class AuthError extends Error {\n override readonly name = 'AuthError';\n}\n\nexport interface AuthPlan {\n storageState?: StorageState;\n postLaunch?: (page: Page) => Promise<void>;\n}\n\nexport async function buildAuthPlan(\n auth: AuthConfig | undefined,\n configDir: string,\n): Promise<AuthPlan> {\n if (!auth) return {};\n\n if (auth.type === 'setup_script') {\n return { postLaunch: await loadSetupScript(auth.path, configDir) };\n }\n\n if (auth.type === 'session') {\n return { storageState: await buildStorageState(auth.cookies_file, auth.local_storage_file, configDir) };\n }\n\n if (auth.type === 'form') {\n return { postLaunch: buildFormFill(auth) };\n }\n\n return {};\n}\n\nasync function loadSetupScript(\n scriptPath: string,\n configDir: string,\n): Promise<(page: Page) => Promise<void>> {\n const abs = isAbsolute(scriptPath) ? scriptPath : resolve(configDir, scriptPath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(abs).href)) as { default?: unknown };\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to load setup_script at ${abs}: ${cause}`);\n }\n if (typeof mod.default !== 'function') {\n throw new AuthError(\n `setup_script at ${abs} must default-export an async function (page: Page) => Promise<void>`,\n );\n }\n const fn = mod.default as (page: Page) => Promise<void>;\n return async (page) => {\n try {\n await fn(page);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`setup_script failed: ${cause}`);\n }\n };\n}\n\nasync function buildStorageState(\n cookiesFile: string,\n localStorageFile: string | undefined,\n configDir: string,\n): Promise<StorageState> {\n const cookiesAbs = isAbsolute(cookiesFile) ? cookiesFile : resolve(configDir, cookiesFile);\n let cookiesRaw: string;\n try {\n cookiesRaw = await readFile(cookiesAbs, 'utf8');\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to read cookies_file at ${cookiesAbs}: ${cause}`);\n }\n let cookiesJson: unknown;\n try {\n cookiesJson = JSON.parse(cookiesRaw);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Invalid JSON in cookies_file ${cookiesAbs}: ${cause}`);\n }\n\n if (!isPlaywrightStorageState(cookiesJson)) {\n throw new AuthError(\n `cookies_file at ${cookiesAbs} is not in Playwright storageState format (expected { cookies: [...], origins: [...] })`,\n );\n }\n\n if (localStorageFile) {\n const lsAbs = isAbsolute(localStorageFile)\n ? localStorageFile\n : resolve(configDir, localStorageFile);\n try {\n const lsRaw = await readFile(lsAbs, 'utf8');\n const lsJson = JSON.parse(lsRaw) as unknown;\n if (isOriginsList(lsJson)) {\n cookiesJson.origins = [...(cookiesJson.origins ?? []), ...lsJson];\n } else {\n logger.warn(\n `local_storage_file at ${lsAbs} is not a Playwright origins list — skipping. Use storageState() output format.`,\n );\n }\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(`Failed to read local_storage_file at ${lsAbs}: ${cause}`);\n }\n }\n\n return cookiesJson as StorageState;\n}\n\ninterface PlaywrightStorageState {\n cookies?: unknown[];\n origins?: unknown[];\n}\n\nfunction isPlaywrightStorageState(value: unknown): value is PlaywrightStorageState {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n return Array.isArray(v['cookies']) || Array.isArray(v['origins']);\n}\n\nfunction isOriginsList(value: unknown): value is unknown[] {\n return Array.isArray(value);\n}\n\nfunction buildFormFill(\n auth: Extract<AuthConfig, { type: 'form' }>,\n): (page: Page) => Promise<void> {\n return async (page) => {\n const email = process.env[auth.fields.email.env];\n const password = process.env[auth.fields.password.env];\n if (!email) {\n throw new AuthError(\n `Form auth: env var ${auth.fields.email.env} is not set`,\n );\n }\n if (!password) {\n throw new AuthError(\n `Form auth: env var ${auth.fields.password.env} is not set`,\n );\n }\n await page.goto(auth.login_url);\n await page.fill(auth.fields.email.selector, email);\n await page.fill(auth.fields.password.selector, password);\n await page.click(auth.submit_selector);\n try {\n await page.waitForURL(auth.success_url_pattern, { timeout: auth.timeout_ms });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new AuthError(\n `Form auth: did not reach ${auth.success_url_pattern} within ${auth.timeout_ms}ms — ${cause}`,\n );\n }\n };\n}\n","import { mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { errors as playwrightErrors, type Page } from 'playwright-core';\nimport type { Action } from '../manifest/schema.js';\nimport { moveCursor, pulseCursor } from './cursorOverlay.js';\nimport { resolveSelector } from './selector.js';\n\nexport type ActionOutcome =\n | { status: 'ok' }\n | { status: 'skipped'; reason: string; screenshot?: string }\n | { status: 'segment_failed'; reason: string; screenshot?: string };\n\nexport class SegmentFailedError extends Error {\n override readonly name = 'SegmentFailedError';\n}\n\nconst CURSOR_SETTLE_MS = 280;\n\nexport interface ExecuteOptions {\n cursorEnabled: boolean;\n skipCursorPositioning?: boolean;\n /** When set, on-error screenshots will be written under this directory. */\n failureDir?: string;\n /** Owning segment id, used in the screenshot filename. */\n segmentId?: string;\n /** Index of the action inside the segment, used in the screenshot filename. */\n actionIndex?: number;\n}\n\nexport async function executeAction(\n page: Page,\n action: Action,\n opts: ExecuteOptions = { cursorEnabled: false },\n): Promise<ActionOutcome> {\n try {\n if (opts.cursorEnabled && !opts.skipCursorPositioning) {\n await positionCursorForAction(page, action);\n }\n switch (action.type) {\n case 'idle':\n return { status: 'ok' };\n case 'click': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.click();\n return { status: 'ok' };\n }\n case 'fill': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.fill(action.value);\n return { status: 'ok' };\n }\n case 'type': {\n if (opts.cursorEnabled) await pulseCursor(page);\n const locator = await resolveSelector(page, action.selector);\n await locator.pressSequentially(action.value, { delay: 60 });\n return { status: 'ok' };\n }\n case 'hover': {\n const locator = await resolveSelector(page, action.selector);\n await locator.hover();\n return { status: 'ok' };\n }\n case 'scroll': {\n const direction = action.direction;\n const locator = await resolveSelector(page, action.selector);\n await locator.evaluate((el, dir) => {\n const node = el as unknown as { scrollTop: number; scrollHeight: number };\n node.scrollTop = dir === 'down' ? node.scrollHeight : -node.scrollHeight;\n }, direction);\n return { status: 'ok' };\n }\n case 'navigate':\n await page.goto(action.url);\n return { status: 'ok' };\n case 'wait_for': {\n const locator = await resolveSelector(page, action.selector);\n await locator.waitFor({ state: 'attached' });\n return { status: 'ok' };\n }\n case 'wait_for_url':\n await page.waitForURL(action.pattern);\n return { status: 'ok' };\n case 'wait':\n await page.waitForTimeout(action.ms);\n return { status: 'ok' };\n case 'assert_visible': {\n const locator = await resolveSelector(page, action.selector, { state: 'visible' });\n await locator.waitFor({ state: 'visible' });\n return { status: 'ok' };\n }\n case 'press':\n if (opts.cursorEnabled) await pulseCursor(page);\n if (action.selector) {\n const locator = await resolveSelector(page, action.selector);\n await locator.press(action.key);\n } else {\n await page.keyboard.press(action.key);\n }\n return { status: 'ok' };\n case 'custom':\n await page.evaluate(action.js);\n return { status: 'ok' };\n }\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n const screenshot = await captureFailureScreenshot(page, opts, action.type);\n\n if (action.type === 'assert_visible') {\n return {\n status: 'segment_failed',\n reason: `assert_visible failed: ${reason}`,\n screenshot,\n };\n }\n\n if (err instanceof playwrightErrors.TimeoutError) {\n return { status: 'skipped', reason: `timeout on ${action.type}: ${reason}`, screenshot };\n }\n\n return { status: 'skipped', reason: `${action.type} error: ${reason}`, screenshot };\n }\n}\n\nasync function captureFailureScreenshot(\n page: Page,\n opts: ExecuteOptions,\n actionType: string,\n): Promise<string | undefined> {\n if (!opts.failureDir || !opts.segmentId) return undefined;\n const idx = opts.actionIndex ?? 0;\n const path = join(opts.failureDir, `${opts.segmentId}-${idx}-${actionType}.png`);\n try {\n await mkdir(dirname(path), { recursive: true });\n await page.screenshot({ path, fullPage: false });\n return path;\n } catch {\n return undefined;\n }\n}\n\nasync function positionCursorForAction(page: Page, action: Action): Promise<void> {\n if (!('selector' in action) || !action.selector) return;\n try {\n const locator = await resolveSelector(page, action.selector, { timeoutMs: 2000 });\n const box = await locator.boundingBox({ timeout: 2000 });\n if (!box) return;\n const x = box.x + box.width / 2;\n const y = box.y + box.height / 2;\n await moveCursor(page, x, y);\n await page.waitForTimeout(CURSOR_SETTLE_MS);\n } catch {\n // selector might not exist yet; cursor stays where it was\n }\n}\n","import type { BrowserContext, Page } from 'playwright-core';\n\nconst CURSOR_INIT_SCRIPT = `\n(() => {\n if (window.__showrunnerCursorInstalled) return;\n console.log('[showrunner-cursor] boot');\n\n const tryInstall = () => {\n if (window.__showrunnerCursorInstalled) return true;\n if (!document.body || !document.head) return false;\n\n const style = document.createElement('style');\n style.textContent = \\`\n @keyframes sr-cursor-pulse-kf {\n 0% { transform: scale(1); opacity: 0.9; }\n 100% { transform: scale(2.6); opacity: 0; }\n }\n #showrunner-cursor {\n position: fixed !important;\n left: 50vw;\n top: 50vh;\n width: 28px !important;\n height: 28px !important;\n margin-left: -14px !important;\n margin-top: -14px !important;\n pointer-events: none !important;\n z-index: 2147483647 !important;\n transition: left 240ms cubic-bezier(0.42, 0, 0.58, 1),\n top 240ms cubic-bezier(0.42, 0, 0.58, 1);\n display: block !important;\n opacity: 1 !important;\n visibility: visible !important;\n }\n #showrunner-cursor .sr-cursor-dot {\n width: 28px !important;\n height: 28px !important;\n border-radius: 50% !important;\n background: rgba(255, 60, 60, 0.85) !important;\n box-shadow: 0 0 0 3px rgba(255, 60, 60, 1),\n 0 0 0 6px rgba(255, 255, 255, 0.6),\n 0 4px 18px rgba(0, 0, 0, 0.45) !important;\n }\n #showrunner-cursor .sr-cursor-ring {\n position: absolute !important;\n inset: 0 !important;\n border-radius: 50% !important;\n border: 4px solid rgba(255, 60, 60, 0.9) !important;\n opacity: 0;\n pointer-events: none !important;\n }\n #showrunner-cursor.sr-cursor-pulse .sr-cursor-ring {\n animation: sr-cursor-pulse-kf 420ms ease-out;\n }\n \\`;\n document.head.appendChild(style);\n\n const cursor = document.createElement('div');\n cursor.id = 'showrunner-cursor';\n const dot = document.createElement('div');\n dot.className = 'sr-cursor-dot';\n const ring = document.createElement('div');\n ring.className = 'sr-cursor-ring';\n cursor.appendChild(dot);\n cursor.appendChild(ring);\n document.body.appendChild(cursor);\n\n window.__showrunnerCursorInstalled = true;\n console.log('[showrunner-cursor] mounted');\n return true;\n };\n\n if (tryInstall()) return;\n\n console.log('[showrunner-cursor] deferring — body not ready');\n\n const tick = () => { if (tryInstall()) cleanup(); };\n const observer = new MutationObserver(tick);\n const target = document.documentElement || document;\n observer.observe(target, { childList: true, subtree: true });\n const interval = setInterval(tick, 50);\n const onReady = () => tick();\n document.addEventListener('DOMContentLoaded', onReady);\n document.addEventListener('readystatechange', onReady);\n const cleanup = () => {\n observer.disconnect();\n clearInterval(interval);\n document.removeEventListener('DOMContentLoaded', onReady);\n document.removeEventListener('readystatechange', onReady);\n };\n})();\n`;\n\nexport async function installCursorOverlay(context: BrowserContext): Promise<void> {\n await context.addInitScript(CURSOR_INIT_SCRIPT);\n}\n\nexport async function ensureCursorInstalled(page: Page): Promise<void> {\n try {\n await page.evaluate(CURSOR_INIT_SCRIPT);\n } catch {\n // best effort\n }\n}\n\nexport async function verifyCursorMounted(page: Page): Promise<boolean> {\n try {\n return await page.evaluate(() => {\n const doc = (globalThis as unknown as { document?: { getElementById: (id: string) => unknown } })\n .document;\n return Boolean(doc && doc.getElementById('showrunner-cursor'));\n });\n } catch {\n return false;\n }\n}\n\ninterface CursorElement {\n style: { left: string; top: string };\n classList: { add: (c: string) => void; remove: (c: string) => void };\n offsetWidth: number;\n}\ninterface CursorDoc {\n getElementById: (id: string) => CursorElement | null;\n}\n\ninterface CursorElementWithTransition extends CursorElement {\n style: { left: string; top: string; transition: string };\n}\ninterface CursorDocWithTransition {\n getElementById: (id: string) => CursorElementWithTransition | null;\n}\n\n// easeInOutCubic: pronounced ease at both ends, fast through the middle.\n// cubic-bezier(0.42, 0, 0.58, 1) — much more dramatic than Material's standard curve.\nconst CURSOR_EASE = 'cubic-bezier(0.42, 0, 0.58, 1)';\n\nexport async function moveCursor(\n page: Page,\n x: number,\n y: number,\n motionMs?: number,\n): Promise<void> {\n try {\n await page.evaluate(\n ({ x: cx, y: cy, ms, ease }) => {\n const doc = (globalThis as unknown as { document?: CursorDocWithTransition }).document;\n const el = doc?.getElementById('showrunner-cursor');\n if (!el) return;\n const duration = typeof ms === 'number' && ms > 0 ? ms : 240;\n el.style.transition = `left ${duration}ms ${ease}, top ${duration}ms ${ease}`;\n el.style.left = cx + 'px';\n el.style.top = cy + 'px';\n },\n { x, y, ms: motionMs, ease: CURSOR_EASE },\n );\n } catch {\n // page closed or eval failed — cursor is best-effort\n }\n}\n\nexport async function pulseCursor(page: Page): Promise<void> {\n try {\n await page.evaluate(() => {\n const doc = (globalThis as unknown as { document?: CursorDoc }).document;\n const el = doc?.getElementById('showrunner-cursor');\n if (el) {\n el.classList.remove('sr-cursor-pulse');\n void el.offsetWidth;\n el.classList.add('sr-cursor-pulse');\n }\n });\n } catch {\n // ignore\n }\n}\n","import type { Locator, Page } from 'playwright-core';\nimport type { SelectorSpec } from '../manifest/schema.js';\n\nexport type { SelectorSpec } from '../manifest/schema.js';\n\nexport class SelectorResolutionError extends Error {\n override readonly name = 'SelectorResolutionError';\n constructor(\n readonly tried: string[],\n cause: string,\n ) {\n super(`None of [${tried.join(' | ')}] resolved: ${cause}`);\n }\n}\n\nexport function normalizeSelector(sel: SelectorSpec): string[] {\n return Array.isArray(sel) ? sel : [sel];\n}\n\nexport interface ResolveOptions {\n timeoutMs?: number;\n state?: 'attached' | 'visible';\n}\n\nexport async function resolveSelector(\n page: Page,\n sel: SelectorSpec,\n opts: ResolveOptions = {},\n): Promise<Locator> {\n const timeout = opts.timeoutMs ?? 5000;\n const state = opts.state ?? 'attached';\n const candidates = normalizeSelector(sel);\n const errors: string[] = [];\n for (const candidate of candidates) {\n const locator = page.locator(candidate).first();\n try {\n await locator.waitFor({ state, timeout });\n return locator;\n } catch (err) {\n errors.push(`${candidate}: ${err instanceof Error ? err.message.split('\\n')[0] : String(err)}`);\n }\n }\n throw new SelectorResolutionError(candidates, errors.join(' ; '));\n}\n\n/**\n * Heuristic chain detection. In 'strict' mode, only exact equality counts.\n * In 'smart' mode, also treat as chained when:\n * - selectors share a `[name=\"...\"]` or `[data-testid=\"...\"]` attribute literal,\n * - one selector string is a prefix of the other (e.g. `form input` vs `form input[name=email]`).\n * Selector arrays are reduced to their first entry for comparison — the resolver\n * picks the first match at runtime, so first-entry equivalence is the load-bearing signal.\n */\nexport function isChainedTarget(\n prev: SelectorSpec | undefined,\n cur: SelectorSpec | undefined,\n mode: 'strict' | 'smart',\n): boolean {\n if (prev === undefined || cur === undefined) return false;\n const prevFirst = normalizeSelector(prev)[0]!;\n const curFirst = normalizeSelector(cur)[0]!;\n if (prevFirst === curFirst) return true;\n if (mode === 'strict') return false;\n\n const attrMatch = (a: string, b: string, attr: 'name' | 'data-testid'): boolean => {\n const re = new RegExp(`\\\\[${attr}=[\"']([^\"']+)[\"']\\\\]`);\n const ma = re.exec(a);\n const mb = re.exec(b);\n return ma !== null && mb !== null && ma[1] === mb[1];\n };\n if (attrMatch(prevFirst, curFirst, 'name')) return true;\n if (attrMatch(prevFirst, curFirst, 'data-testid')) return true;\n if (prevFirst.startsWith(curFirst) || curFirst.startsWith(prevFirst)) return true;\n return false;\n}\n","import { cpus, freemem, totalmem } from 'node:os';\nimport { statfs } from 'node:fs/promises';\nimport { logger } from './logger.js';\n\nexport class ResourceError extends Error {\n override readonly name = 'ResourceError';\n constructor(\n message: string,\n readonly kind: 'disk' | 'memory',\n ) {\n super(message);\n }\n}\n\nconst MB = 1024 * 1024;\nconst GB = 1024 * MB;\nconst SAFETY_FLOOR_BYTES = 500 * MB;\n\nexport function getFreeMemoryBytes(): number {\n return freemem();\n}\n\nexport function getTotalMemoryBytes(): number {\n return totalmem();\n}\n\n/**\n * Free disk space at `path` in bytes. Returns Infinity on filesystems that\n * don't support statfs (network mounts, some Windows configurations).\n */\nexport async function getFreeDiskBytes(path: string): Promise<number> {\n try {\n const stats = await statfs(path);\n return stats.bavail * stats.bsize;\n } catch {\n return Infinity;\n }\n}\n\nexport interface ThreadCapOptions {\n width: number;\n height: number;\n fps: number;\n quality: 'draft' | 'standard' | 'high';\n freeMemBytes: number;\n}\n\n/**\n * libx264 working set ≈ frame buffer (W*H*1.5 bytes for YUV420) × per-thread\n * coefficient × lookahead frames. Quality preset drives lookahead.\n * draft → veryfast → ~10 lookahead frames\n * standard → medium → ~25 lookahead frames\n * high → slow → ~50 lookahead frames\n * Cap at the CPU count. Operator escape hatch: SHOWRUNNER_FFMPEG_THREADS env.\n */\nexport function computeThreadCap(opts: ThreadCapOptions): number {\n const override = process.env['SHOWRUNNER_FFMPEG_THREADS'];\n if (override) {\n const n = parseInt(override, 10);\n if (Number.isFinite(n) && n > 0) return n;\n }\n const cpuCount = Math.max(1, cpus().length);\n const lookaheadByQuality: Record<ThreadCapOptions['quality'], number> = {\n draft: 10,\n standard: 25,\n high: 50,\n };\n const lookahead = lookaheadByQuality[opts.quality];\n const frameBytes = Math.ceil(opts.width * opts.height * 1.5);\n // Per-thread overhead: roughly one frame buffer × lookahead, plus some slack\n const perThreadBytes = frameBytes * lookahead * 1.2;\n const headroom = Math.max(0, opts.freeMemBytes - SAFETY_FLOOR_BYTES);\n if (headroom < perThreadBytes) return 1;\n const capByMemory = Math.floor(headroom / perThreadBytes);\n return Math.max(1, Math.min(cpuCount, capByMemory));\n}\n\nexport interface MasterWebmEstimateOptions {\n durationSec: number;\n width: number;\n height: number;\n fps: number;\n}\n\n/**\n * Conservative size estimate for the master.webm Playwright will record.\n * VP8 in Playwright defaults to ~1 Mbps at 720p and scales with resolution +\n * fps. Used to fail-fast before recording if disk space is too tight.\n */\nexport function estimateMasterWebmBytes(opts: MasterWebmEstimateOptions): number {\n const pixelRate = opts.width * opts.height * opts.fps;\n // Bytes per pixel-frame ≈ 0.1 bits → ~0.0125 bytes\n const bytesPerSec = pixelRate * 0.0125;\n return Math.ceil(bytesPerSec * opts.durationSec);\n}\n\nexport async function assertEnoughDisk(\n targetDir: string,\n minBytes: number,\n label: string,\n): Promise<void> {\n const free = await getFreeDiskBytes(targetDir);\n if (free < minBytes) {\n throw new ResourceError(\n `${label}: insufficient free disk at ${targetDir} — need ~${formatBytes(minBytes)}, found ~${formatBytes(free)}. Free up space or move the project off this filesystem.`,\n 'disk',\n );\n }\n logger.debug(`disk check ok: ${label}`, {\n path: targetDir,\n free_mb: Math.round(free / MB),\n required_mb: Math.round(minBytes / MB),\n });\n}\n\nexport function formatBytes(n: number): string {\n if (!Number.isFinite(n)) return '∞';\n if (n >= GB) return `${(n / GB).toFixed(1)} GB`;\n if (n >= MB) return `${Math.round(n / MB)} MB`;\n return `${Math.round(n / 1024)} KB`;\n}\n","import { mkdir, stat, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport type { Manifest, Segment } from '../manifest/schema.js';\nimport { ffprobeDuration } from '../voiceover/ffmpeg.js';\nimport {\n buildFullScript,\n computeSliceBoundaries,\n loadMasterAlignment,\n locateSegmentWindows,\n masterPaths,\n sliceAlignment,\n sliceMasterAudio,\n writeMasterAlignment,\n type SegmentWindow,\n type SliceBoundary,\n} from '../voiceover/fullVo.js';\nimport {\n resolveAlignmentStrategy,\n resolveElevenLabsConfigOrNull,\n resolveTTSProvider,\n type AlignmentStrategy,\n} from '../providers/tts/resolveFromContext.js';\nimport { TTSProviderError, type TTSProvider } from '../providers/tts/types.js';\nimport type { VoiceoverConfig } from '../config/schema.js';\n\ninterface SegmentArtifact {\n segment_id: string;\n final_path: string;\n natural_duration_seconds: number;\n final_duration_seconds: number;\n target_duration_seconds: number;\n characters_synthesized: number;\n used_speed: number;\n drift_action: 'kept' | 'auto_extended' | 'reused';\n pause_strategy: 'master_slice';\n warnings: string[];\n}\n\nexport const voiceoverStage: Stage = {\n name: 'voiceover',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const stageWarnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const audioDir = resolve(ctx.configDir, ctx.config.voiceover.output_dir);\n const alignmentDir = resolve(ctx.configDir, ctx.config.voiceover.alignment_dir);\n await mkdir(audioDir, { recursive: true });\n await mkdir(alignmentDir, { recursive: true });\n\n if (!(await fileExists(manifestPath))) {\n return {\n stage: 'voiceover',\n skipped: true,\n reason: `manifest.json not found at ${manifestPath} — run the script stage first`,\n durationMs: Date.now() - start,\n };\n }\n\n let manifest: Manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`voiceover stage: ${err.message}`);\n }\n throw err;\n }\n\n const vo = ctx.config.voiceover;\n const elevenSpec = resolveElevenLabsConfigOrNull(ctx);\n const voSpeed = elevenSpec?.speed ?? 1.0;\n const forced = ctx.forced.has('voiceover');\n const tailPaddingSec = vo.tail_padding_ms / 1000;\n const master = masterPaths(audioDir, alignmentDir);\n const alignmentStrategy = resolveAlignmentStrategy(ctx);\n const provider = resolveTTSProvider(ctx);\n\n // Provider doesn't return alignment AND user requires it → fail fast.\n if (!provider.supportsAlignment && alignmentStrategy === 'required') {\n throw new Error(\n `voiceover stage: provider '${provider.name}' does not return alignment data, ` +\n `but voiceover.alignment_strategy is 'required'. Either switch providers (elevenlabs) ` +\n `or set alignment_strategy: best_effort in demo.yaml.`,\n );\n }\n\n // Non-aligned providers take the per-segment fallback path — one TTS call\n // per segment, concatenated. Skips master-alignment work entirely.\n if (!provider.supportsAlignment) {\n return await runBestEffortPath({\n ctx,\n manifest,\n provider,\n audioDir,\n alignmentDir,\n tailPaddingSec,\n forced,\n start,\n manifestPath,\n voSpeed,\n });\n }\n\n // 1. Synthesize the master VO (one TTS call), or reuse cache.\n const masterCached =\n (await fileExists(master.rawAudio)) && (await fileExists(master.alignment));\n if (forced || !masterCached) {\n logger.event({\n stage: 'voiceover',\n status: 'synthesizing_master',\n provider: provider.name,\n segments: manifest.segments.length,\n });\n try {\n const fullText = buildFullScript(manifest.segments);\n const result = await provider.synthesize({ text: fullText });\n if (!result.alignment) {\n // provider.supportsAlignment said true but didn't return any — surface as error.\n throw new TTSProviderError(\n `provider ${provider.name} advertised supportsAlignment but returned no alignment data`,\n provider.name,\n );\n }\n await writeFile(master.rawAudio, result.audio);\n await writeMasterAlignment(master.alignment, result.alignment);\n logger.event({\n stage: 'voiceover',\n status: 'master_written',\n path: master.rawAudio,\n duration: result.durationSeconds.toFixed(2),\n chars: result.charactersSynthesized,\n });\n } catch (err) {\n if (err instanceof TTSProviderError) {\n throw new Error(`voiceover stage: master synthesis failed — ${err.message}`);\n }\n throw err;\n }\n } else {\n logger.event({\n stage: 'voiceover',\n status: 'reusing_master',\n path: master.rawAudio,\n });\n }\n\n // 2. Load master alignment, locate each segment's window.\n const alignment = await loadMasterAlignment(master.alignment);\n if (!alignment) {\n throw new Error(`voiceover stage: failed to load master alignment at ${master.alignment}`);\n }\n let windows: SegmentWindow[];\n try {\n windows = locateSegmentWindows(manifest.segments, alignment);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(`voiceover stage: ${cause}`);\n }\n\n // 3. Compute midpoint boundaries so each segment slice absorbs half of the\n // silence on either side. Concatenating the slices reproduces the master\n // bit-for-bit (modulo ffmpeg re-encode), preserving model-generated pauses.\n const masterDuration = await ffprobeDuration(master.rawAudio);\n const boundaries = computeSliceBoundaries(windows, masterDuration);\n\n // 4. Slice master per segment, write per-segment alignment.\n const artifacts: SegmentArtifact[] = [];\n for (let i = 0; i < manifest.segments.length; i++) {\n const segment = manifest.segments[i]!;\n const window = windows[i]!;\n const boundary = boundaries[i]!;\n try {\n const artifact = await sliceSegmentFromMaster({\n segment,\n window,\n boundary,\n masterAudioPath: master.rawAudio,\n masterAlignment: alignment,\n operatorAllocated: segment.end - segment.start,\n tailPaddingSec,\n audioDir,\n alignmentDir,\n voSpeed,\n });\n artifacts.push(artifact);\n logger.event({\n stage: 'voiceover',\n status: 'segment_sliced',\n segment: segment.id,\n slice_start: boundary.start_sec.toFixed(2),\n slice_end: boundary.end_sec.toFixed(2),\n natural: artifact.natural_duration_seconds.toFixed(2),\n final: artifact.final_duration_seconds.toFixed(2),\n });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(`voiceover stage: segment ${segment.id}: ${cause}`);\n }\n }\n\n // 4. Rewrite manifest timings to reflect actual VO durations.\n const rewritten = rewriteManifestTimings(manifest, artifacts);\n if (rewritten.changed) {\n await writeManifest(manifestPath, rewritten.manifest);\n stageWarnings.push(\n `manifest timings derived from VO: total_duration ${manifest.total_duration_seconds.toFixed(2)}s → ${rewritten.manifest.total_duration_seconds.toFixed(2)}s`,\n );\n logger.event({\n stage: 'voiceover',\n status: 'manifest_rewritten',\n path: manifestPath,\n new_total: rewritten.manifest.total_duration_seconds,\n });\n }\n\n const summaryPath = join(audioDir, 'voiceover_summary.json');\n const totalCharacters = manifest.segments.reduce((acc, s) => acc + s.vo_line.length, 0);\n await writeFile(\n summaryPath,\n JSON.stringify(\n {\n mode: 'full',\n characters_synthesized: totalCharacters,\n tail_padding_ms: vo.tail_padding_ms,\n master_audio: master.rawAudio,\n master_alignment: master.alignment,\n segments: artifacts,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n const artifactsRecord: Record<string, string> = {\n voiceover_summary: summaryPath,\n master_audio: master.rawAudio,\n master_alignment: master.alignment,\n };\n for (const a of artifacts) {\n artifactsRecord[`audio_${a.segment_id}`] = a.final_path;\n }\n\n return {\n stage: 'voiceover',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: artifactsRecord,\n warnings: [...stageWarnings, ...artifacts.flatMap((a) => a.warnings)],\n meta: {\n mode: 'full',\n segments: artifacts.length,\n characters_synthesized: totalCharacters,\n },\n };\n },\n};\n\ninterface SliceSegmentInput {\n segment: Segment;\n window: SegmentWindow;\n boundary: SliceBoundary;\n masterAudioPath: string;\n masterAlignment: import('../manifest/alignment.js').CharacterAlignment;\n operatorAllocated: number;\n tailPaddingSec: number;\n audioDir: string;\n alignmentDir: string;\n voSpeed: number;\n}\n\nasync function sliceSegmentFromMaster(input: SliceSegmentInput): Promise<SegmentArtifact> {\n const {\n segment,\n window,\n boundary,\n masterAudioPath,\n masterAlignment,\n operatorAllocated,\n audioDir,\n alignmentDir,\n voSpeed,\n } = input;\n const warnings: string[] = [];\n\n // The slice covers boundary.start_sec → boundary.end_sec of the master, which\n // includes this segment's speech plus its half-share of inter-segment silence.\n // No debreath, no pause injection — the master already carries natural pauses.\n const finalPath = join(audioDir, `${segment.id}.mp3`);\n await sliceMasterAudio({\n masterPath: masterAudioPath,\n outputPath: finalPath,\n startSec: boundary.start_sec,\n durationSec: boundary.end_sec - boundary.start_sec,\n });\n\n // Per-segment alignment file with segment-mp3 timings (0 = start of the mp3\n // including any leading silence). Both at_word resolution in record.ts and\n // caption emission rely on this coordinate system.\n const segAlignment = sliceAlignment(masterAlignment, window, boundary);\n const alignmentPath = join(alignmentDir, `${segment.id}.alignment.json`);\n await writeFile(alignmentPath, JSON.stringify(segAlignment, null, 2) + '\\n', 'utf8');\n\n const finalDuration = await ffprobeDuration(finalPath);\n const speechDuration = window.end_time_seconds - window.start_time_seconds;\n const driftAction: SegmentArtifact['drift_action'] =\n Math.abs(finalDuration - operatorAllocated) > 0.05 ? 'auto_extended' : 'kept';\n\n return {\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: speechDuration,\n final_duration_seconds: finalDuration,\n target_duration_seconds: finalDuration,\n characters_synthesized: segment.vo_line.length,\n used_speed: voSpeed,\n drift_action: driftAction,\n pause_strategy: 'master_slice',\n warnings,\n };\n}\n\ninterface RewriteResult {\n manifest: Manifest;\n changed: boolean;\n}\n\nfunction rewriteManifestTimings(manifest: Manifest, artifacts: SegmentArtifact[]): RewriteResult {\n const byId = new Map(artifacts.map((a) => [a.segment_id, a]));\n let cursor = 0;\n let changed = false;\n const newSegments = manifest.segments.map((seg) => {\n const a = byId.get(seg.id);\n const allocated = seg.end - seg.start;\n const actual = a?.final_duration_seconds ?? allocated;\n if (Math.abs(actual - allocated) > 0.01 || Math.abs(seg.start - cursor) > 0.01) {\n changed = true;\n }\n const newStart = cursor;\n const newEnd = cursor + actual;\n cursor = newEnd;\n return { ...seg, start: round(newStart), end: round(newEnd) };\n });\n const newTotal = round(cursor);\n if (Math.abs(newTotal - manifest.total_duration_seconds) > 0.01) changed = true;\n return {\n manifest: { ...manifest, segments: newSegments, total_duration_seconds: newTotal },\n changed,\n };\n}\n\nfunction round(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\ninterface BestEffortPathInput {\n ctx: PipelineContext;\n manifest: Manifest;\n provider: TTSProvider;\n audioDir: string;\n alignmentDir: string;\n tailPaddingSec: number;\n forced: boolean;\n start: number;\n manifestPath: string;\n voSpeed: number;\n}\n\n/**\n * Per-segment synthesis fallback for providers that don't return alignment\n * data. One TTS call per segment; no master alignment to slice from. Captions\n * fall back to whole-segment cues (handled in mux/captions.ts), and at_word\n * action timing degrades to action.at (handled in record.ts:resolveAtForAction).\n */\nasync function runBestEffortPath(input: BestEffortPathInput): Promise<StageResult> {\n const { ctx, manifest, provider, audioDir, tailPaddingSec, forced, start, manifestPath, voSpeed } = input;\n void ctx;\n const stageWarnings: string[] = [\n `alignment_strategy=best_effort: provider '${provider.name}' produces no alignment — captions will be whole-segment cues and at_word will degrade to at-time`,\n ];\n logger.warn(stageWarnings[0]!);\n\n const artifacts: SegmentArtifact[] = [];\n let totalCharacters = 0;\n\n for (const segment of manifest.segments) {\n const finalPath = join(audioDir, `${segment.id}.mp3`);\n if ((await fileExists(finalPath)) && !forced) {\n const existingDuration = await ffprobeDuration(finalPath).catch(\n () => segment.end - segment.start,\n );\n artifacts.push({\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: existingDuration,\n final_duration_seconds: existingDuration,\n target_duration_seconds: existingDuration,\n characters_synthesized: 0,\n used_speed: voSpeed,\n drift_action: 'reused',\n pause_strategy: 'master_slice',\n warnings: [],\n });\n logger.event({ stage: 'voiceover', status: 'reusing', segment: segment.id, path: finalPath });\n continue;\n }\n\n logger.event({\n stage: 'voiceover',\n status: 'synthesizing_segment',\n provider: provider.name,\n segment: segment.id,\n });\n const result = await provider.synthesize({ text: segment.vo_line });\n await writeFile(finalPath, result.audio);\n totalCharacters += result.charactersSynthesized;\n const finalDuration = await ffprobeDuration(finalPath);\n artifacts.push({\n segment_id: segment.id,\n final_path: finalPath,\n natural_duration_seconds: result.durationSeconds,\n final_duration_seconds: finalDuration,\n target_duration_seconds: finalDuration + tailPaddingSec,\n characters_synthesized: result.charactersSynthesized,\n used_speed: voSpeed,\n drift_action: 'kept',\n pause_strategy: 'master_slice',\n warnings: [],\n });\n logger.event({\n stage: 'voiceover',\n status: 'segment_complete',\n segment: segment.id,\n duration: finalDuration.toFixed(2),\n });\n }\n\n const rewritten = rewriteManifestTimings(manifest, artifacts);\n if (rewritten.changed) {\n await writeManifest(manifestPath, rewritten.manifest);\n stageWarnings.push(\n `manifest timings derived from per-segment VO: total_duration ${manifest.total_duration_seconds.toFixed(2)}s → ${rewritten.manifest.total_duration_seconds.toFixed(2)}s`,\n );\n }\n\n const summaryPath = join(audioDir, 'voiceover_summary.json');\n await writeFile(\n summaryPath,\n JSON.stringify(\n {\n mode: 'per_segment_best_effort',\n provider: provider.name,\n alignment_available: false,\n characters_synthesized: totalCharacters,\n segments: artifacts,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n const artifactsRecord: Record<string, string> = { voiceover_summary: summaryPath };\n for (const a of artifacts) artifactsRecord[`audio_${a.segment_id}`] = a.final_path;\n\n return {\n stage: 'voiceover',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: artifactsRecord,\n warnings: [...stageWarnings, ...artifacts.flatMap((a) => a.warnings)],\n meta: {\n mode: 'best_effort',\n provider: provider.name,\n alignment_available: false,\n segments: artifacts.length,\n characters_synthesized: totalCharacters,\n },\n };\n}\n","import { spawn } from 'node:child_process';\n\nexport type FfmpegErrorCategory =\n | 'oom'\n | 'no_space'\n | 'codec_missing'\n | 'permission'\n | 'unknown';\n\nexport class FfmpegError extends Error {\n override readonly name = 'FfmpegError';\n readonly category: FfmpegErrorCategory;\n constructor(\n message: string,\n readonly exitCode: number | null,\n readonly stderr: string,\n category?: FfmpegErrorCategory,\n ) {\n super(message);\n this.category = category ?? classifyFfmpegStderr(stderr);\n }\n}\n\n/**\n * Pure classifier — pattern-match common failure modes in ffmpeg/x264 stderr\n * so callers can attach actionable remediation hints.\n */\nexport function classifyFfmpegStderr(stderr: string): FfmpegErrorCategory {\n if (/malloc|out of memory|cannot allocate/i.test(stderr)) return 'oom';\n if (/no space left|ENOSPC|disk full/i.test(stderr)) return 'no_space';\n if (/unknown encoder|encoder not found|libx264 not found/i.test(stderr)) return 'codec_missing';\n if (/EACCES|permission denied/i.test(stderr)) return 'permission';\n return 'unknown';\n}\n\n/**\n * Build an actionable hint to append to an ffmpeg failure message based on its\n * category. Caller injects width/height/workDir context where relevant.\n */\nexport function ffmpegHintFor(\n category: FfmpegErrorCategory,\n ctx?: { width?: number; height?: number; workDir?: string },\n): string {\n switch (category) {\n case 'oom': {\n const cur = ctx?.width && ctx?.height ? ` (currently ${ctx.width}x${ctx.height})` : '';\n return `x264 ran out of working memory${cur}. Try lowering output.resolution to 1280x720, or set SHOWRUNNER_FFMPEG_THREADS=1 to use a single encoder thread.`;\n }\n case 'no_space':\n return `Disk full${ctx?.workDir ? ` at ${ctx.workDir}` : ''}. Free up space and re-run.`;\n case 'codec_missing':\n return `Your ffmpeg build is missing libx264. Reinstall ffmpeg with --enable-libx264 (or via your package manager's \"ffmpeg-full\" variant).`;\n case 'permission':\n return `Permission denied. Check write access on the output directory.`;\n case 'unknown':\n return '';\n }\n}\n\nexport interface RunOptions {\n bin?: string;\n args: string[];\n captureStderr?: boolean;\n /** Inject `-threads N` before the output path. Useful for memory-constrained encodes. */\n threads?: number;\n /** Context for error hint rendering (resolution, work dir). */\n hintContext?: { width?: number; height?: number; workDir?: string };\n}\n\nexport async function runFfmpeg(opts: RunOptions): Promise<{ stderr: string }> {\n const bin = opts.bin ?? 'ffmpeg';\n const args =\n opts.threads !== undefined\n ? injectThreadsArg(opts.args, opts.threads)\n : opts.args;\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(bin, args, { stdio: ['ignore', 'ignore', 'pipe'] });\n let stderr = '';\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code === 0) {\n resolveRun({ stderr });\n } else {\n const category = classifyFfmpegStderr(stderr);\n const hint = ffmpegHintFor(category, opts.hintContext);\n const hintLine = hint ? `\\n→ ${hint}` : '';\n rejectRun(\n new FfmpegError(\n `${bin} exited ${code}${hintLine}\\n${stderr.slice(-2000)}`,\n code,\n stderr,\n category,\n ),\n );\n }\n });\n });\n}\n\n/**\n * Insert `-threads N` immediately before the output path (last arg). Idempotent\n * if the input already contained `-threads`.\n */\nfunction injectThreadsArg(args: string[], threads: number): string[] {\n if (args.includes('-threads')) return args;\n // Output path is conventionally the last positional arg in ffmpeg invocations.\n return [...args.slice(0, -1), '-threads', String(threads), args[args.length - 1]!];\n}\n\n/**\n * Get the duration of an audio buffer by piping it through ffprobe via stdin.\n * Avoids the tmpfile dance for short clips returned directly from a TTS API.\n */\nexport async function ffprobeDurationFromStdin(buf: Buffer): Promise<number> {\n const bin = 'ffprobe';\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(\n bin,\n ['-i', 'pipe:0', '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv=p=0'],\n { stdio: ['pipe', 'pipe', 'pipe'] },\n );\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code !== 0) {\n rejectRun(new FfmpegError(`${bin} exited ${code}: ${stderr.slice(-500)}`, code, stderr));\n return;\n }\n const trimmed = stdout.trim();\n const n = Number.parseFloat(trimmed);\n if (Number.isNaN(n)) {\n rejectRun(new FfmpegError(`${bin} returned unparseable duration: ${trimmed}`, code, stderr));\n } else {\n resolveRun(n);\n }\n });\n child.stdin.write(buf);\n child.stdin.end();\n });\n}\n\nexport async function ffprobeDuration(path: string): Promise<number> {\n const bin = 'ffprobe';\n return await new Promise((resolveRun, rejectRun) => {\n const child = spawn(\n bin,\n ['-i', path, '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv=p=0'],\n { stdio: ['ignore', 'pipe', 'pipe'] },\n );\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (err) => {\n rejectRun(new FfmpegError(`Failed to spawn ${bin}: ${err.message}`, null, stderr));\n });\n child.on('exit', (code) => {\n if (code !== 0) {\n rejectRun(new FfmpegError(`${bin} exited ${code}: ${stderr.slice(-500)}`, code, stderr));\n return;\n }\n const trimmed = stdout.trim();\n const n = Number.parseFloat(trimmed);\n if (Number.isNaN(n)) {\n rejectRun(new FfmpegError(`${bin} returned unparseable duration: ${trimmed}`, code, stderr));\n } else {\n resolveRun(n);\n }\n });\n });\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { logger } from '../util/logger.js';\nimport { runFfmpeg } from './ffmpeg.js';\nimport type { Segment } from '../manifest/schema.js';\nimport type { CharacterAlignment } from '../manifest/alignment.js';\n\nexport interface SegmentWindow {\n segment_id: string;\n start_time_seconds: number;\n end_time_seconds: number;\n start_char_index: number;\n end_char_index: number;\n}\n\nexport interface BreakPolicy {\n /** Default pause between segments, in seconds. */\n betweenSegments: number;\n /** Pause around fade_in / fade_out transitions. */\n fadeBoundary: number;\n}\n\nconst DEFAULT_BREAK_POLICY: BreakPolicy = {\n betweenSegments: 0.45,\n fadeBoundary: 0.75,\n};\n\n/**\n * Build the master script that gets sent as a single ElevenLabs call. Segments\n * are joined with `<break time=\"X.Xs\"/>` SSML tags so the TTS engine renders\n * one continuous take with model-generated pauses between segments — preserving\n * prosody, breath, and natural intonation across the entire demo. Slicing back\n * into per-segment files happens against the rendered audio, at midpoints\n * inside each break, so concatenation reproduces the master.\n */\nexport function buildFullScript(segments: Segment[], policy: BreakPolicy = DEFAULT_BREAK_POLICY): string {\n const parts: string[] = [];\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]!;\n if (i > 0) {\n const prev = segments[i - 1]!;\n const fade = prev.transition === 'fade_out' || seg.transition === 'fade_in';\n const dur = fade ? policy.fadeBoundary : policy.betweenSegments;\n parts.push(`<break time=\"${dur.toFixed(2)}s\"/>`);\n }\n parts.push(seg.vo_line.trim());\n }\n return parts.join(' ');\n}\n\n/**\n * Walk the alignment.characters array and identify, for each segment, the\n * [start, end] character indices that correspond to its vo_line. We match by\n * comparing collapsed-whitespace prefixes — robust to small drift between the\n * exact text we sent and what ElevenLabs reports back in the alignment.\n */\nexport function locateSegmentWindows(\n segments: Segment[],\n alignment: CharacterAlignment,\n): SegmentWindow[] {\n const windows: SegmentWindow[] = [];\n let cursor = 0;\n for (const seg of segments) {\n const target = seg.vo_line.trim();\n if (target.length === 0) {\n windows.push({\n segment_id: seg.id,\n start_time_seconds: cursor < alignment.character_start_times_seconds.length\n ? alignment.character_start_times_seconds[cursor] ?? 0\n : 0,\n end_time_seconds: cursor < alignment.character_end_times_seconds.length\n ? alignment.character_end_times_seconds[cursor] ?? 0\n : 0,\n start_char_index: cursor,\n end_char_index: cursor,\n });\n continue;\n }\n const startIdx = findSegmentStart(alignment.characters, target, cursor);\n if (startIdx === -1) {\n throw new Error(\n `Could not locate segment \"${seg.id}\" in master alignment (starting search at index ${cursor}). ` +\n `First 80 chars of expected text: ${JSON.stringify(target.slice(0, 80))}`,\n );\n }\n const endIdx = findSegmentEnd(alignment.characters, target, startIdx);\n if (endIdx === -1) {\n throw new Error(\n `Located start of segment \"${seg.id}\" at index ${startIdx} but could not find its end.`,\n );\n }\n windows.push({\n segment_id: seg.id,\n start_time_seconds: alignment.character_start_times_seconds[startIdx] ?? 0,\n end_time_seconds: alignment.character_end_times_seconds[endIdx] ?? 0,\n start_char_index: startIdx,\n end_char_index: endIdx,\n });\n cursor = endIdx + 1;\n }\n return windows;\n}\n\n/**\n * Find the index in `chars` where `target` begins, starting search at `from`.\n * Tolerates whitespace differences (consecutive whitespace in either string is\n * treated as a single space).\n */\nfunction findSegmentStart(chars: string[], target: string, from: number): number {\n const normTarget = collapseWhitespace(target);\n const firstTargetChar = normTarget[0]!;\n for (let i = from; i < chars.length; i++) {\n const c = chars[i]!;\n if (c.toLowerCase() !== firstTargetChar.toLowerCase()) continue;\n if (matchesAt(chars, i, normTarget)) return i;\n }\n return -1;\n}\n\nfunction findSegmentEnd(chars: string[], target: string, startIdx: number): number {\n // Walk forward from startIdx, matching against target with whitespace tolerance.\n let ti = 0;\n let ci = startIdx;\n const normTarget = collapseWhitespace(target);\n while (ti < normTarget.length && ci < chars.length) {\n const tc = normTarget[ti]!;\n const cc = chars[ci]!;\n if (tc === ' ') {\n // Consume one or more whitespace chars in source\n if (isWs(cc)) {\n while (ci < chars.length && isWs(chars[ci]!)) ci++;\n ti++;\n continue;\n }\n // Target wants space but source doesn't — abort\n return -1;\n }\n if (cc.toLowerCase() === tc.toLowerCase()) {\n ti++;\n ci++;\n continue;\n }\n if (isWs(cc)) {\n // skip extra whitespace in source\n ci++;\n continue;\n }\n return -1;\n }\n return ti === normTarget.length ? ci - 1 : -1;\n}\n\nfunction matchesAt(chars: string[], from: number, normTarget: string): boolean {\n let ti = 0;\n let ci = from;\n // Quick check: scan PREFIX_CHECK characters\n const PREFIX_CHECK = Math.min(20, normTarget.length);\n while (ti < PREFIX_CHECK && ci < chars.length) {\n const tc = normTarget[ti]!;\n const cc = chars[ci]!;\n if (tc === ' ') {\n if (isWs(cc)) {\n while (ci < chars.length && isWs(chars[ci]!)) ci++;\n ti++;\n continue;\n }\n return false;\n }\n if (cc.toLowerCase() === tc.toLowerCase()) {\n ti++;\n ci++;\n continue;\n }\n if (isWs(cc)) {\n ci++;\n continue;\n }\n return false;\n }\n return ti === PREFIX_CHECK;\n}\n\nfunction collapseWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ');\n}\n\nfunction isWs(ch: string): boolean {\n return ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r';\n}\n\nexport interface SliceBoundary {\n segment_id: string;\n /** Start time in master (seconds). Includes leading silence up to the midpoint of the prior gap. */\n start_sec: number;\n /** End time in master (seconds). Includes trailing silence up to the midpoint of the next gap. */\n end_sec: number;\n}\n\n/**\n * Convert per-segment character windows into mp3 slice boundaries. Each segment\n * absorbs half of the silence on either side of it, so concatenating all slices\n * exactly reproduces the master audio — preserving the model-generated pauses\n * (and the natural breath/prosody around them) instead of replacing them with\n * dead silence.\n */\nexport function computeSliceBoundaries(\n windows: SegmentWindow[],\n masterDurationSec: number,\n): SliceBoundary[] {\n const boundaries: SliceBoundary[] = [];\n for (let i = 0; i < windows.length; i++) {\n const w = windows[i]!;\n const prev = windows[i - 1];\n const next = windows[i + 1];\n const start =\n i === 0\n ? 0\n : (prev!.end_time_seconds + w.start_time_seconds) / 2;\n const end =\n i === windows.length - 1\n ? masterDurationSec\n : (w.end_time_seconds + next!.start_time_seconds) / 2;\n boundaries.push({ segment_id: w.segment_id, start_sec: start, end_sec: end });\n }\n return boundaries;\n}\n\n/**\n * Slice a single segment out of the master mp3 with a clean re-encode so cut\n * boundaries land on frame edges. Re-encode is fast for ~5s clips and avoids\n * the keyframe glitches `-c copy` would introduce.\n */\nexport async function sliceMasterAudio(opts: {\n masterPath: string;\n outputPath: string;\n startSec: number;\n durationSec: number;\n}): Promise<void> {\n await runFfmpeg({\n args: [\n '-y',\n '-ss',\n opts.startSec.toFixed(3),\n '-i',\n opts.masterPath,\n '-t',\n Math.max(0.1, opts.durationSec).toFixed(3),\n '-c:a',\n 'libmp3lame',\n '-q:a',\n '4',\n opts.outputPath,\n ],\n });\n}\n\n/**\n * Build a per-segment alignment file by slicing the master alignment and\n * shifting all timestamps into segment-mp3-file time. The mp3 starts at\n * `boundary.start_sec` in the master, so subtracting that gives times that are\n * relative to the segment's mp3 file (i.e. include the leading silence before\n * the speech starts). This is what both record.ts (at_word resolution) and\n * captions.ts (cue scheduling) need.\n */\nexport function sliceAlignment(\n master: CharacterAlignment,\n window: SegmentWindow,\n boundary: SliceBoundary,\n): CharacterAlignment {\n const start = window.start_char_index;\n const end = window.end_char_index;\n const t0 = boundary.start_sec;\n return {\n characters: master.characters.slice(start, end + 1),\n character_start_times_seconds: master.character_start_times_seconds\n .slice(start, end + 1)\n .map((t) => t - t0),\n character_end_times_seconds: master.character_end_times_seconds\n .slice(start, end + 1)\n .map((t) => t - t0),\n };\n}\n\nexport async function loadMasterAlignment(path: string): Promise<CharacterAlignment | null> {\n try {\n const raw = await readFile(path, 'utf8');\n return JSON.parse(raw) as CharacterAlignment;\n } catch {\n return null;\n }\n}\n\nexport async function writeMasterAlignment(\n path: string,\n alignment: CharacterAlignment,\n): Promise<void> {\n await writeFile(path, JSON.stringify(alignment) + '\\n', 'utf8');\n logger.debug(`Wrote master alignment to ${path}`);\n}\n\nexport interface MasterPaths {\n rawAudio: string;\n alignment: string;\n}\n\nexport function masterPaths(audioDir: string, alignmentDir: string): MasterPaths {\n return {\n rawAudio: join(audioDir, '_master.raw.mp3'),\n alignment: join(alignmentDir, '_master.alignment.json'),\n };\n}\n","import type { CharacterAlignment } from '../../manifest/alignment.js';\n\nexport interface TTSSynthesisRequest {\n text: string;\n /** Provider-specific voice id; falls back to whatever the provider was constructed with. */\n voice?: string;\n /** Playback speed multiplier (provider-dependent; safe range typically 0.85–1.15). */\n speed?: number;\n}\n\nexport interface TTSSynthesisResult {\n audio: Buffer;\n /** Character-level timing data. Optional — only ElevenLabs `with_timestamps` returns this today. */\n alignment?: CharacterAlignment;\n durationSeconds: number;\n charactersSynthesized: number;\n}\n\nexport interface TTSProvider {\n /** Provider name for logging/diagnostics. */\n readonly name: string;\n /** True if this provider returns character-level alignment data. */\n readonly supportsAlignment: boolean;\n synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult>;\n}\n\nexport class TTSProviderError extends Error {\n override readonly name = 'TTSProviderError';\n constructor(\n message: string,\n readonly providerName: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n }\n}\n","import { request } from 'undici';\nimport { logger } from '../util/logger.js';\n\nconst BASE_URL = 'https://api.elevenlabs.io';\n\nexport interface VoiceSettings {\n stability: number;\n similarity_boost: number;\n style: number;\n use_speaker_boost: boolean;\n speed: number;\n}\n\nexport interface SynthesisRequest {\n voiceId: string;\n modelId: string;\n text: string;\n voiceSettings: VoiceSettings;\n apiKey: string;\n}\n\nexport interface WithTimestampsResponse {\n audio_base64: string;\n alignment: {\n characters: string[];\n character_start_times_seconds: number[];\n character_end_times_seconds: number[];\n };\n}\n\nexport interface SynthesisResult {\n audio: Buffer;\n alignment?: WithTimestampsResponse['alignment'];\n durationSeconds: number;\n charactersSynthesized: number;\n}\n\nexport class ElevenLabsError extends Error {\n override readonly name = 'ElevenLabsError';\n constructor(\n message: string,\n readonly status: number,\n readonly body: string,\n ) {\n super(message);\n }\n}\n\nconst MAX_ATTEMPTS = 3;\n\nexport async function synthesizeWithTimestamps(req: SynthesisRequest): Promise<SynthesisResult> {\n const url = `${BASE_URL}/v1/text-to-speech/${encodeURIComponent(req.voiceId)}/with-timestamps`;\n const body = {\n text: req.text,\n model_id: req.modelId,\n voice_settings: req.voiceSettings,\n };\n\n const responseJson = await postWithRetry(url, body, req.apiKey, 'json');\n const parsed = responseJson as WithTimestampsResponse;\n if (\n typeof parsed.audio_base64 !== 'string' ||\n !parsed.alignment ||\n !Array.isArray(parsed.alignment.character_end_times_seconds)\n ) {\n throw new ElevenLabsError(\n 'ElevenLabs with_timestamps response shape unexpected',\n 200,\n JSON.stringify(parsed).slice(0, 500),\n );\n }\n\n const audio = Buffer.from(parsed.audio_base64, 'base64');\n const endTimes = parsed.alignment.character_end_times_seconds;\n const durationSeconds = endTimes.length > 0 ? (endTimes[endTimes.length - 1] ?? 0) : 0;\n\n return {\n audio,\n alignment: parsed.alignment,\n durationSeconds,\n charactersSynthesized: req.text.length,\n };\n}\n\nexport async function synthesizeBasic(req: SynthesisRequest): Promise<Omit<SynthesisResult, 'durationSeconds'>> {\n const url = `${BASE_URL}/v1/text-to-speech/${encodeURIComponent(req.voiceId)}`;\n const body = {\n text: req.text,\n model_id: req.modelId,\n voice_settings: req.voiceSettings,\n };\n\n const audio = (await postWithRetry(url, body, req.apiKey, 'binary')) as Buffer;\n return {\n audio,\n charactersSynthesized: req.text.length,\n };\n}\n\nasync function postWithRetry(\n url: string,\n body: unknown,\n apiKey: string,\n responseMode: 'json' | 'binary',\n): Promise<unknown> {\n let lastError: ElevenLabsError | undefined;\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n return await postOnce(url, body, apiKey, responseMode);\n } catch (err) {\n if (!(err instanceof ElevenLabsError)) throw err;\n lastError = err;\n const retriable = err.status === 429 || err.status >= 500;\n if (!retriable || attempt === MAX_ATTEMPTS) break;\n const backoffMs = Math.min(8000, 500 * 2 ** (attempt - 1));\n logger.warn(`ElevenLabs ${err.status} on attempt ${attempt}, retrying in ${backoffMs}ms`);\n await sleep(backoffMs);\n }\n }\n throw lastError ?? new ElevenLabsError('ElevenLabs request failed', 0, '');\n}\n\nasync function postOnce(\n url: string,\n body: unknown,\n apiKey: string,\n responseMode: 'json' | 'binary',\n): Promise<unknown> {\n const res = await request(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: responseMode === 'json' ? 'application/json' : 'audio/mpeg',\n 'xi-api-key': apiKey,\n },\n body: JSON.stringify(body),\n });\n\n if (res.statusCode >= 400) {\n const errBody = await res.body.text();\n throw new ElevenLabsError(\n `ElevenLabs ${res.statusCode}: ${errBody.slice(0, 300)}`,\n res.statusCode,\n errBody,\n );\n }\n\n if (responseMode === 'json') {\n return await res.body.json();\n }\n const buf = Buffer.from(await res.body.arrayBuffer());\n return buf;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));\n}\n","import { synthesizeWithTimestamps } from '../../voiceover/elevenlabs.js';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface ElevenLabsProviderConfig {\n apiKey: string;\n voiceId: string;\n modelId: string;\n stability: number;\n similarityBoost: number;\n style: number;\n useSpeakerBoost: boolean;\n speed: number;\n}\n\nexport class ElevenLabsTTSProvider implements TTSProvider {\n readonly name = 'elevenlabs';\n readonly supportsAlignment = true;\n\n constructor(private readonly cfg: ElevenLabsProviderConfig) {\n if (!cfg.apiKey) {\n throw new TTSProviderError(\n 'ElevenLabsTTSProvider: apiKey is required',\n 'elevenlabs',\n );\n }\n }\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n const result = await synthesizeWithTimestamps({\n voiceId: req.voice ?? this.cfg.voiceId,\n modelId: this.cfg.modelId,\n text: req.text,\n voiceSettings: {\n stability: this.cfg.stability,\n similarity_boost: this.cfg.similarityBoost,\n style: this.cfg.style,\n use_speaker_boost: this.cfg.useSpeakerBoost,\n speed: req.speed ?? this.cfg.speed,\n },\n apiKey: this.cfg.apiKey,\n });\n return {\n audio: result.audio,\n alignment: result.alignment,\n durationSeconds: result.durationSeconds,\n charactersSynthesized: result.charactersSynthesized,\n };\n }\n}\n","import OpenAI from 'openai';\nimport { ffprobeDurationFromStdin } from '../../voiceover/ffmpeg.js';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface OpenAITTSProviderConfig {\n apiKey: string;\n /** Voice id, e.g. 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'. */\n voice: string;\n /** Model, e.g. 'tts-1', 'tts-1-hd', or 'gpt-4o-mini-tts'. */\n model: string;\n /** Override the API base (Azure / OpenRouter / etc). */\n baseURL?: string;\n}\n\nexport class OpenAITTSProvider implements TTSProvider {\n readonly name = 'openai';\n readonly supportsAlignment = false;\n\n private readonly client: OpenAI;\n\n constructor(private readonly cfg: OpenAITTSProviderConfig) {\n if (!cfg.apiKey) {\n throw new TTSProviderError(\n 'OpenAITTSProvider: apiKey is required',\n 'openai',\n );\n }\n this.client = new OpenAI({ apiKey: cfg.apiKey, baseURL: cfg.baseURL });\n }\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n let response;\n try {\n response = await this.client.audio.speech.create({\n model: this.cfg.model,\n voice: (req.voice ?? this.cfg.voice) as 'alloy',\n input: req.text,\n response_format: 'mp3',\n speed: req.speed ?? 1.0,\n });\n } catch (err) {\n throw new TTSProviderError(\n `OpenAI TTS call failed: ${err instanceof Error ? err.message : String(err)}`,\n 'openai',\n err,\n );\n }\n const arrayBuffer = await response.arrayBuffer();\n const audio = Buffer.from(arrayBuffer);\n const durationSeconds = await ffprobeDurationFromStdin(audio);\n return {\n audio,\n // OpenAI TTS does not return character/word alignment.\n alignment: undefined,\n durationSeconds,\n charactersSynthesized: req.text.length,\n };\n }\n}\n","import { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type {\n TTSProvider,\n TTSSynthesisRequest,\n TTSSynthesisResult,\n} from './types.js';\nimport { TTSProviderError } from './types.js';\n\nexport interface CustomTTSProviderConfig {\n modulePath: string;\n configDir: string;\n options?: Record<string, unknown>;\n}\n\n/**\n * Loads an operator-supplied module that default-exports either a TTSProvider\n * directly or a factory function. Same shape as CustomLLMProvider.\n */\nexport class CustomTTSProvider implements TTSProvider {\n readonly name = 'custom';\n // We can't know up-front whether the custom provider supports alignment.\n // Default to false; the actual provider it loads can advertise its own.\n readonly supportsAlignment = false;\n\n private inner: Promise<TTSProvider> | null = null;\n constructor(private readonly cfg: CustomTTSProviderConfig) {}\n\n async synthesize(req: TTSSynthesisRequest): Promise<TTSSynthesisResult> {\n const provider = await this.load();\n return provider.synthesize(req);\n }\n\n private async load(): Promise<TTSProvider> {\n if (this.inner) return this.inner;\n this.inner = (async () => {\n const absPath = isAbsolute(this.cfg.modulePath)\n ? this.cfg.modulePath\n : resolve(this.cfg.configDir, this.cfg.modulePath);\n let mod: { default?: unknown };\n try {\n mod = (await import(pathToFileURL(absPath).href)) as { default?: unknown };\n } catch (err) {\n throw new TTSProviderError(\n `Failed to load custom TTS module at ${absPath}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 'custom',\n err,\n );\n }\n const exp = mod.default ?? mod;\n if (typeof exp === 'function') {\n const built = await (exp as (o?: unknown) => Promise<TTSProvider> | TTSProvider)(\n this.cfg.options,\n );\n if (!isTTSProvider(built)) {\n throw new TTSProviderError(\n `Custom TTS module at ${absPath} returned a value that is not a TTSProvider (missing synthesize)`,\n 'custom',\n );\n }\n return built;\n }\n if (isTTSProvider(exp)) return exp;\n throw new TTSProviderError(\n `Custom TTS module at ${absPath} must default-export a TTSProvider or a factory function`,\n 'custom',\n );\n })();\n return this.inner;\n }\n}\n\nfunction isTTSProvider(v: unknown): v is TTSProvider {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as { synthesize?: unknown }).synthesize === 'function'\n );\n}\n","import type { TTSProvider } from './types.js';\nimport { TTSProviderError } from './types.js';\nimport { ElevenLabsTTSProvider } from './elevenlabs.js';\nimport { OpenAITTSProvider } from './openai.js';\nimport { CustomTTSProvider } from './custom.js';\n\nexport interface ElevenLabsTTSSpec {\n name: 'elevenlabs';\n voice_id: string;\n model: string;\n api_key_env: string;\n endpoint?: 'with_timestamps' | 'basic';\n stability: number;\n similarity_boost: number;\n style: number;\n use_speaker_boost: boolean;\n speed: number;\n}\n\nexport interface OpenAITTSSpec {\n name: 'openai';\n voice: string;\n model: string;\n api_key_env: string;\n base_url?: string;\n}\n\nexport interface CustomTTSSpec {\n name: 'custom';\n module_path: string;\n options?: Record<string, unknown>;\n}\n\nexport type TTSProviderSpec = ElevenLabsTTSSpec | OpenAITTSSpec | CustomTTSSpec;\n\nexport interface CreateTTSContext {\n configDir: string;\n}\n\nexport function createTTSProvider(spec: TTSProviderSpec, ctx: CreateTTSContext): TTSProvider {\n switch (spec.name) {\n case 'elevenlabs': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new TTSProviderError(\n `TTS provider 'elevenlabs' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'elevenlabs',\n );\n }\n return new ElevenLabsTTSProvider({\n apiKey,\n voiceId: spec.voice_id,\n modelId: spec.model,\n stability: spec.stability,\n similarityBoost: spec.similarity_boost,\n style: spec.style,\n useSpeakerBoost: spec.use_speaker_boost,\n speed: spec.speed,\n });\n }\n case 'openai': {\n const apiKey = process.env[spec.api_key_env];\n if (!apiKey) {\n throw new TTSProviderError(\n `TTS provider 'openai' configured with api_key_env='${spec.api_key_env}' but that env var is not set.`,\n 'openai',\n );\n }\n return new OpenAITTSProvider({\n apiKey,\n voice: spec.voice,\n model: spec.model,\n baseURL: spec.base_url,\n });\n }\n case 'custom':\n return new CustomTTSProvider({\n modulePath: spec.module_path,\n configDir: ctx.configDir,\n options: spec.options,\n });\n }\n}\n\n/**\n * Narrowing helper: return the ElevenLabs sub-config when that's the configured\n * provider, otherwise null. Used by call sites that need to read voice_id etc.\n * without unwrapping the full discriminated union everywhere.\n */\nexport function getElevenLabsSpec(spec: TTSProviderSpec): ElevenLabsTTSSpec | null {\n return spec.name === 'elevenlabs' ? spec : null;\n}\n","import type { PipelineContext } from '../../pipeline/types.js';\nimport type { TTSProvider } from './types.js';\nimport {\n createTTSProvider,\n getElevenLabsSpec,\n type ElevenLabsTTSSpec,\n type TTSProviderSpec,\n} from './factory.js';\nimport type { TTSProviderConfig } from '../../config/schema.js';\n\nconst PROVIDER_CACHE = new WeakMap<PipelineContext, TTSProvider>();\n\n/**\n * Build (or fetch the cached) TTSProvider for this run.\n *\n * Reads from `ctx.providers.tts` when pre-wired by the pipeline, otherwise\n * constructs lazily from `ctx.config.voiceover.provider`. Caching is per-ctx\n * so repeated calls within a stage share the same provider instance.\n */\nexport function resolveTTSProvider(ctx: PipelineContext): TTSProvider {\n const pre = (ctx as PipelineContext & { providers?: { tts?: TTSProvider } }).providers;\n if (pre?.tts) return pre.tts;\n\n const cached = PROVIDER_CACHE.get(ctx);\n if (cached) return cached;\n\n const spec = configToSpec(ctx.config.voiceover.provider);\n const provider = createTTSProvider(spec, { configDir: ctx.configDir });\n PROVIDER_CACHE.set(ctx, provider);\n return provider;\n}\n\nexport type AlignmentStrategy = 'required' | 'best_effort';\n\nexport function resolveAlignmentStrategy(ctx: PipelineContext): AlignmentStrategy {\n return ctx.config.voiceover.alignment_strategy ?? 'required';\n}\n\n/**\n * Narrowing helper for legacy ElevenLabs-only call sites (e.g. `voiceover.ts`\n * reads `vo.speed` for the \"used_speed\" metadata field). Returns the\n * ElevenLabs sub-spec when configured, otherwise null.\n */\nexport function resolveElevenLabsConfigOrNull(ctx: PipelineContext): ElevenLabsTTSSpec | null {\n const spec = configToSpec(ctx.config.voiceover.provider);\n return getElevenLabsSpec(spec);\n}\n\nfunction configToSpec(cfg: TTSProviderConfig): TTSProviderSpec {\n switch (cfg.name) {\n case 'elevenlabs':\n return {\n name: 'elevenlabs',\n voice_id: cfg.voice_id,\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n endpoint: cfg.endpoint,\n stability: cfg.stability,\n similarity_boost: cfg.similarity_boost,\n style: cfg.style,\n use_speaker_boost: cfg.use_speaker_boost,\n speed: cfg.speed,\n };\n case 'openai':\n return {\n name: 'openai',\n voice: cfg.voice,\n model: cfg.model,\n api_key_env: cfg.api_key_env,\n ...(cfg.base_url !== undefined && { base_url: cfg.base_url }),\n };\n case 'custom':\n return {\n name: 'custom',\n module_path: cfg.module_path,\n ...(cfg.options !== undefined && { options: cfg.options }),\n };\n }\n}\n","import { mkdir, rm, rename } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport type { Stage, StageResult, PipelineContext } from '../pipeline/types.js';\nimport { logger } from '../util/logger.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { ffprobeDuration } from '../voiceover/ffmpeg.js';\nimport { normalizeVideo } from '../mux/normalize.js';\nimport { prepareSegmentVideo, readSlicePlan } from '../mux/slice.js';\nimport { muxSegment } from '../mux/segmentMux.js';\nimport { concatSegments } from '../mux/concat.js';\nimport { applyBackgroundMusic, fileExists, renderCard } from '../mux/branding.js';\nimport { emitCaptions } from '../mux/captions.js';\nimport {\n assertEnoughDisk,\n computeThreadCap,\n formatBytes,\n getFreeDiskBytes,\n getFreeMemoryBytes,\n} from '../util/resources.js';\n\nexport const muxStage: Stage = {\n name: 'mux',\n async run(ctx: PipelineContext): Promise<StageResult> {\n const start = Date.now();\n const warnings: string[] = [];\n\n const manifestPath = resolve(ctx.configDir, './scripts/manifest.json');\n const videoDir = resolve(ctx.configDir, ctx.config.recording.output_dir);\n const audioDir = resolve(ctx.configDir, ctx.config.voiceover.output_dir);\n const masterWebm = resolve(videoDir, 'master.webm');\n const slicePlanPath = resolve(videoDir, 'slice_plan.json');\n const outputPath = resolveOutput(ctx.config.output.output_path, ctx.configDir);\n\n const forced = ctx.forced.has('mux');\n if ((await fileExists(outputPath)) && !forced) {\n logger.event({ stage: 'mux', status: 'reusing', path: outputPath });\n return {\n stage: 'mux',\n skipped: true,\n reason: 'output file already present',\n durationMs: Date.now() - start,\n artifacts: { output: outputPath },\n };\n }\n\n for (const [label, path] of [\n ['manifest.json', manifestPath],\n ['master.webm', masterWebm],\n ['slice_plan.json', slicePlanPath],\n ] as const) {\n if (!(await fileExists(path))) {\n return {\n stage: 'mux',\n skipped: true,\n reason: `${label} not found at ${path} — run upstream stages first`,\n durationMs: Date.now() - start,\n };\n }\n }\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`mux stage: ${err.message}`);\n }\n throw err;\n }\n\n const slicePlan = await readSlicePlan(slicePlanPath);\n\n for (const seg of manifest.segments) {\n const audio = join(audioDir, `${seg.id}.mp3`);\n if (!(await fileExists(audio))) {\n return {\n stage: 'mux',\n skipped: true,\n reason: `audio for segment \"${seg.id}\" not found at ${audio} — run voiceover stage first`,\n durationMs: Date.now() - start,\n };\n }\n }\n\n const workDir = resolve(ctx.configDir, '.showrunner-cache', 'mux');\n await mkdir(workDir, { recursive: true });\n\n const fps = ctx.config.output.fps;\n const [widthStr, heightStr] = ctx.config.output.resolution.split('x');\n const width = Number.parseInt(widthStr!, 10);\n const height = Number.parseInt(heightStr!, 10);\n const quality = ctx.config.output.quality;\n logger.event({ stage: 'mux', status: 'quality', preset: quality });\n\n // Preflight: RAM headroom drives a per-encode thread cap; disk space gets\n // a sanity check on the workDir (rough estimate: 50 MB per segment + 200 MB\n // for the normalized master + final mp4 headroom).\n const freeMem = getFreeMemoryBytes();\n const freeDisk = await getFreeDiskBytes(workDir);\n const threads = computeThreadCap({ width, height, fps, quality, freeMemBytes: freeMem });\n const estDiskNeed = (manifest.segments.length * 50 + 200) * 1024 * 1024;\n logger.event({\n stage: 'mux',\n status: 'preflight',\n free_mem: formatBytes(freeMem),\n free_disk: formatBytes(freeDisk),\n threads,\n est_disk_need: formatBytes(estDiskNeed),\n });\n await assertEnoughDisk(workDir, estDiskNeed, 'mux workDir');\n\n logger.event({ stage: 'mux', status: 'normalizing_master' });\n const normalizedMaster = join(workDir, 'master.mp4');\n await normalizeVideo({\n inputPath: masterWebm,\n outputPath: normalizedMaster,\n fps,\n width,\n height,\n quality,\n threads,\n });\n\n const segmentPaths: string[] = [];\n\n if (ctx.config.output.branding.title_card?.enabled) {\n const tc = ctx.config.output.branding.title_card;\n const titlePath = join(workDir, '_title.mp4');\n await renderCard({\n outputPath: titlePath,\n width,\n height,\n fps,\n durationSeconds: tc.duration_seconds,\n text: tc.text,\n textColor: tc.text_color,\n backgroundColor: tc.background_color,\n fontPath: tc.font ? resolveMaybe(tc.font, ctx.configDir) : undefined,\n fontSize: tc.font_size,\n logoPath: tc.logo ? resolveMaybe(tc.logo, ctx.configDir) : undefined,\n logoPosition: tc.logo_position,\n quality,\n });\n segmentPaths.push(titlePath);\n logger.event({ stage: 'mux', status: 'title_card_rendered', path: titlePath });\n }\n\n for (const seg of manifest.segments) {\n logger.event({ stage: 'mux', status: 'segment_prepare', segment: seg.id });\n const videoSource = await prepareSegmentVideo({\n id: seg.id,\n videoDir,\n workDir,\n normalizedMasterPath: normalizedMaster,\n slicePlan,\n fps,\n width,\n height,\n quality,\n });\n\n const finalSeg = join(workDir, `${seg.id}.final.mp4`);\n await muxSegment({\n videoPath: videoSource.path,\n audioPath: join(audioDir, `${seg.id}.mp3`),\n outputPath: finalSeg,\n fps,\n width,\n height,\n transition: seg.transition,\n quality,\n });\n segmentPaths.push(finalSeg);\n logger.event({\n stage: 'mux',\n status: 'segment_muxed',\n segment: seg.id,\n source: videoSource.source,\n });\n }\n\n if (ctx.config.output.branding.outro_card?.enabled) {\n const oc = ctx.config.output.branding.outro_card;\n const outroPath = join(workDir, '_outro.mp4');\n await renderCard({\n outputPath: outroPath,\n width,\n height,\n fps,\n durationSeconds: oc.duration_seconds,\n text: oc.text,\n textColor: '#FFFFFF',\n backgroundColor: '#0F172A',\n fontSize: 36,\n quality,\n });\n segmentPaths.push(outroPath);\n logger.event({ stage: 'mux', status: 'outro_card_rendered', path: outroPath });\n }\n\n const concatPath = join(workDir, 'stitched.mp4');\n logger.event({ stage: 'mux', status: 'concat', inputs: segmentPaths.length });\n await concatSegments({\n segmentPaths,\n workDir,\n outputPath: concatPath,\n });\n\n let finalSource = concatPath;\n const music = ctx.config.output.background_music;\n if (music?.path) {\n const musicPath = resolveMaybe(music.path, ctx.configDir);\n if (await fileExists(musicPath)) {\n const mixed = join(workDir, 'mixed.mp4');\n logger.event({ stage: 'mux', status: 'background_music', path: musicPath });\n await applyBackgroundMusic({\n inputPath: concatPath,\n outputPath: mixed,\n musicPath,\n volumeDb: music.volume_db,\n quality,\n });\n finalSource = mixed;\n } else {\n warnings.push(`background_music.path not found at ${musicPath} — skipping mix`);\n }\n }\n\n await mkdir(dirname(outputPath), { recursive: true });\n let finalOutputPath = outputPath;\n if (await fileExists(outputPath)) {\n try {\n await rm(outputPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code ?? '';\n if (code === 'EBUSY' || code === 'EPERM') {\n const ext = outputPath.endsWith('.mp4') ? '.mp4' : '';\n const stem = outputPath.slice(0, outputPath.length - ext.length);\n const stamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .slice(0, 19);\n finalOutputPath = `${stem}-${stamp}${ext}`;\n warnings.push(\n `existing output ${outputPath} is locked (likely open in a player); wrote new MP4 to ${finalOutputPath} instead`,\n );\n logger.warn(\n `existing output locked; writing to ${finalOutputPath} (close the player to reuse the canonical filename)`,\n );\n } else {\n throw err;\n }\n }\n }\n await rename(finalSource, finalOutputPath);\n\n const finalDuration = await ffprobeDuration(finalOutputPath);\n\n const captionsCfg = ctx.config.output.captions;\n const captionPaths: string[] = [];\n if (captionsCfg.enabled) {\n const alignmentDir = resolve(ctx.configDir, ctx.config.voiceover.alignment_dir);\n const titleCardOffset = ctx.config.output.branding.title_card?.enabled\n ? ctx.config.output.branding.title_card.duration_seconds\n : 0;\n const outputBase = finalOutputPath.replace(/\\.mp4$/i, '');\n try {\n const written = await emitCaptions({\n manifest,\n alignmentDir,\n slicePlan,\n outputBase,\n format: captionsCfg.format,\n titleCardOffset,\n });\n captionPaths.push(...written);\n for (const p of written) {\n logger.event({ stage: 'mux', status: 'captions_written', path: p });\n }\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n warnings.push(`caption emission failed: ${cause}`);\n }\n }\n\n return {\n stage: 'mux',\n skipped: false,\n durationMs: Date.now() - start,\n artifacts: { output: finalOutputPath, captions: captionPaths.join(',') || undefined } as Record<\n string,\n string | undefined\n > as Record<string, string>,\n warnings,\n meta: {\n duration_seconds: finalDuration,\n segments: manifest.segments.length,\n had_title_card: !!ctx.config.output.branding.title_card?.enabled,\n had_outro_card: !!ctx.config.output.branding.outro_card?.enabled,\n captions: captionPaths,\n },\n };\n },\n};\n\nfunction resolveOutput(p: string, configDir: string): string {\n return isAbsolute(p) ? p : resolve(configDir, p);\n}\n\nfunction resolveMaybe(p: string, configDir: string): string {\n return isAbsolute(p) ? p : resolve(configDir, p);\n}\n","export type QualityPreset = 'draft' | 'standard' | 'high';\n\nexport interface ResolvedQuality {\n /** ffmpeg `-crf` (lower is better; 18–28 is the useful range for libx264). */\n crf: number;\n /** ffmpeg `-preset` (slower = smaller file). */\n preset: 'veryfast' | 'medium' | 'slow';\n /** ffmpeg `-b:a` audio bitrate. */\n audioBitrate: string;\n}\n\n/**\n * Map a human quality knob to ffmpeg encoder params.\n *\n * draft fast iterations: ~5x smaller, visibly soft\n * standard shipping default (matches the previous hardcoded values)\n * high crisp text + smooth motion; ~2x file size, ~3x encode time\n */\nexport function resolveQuality(preset: QualityPreset): ResolvedQuality {\n switch (preset) {\n case 'draft':\n return { crf: 28, preset: 'veryfast', audioBitrate: '128k' };\n case 'high':\n return { crf: 18, preset: 'slow', audioBitrate: '256k' };\n case 'standard':\n default:\n return { crf: 20, preset: 'medium', audioBitrate: '192k' };\n }\n}\n","import { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface NormalizeOptions {\n inputPath: string;\n outputPath: string;\n fps: number;\n width: number;\n height: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function normalizeVideo(opts: NormalizeOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const scaleFilter =\n `scale=${opts.width}:${opts.height}:force_original_aspect_ratio=decrease,` +\n `pad=${opts.width}:${opts.height}:(ow-iw)/2:(oh-ih)/2:color=black,` +\n `setsar=1,format=yuv420p`;\n\n await runFfmpeg({\n args: [\n '-y',\n '-i',\n opts.inputPath,\n '-vf',\n scaleFilter,\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-an',\n opts.outputPath,\n ],\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { normalizeVideo } from './normalize.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nconst sliceSegmentSchema = z.object({\n id: z.string(),\n t_start: z.number(),\n t_end: z.number(),\n status: z.enum(['ok', 'failed']),\n failure_reason: z.string().optional(),\n failure_screenshots: z.array(z.string()).default([]),\n warnings: z.array(z.string()).optional(),\n trace_path: z.string().optional(),\n});\n\nexport const slicePlanSchema = z.object({\n recording_path: z.string(),\n recording_started_at: z.string(),\n segments: z.array(sliceSegmentSchema),\n});\n\nexport type SlicePlan = z.infer<typeof slicePlanSchema>;\n\nexport async function readSlicePlan(path: string): Promise<SlicePlan> {\n const raw = await readFile(path, 'utf8');\n return slicePlanSchema.parse(JSON.parse(raw));\n}\n\nexport interface SliceSegmentInput {\n id: string;\n videoDir: string;\n workDir: string;\n normalizedMasterPath: string;\n slicePlan: SlicePlan;\n fps: number;\n width: number;\n height: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport interface SegmentVideoSource {\n segment_id: string;\n source: 'rerun' | 'master_slice';\n path: string;\n duration_hint: number;\n}\n\nexport async function prepareSegmentVideo(input: SliceSegmentInput): Promise<SegmentVideoSource> {\n const q = resolveQuality(input.quality ?? 'standard');\n const rerunWebm = join(input.videoDir, `${input.id}.webm`);\n const rerunMeta = join(input.videoDir, `${input.id}.rerun.json`);\n if ((await fileExists(rerunWebm)) && (await fileExists(rerunMeta))) {\n const out = join(input.workDir, `${input.id}.mp4`);\n await normalizeVideo({\n inputPath: rerunWebm,\n outputPath: out,\n fps: input.fps,\n width: input.width,\n height: input.height,\n quality: input.quality,\n threads: input.threads,\n });\n return {\n segment_id: input.id,\n source: 'rerun',\n path: out,\n duration_hint: 0,\n };\n }\n\n const slice = input.slicePlan.segments.find((s) => s.id === input.id);\n if (!slice) {\n throw new Error(\n `slice_plan.json has no entry for segment \"${input.id}\". Re-run the record stage.`,\n );\n }\n\n const out = join(input.workDir, `${input.id}.mp4`);\n const duration = slice.t_end - slice.t_start;\n await runFfmpeg({\n args: [\n '-y',\n '-ss',\n slice.t_start.toFixed(3),\n '-i',\n input.normalizedMasterPath,\n '-t',\n duration.toFixed(3),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(input.fps),\n '-g',\n String(input.fps),\n '-an',\n out,\n ],\n threads: input.threads,\n hintContext: { width: input.width, height: input.height },\n });\n return {\n segment_id: input.id,\n source: 'master_slice',\n path: out,\n duration_hint: duration,\n };\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport type { Transition } from '../manifest/schema.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface SegmentMuxOptions {\n videoPath: string;\n audioPath: string;\n outputPath: string;\n fps: number;\n width: number;\n height: number;\n transition: Transition;\n quality?: QualityPreset;\n threads?: number;\n}\n\nconst FADE_IN_DURATION_S = 0.5;\nconst FADE_OUT_DURATION_S = 0.5;\n\nexport async function muxSegment(opts: SegmentMuxOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const videoFilters: string[] = [];\n if (opts.transition === 'fade_in') {\n videoFilters.push(`fade=t=in:st=0:d=${FADE_IN_DURATION_S}`);\n } else if (opts.transition === 'fade_out') {\n videoFilters.push(`fade=t=out:st=0:d=${FADE_OUT_DURATION_S}`);\n }\n\n const args: string[] = ['-y', '-i', opts.videoPath, '-i', opts.audioPath];\n if (videoFilters.length > 0) {\n args.push('-vf', videoFilters.join(','));\n }\n args.push(\n '-map',\n '0:v:0',\n '-map',\n '1:a:0',\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n '-shortest',\n opts.outputPath,\n );\n await runFfmpeg({\n args,\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n","import { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\n\nexport interface ConcatOptions {\n segmentPaths: string[];\n workDir: string;\n outputPath: string;\n}\n\nexport async function concatSegments(opts: ConcatOptions): Promise<void> {\n const listPath = join(opts.workDir, 'concat_list.txt');\n const body = opts.segmentPaths\n .map((p) => `file '${escapeForConcat(p)}'`)\n .join('\\n') + '\\n';\n await writeFile(listPath, body, 'utf8');\n\n await runFfmpeg({\n args: [\n '-y',\n '-f',\n 'concat',\n '-safe',\n '0',\n '-i',\n listPath,\n '-c',\n 'copy',\n opts.outputPath,\n ],\n });\n}\n\nfunction escapeForConcat(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/'/g, \"'\\\\''\");\n}\n","import { stat } from 'node:fs/promises';\nimport { runFfmpeg } from '../voiceover/ffmpeg.js';\nimport { resolveQuality, type QualityPreset } from './quality.js';\n\nexport interface CardOptions {\n outputPath: string;\n width: number;\n height: number;\n fps: number;\n durationSeconds: number;\n text: string;\n textColor: string;\n backgroundColor: string;\n fontPath?: string;\n fontSize: number;\n logoPath?: string;\n logoPosition?: 'top_left' | 'top_center' | 'top_right';\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function renderCard(opts: CardOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const fontDirective = opts.fontPath\n ? `fontfile=${escapeFilterPath(opts.fontPath)}:`\n : '';\n const escapedText = escapeFilterText(opts.text);\n const drawText =\n `drawtext=${fontDirective}` +\n `text=${escapedText}:` +\n `fontsize=${opts.fontSize}:` +\n `fontcolor=${ffmpegColor(opts.textColor)}:` +\n `x=(w-text_w)/2:` +\n `y=(h-text_h)/2`;\n\n const args: string[] = [\n '-y',\n '-f',\n 'lavfi',\n '-i',\n `color=c=${ffmpegColor(opts.backgroundColor)}:s=${opts.width}x${opts.height}:r=${opts.fps}:d=${opts.durationSeconds}`,\n '-f',\n 'lavfi',\n '-i',\n `anullsrc=channel_layout=stereo:sample_rate=44100`,\n ];\n\n if (opts.logoPath) {\n args.push('-i', opts.logoPath);\n const overlayXY = logoOverlayPosition(opts.logoPosition ?? 'top_center');\n args.push(\n '-filter_complex',\n `[0:v]${drawText}[bg];[bg][2:v]overlay=${overlayXY}[v]`,\n '-map',\n '[v]',\n );\n } else {\n args.push('-vf', drawText, '-map', '0:v');\n }\n\n args.push(\n '-map',\n '1:a',\n '-t',\n String(opts.durationSeconds),\n '-c:v',\n 'libx264',\n '-preset',\n q.preset,\n '-crf',\n String(q.crf),\n '-pix_fmt',\n 'yuv420p',\n '-r',\n String(opts.fps),\n '-g',\n String(opts.fps),\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n opts.outputPath,\n );\n\n await runFfmpeg({\n args,\n threads: opts.threads,\n hintContext: { width: opts.width, height: opts.height },\n });\n}\n\nexport interface BackgroundMusicOptions {\n inputPath: string;\n outputPath: string;\n musicPath: string;\n volumeDb: number;\n quality?: QualityPreset;\n threads?: number;\n}\n\nexport async function applyBackgroundMusic(opts: BackgroundMusicOptions): Promise<void> {\n const q = resolveQuality(opts.quality ?? 'standard');\n const volumeFactor = Math.pow(10, opts.volumeDb / 20);\n const filterComplex =\n `[1:a]volume=${volumeFactor.toFixed(4)},aloop=loop=-1:size=2e9[bg];` +\n `[0:a][bg]amix=inputs=2:duration=first:dropout_transition=0:normalize=0[a]`;\n await runFfmpeg({\n args: [\n '-y',\n '-i',\n opts.inputPath,\n '-i',\n opts.musicPath,\n '-filter_complex',\n filterComplex,\n '-map',\n '0:v',\n '-map',\n '[a]',\n '-c:v',\n 'copy',\n '-c:a',\n 'aac',\n '-b:a',\n q.audioBitrate,\n '-shortest',\n opts.outputPath,\n ],\n threads: opts.threads,\n });\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction escapeFilterText(text: string): string {\n return text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/:/g, '\\\\:')\n .replace(/,/g, '\\\\,');\n}\n\nfunction escapeFilterPath(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/:/g, '\\\\\\\\:');\n}\n\nfunction ffmpegColor(value: string): string {\n if (value.startsWith('#')) {\n return `0x${value.slice(1)}`;\n }\n return value;\n}\n\nfunction logoOverlayPosition(pos: 'top_left' | 'top_center' | 'top_right'): string {\n switch (pos) {\n case 'top_left':\n return 'x=24:y=24';\n case 'top_right':\n return 'x=W-w-24:y=24';\n case 'top_center':\n default:\n return 'x=(W-w)/2:y=24';\n }\n}\n","import { writeFile } from 'node:fs/promises';\nimport { loadAlignment, type CharacterAlignment } from '../manifest/alignment.js';\nimport type { Manifest } from '../manifest/schema.js';\nimport type { SlicePlan } from './slice.js';\nimport { logger } from '../util/logger.js';\n\nconst MAX_CUE_CHARS = 42;\nconst MAX_CUE_SECONDS = 3;\n\nexport interface Cue {\n index: number;\n startSec: number;\n endSec: number;\n text: string;\n}\n\nexport interface EmitCaptionsOptions {\n manifest: Manifest;\n alignmentDir: string;\n slicePlan: SlicePlan;\n /** Output path stem (without extension). `.srt` and/or `.vtt` are appended. */\n outputBase: string;\n format: 'srt' | 'vtt' | 'both';\n /**\n * Seconds added to every cue to account for any pre-roll (e.g. the title card).\n * Slice_plan timestamps are in master.webm time; the final mp4 has title card\n * + outro card glued on the ends. The caller passes the title card duration here.\n */\n titleCardOffset?: number;\n}\n\nexport async function emitCaptions(opts: EmitCaptionsOptions): Promise<string[]> {\n const cues: Cue[] = [];\n const titleOffset = opts.titleCardOffset ?? 0;\n let cueIndex = 1;\n\n for (const seg of opts.manifest.segments) {\n const slice = opts.slicePlan.segments.find((s) => s.id === seg.id);\n if (slice && slice.status !== 'ok') continue;\n\n // The manifest is rewritten by the voiceover stage so segment.start/end\n // reflect the audio-concat timeline used by mux. Final-mp4 time =\n // title_card_duration + manifest segment.start. The slice_plan's t_start\n // lives in master.webm coordinates (which include the pre-segment recording\n // offset) and is wrong for the final mp4 — don't use it here.\n const segmentStartInFinalMp4 = titleOffset + seg.start;\n const segmentEndInFinalMp4 = titleOffset + seg.end;\n\n const alignmentPath = `${opts.alignmentDir}/${seg.id}.alignment.json`;\n const alignment = await loadAlignment(alignmentPath);\n if (!alignment) {\n logger.warn(`captions: no alignment for segment ${seg.id} — falling back to whole-segment cue`);\n cues.push({\n index: cueIndex++,\n startSec: segmentStartInFinalMp4,\n endSec: segmentEndInFinalMp4,\n text: collapse(seg.vo_line),\n });\n continue;\n }\n\n // Per-segment alignment now uses segment-mp3 time (0 = segment mp3 start,\n // including any leading silence before speech). Adding segmentStartInFinalMp4\n // gives the absolute time in the final mp4.\n const segCues = chunkAlignmentToCues(alignment, segmentStartInFinalMp4);\n for (const c of segCues) {\n cues.push({ ...c, index: cueIndex++ });\n }\n }\n\n const written: string[] = [];\n if (opts.format === 'srt' || opts.format === 'both') {\n const path = `${opts.outputBase}.srt`;\n await writeFile(path, renderSrt(cues), 'utf8');\n written.push(path);\n }\n if (opts.format === 'vtt' || opts.format === 'both') {\n const path = `${opts.outputBase}.vtt`;\n await writeFile(path, renderVtt(cues), 'utf8');\n written.push(path);\n }\n return written;\n}\n\nexport function chunkAlignmentToCues(\n alignment: CharacterAlignment,\n segmentStartSec: number,\n): Cue[] {\n const cues: Cue[] = [];\n const chars = alignment.characters;\n const starts = alignment.character_start_times_seconds;\n const ends = alignment.character_end_times_seconds;\n if (chars.length === 0) return cues;\n\n let cueStart = starts[0]!;\n let cueChars: string[] = [];\n let lastBoundaryIdx = -1;\n let i = 0;\n\n const pushCue = (endIdx: number): void => {\n const text = cueChars.join('').replace(/\\s+/g, ' ').trim();\n if (text.length === 0) return;\n cues.push({\n index: 0, // assigned by caller\n startSec: segmentStartSec + cueStart,\n endSec: segmentStartSec + ends[endIdx]!,\n text,\n });\n };\n\n while (i < chars.length) {\n cueChars.push(chars[i]!);\n\n const cuTextLen = cueChars.join('').length;\n const cueDuration = ends[i]! - cueStart;\n const atWordBoundary = /\\s/.test(chars[i]!) || /[.,;!?—]/.test(chars[i]!);\n if (atWordBoundary) lastBoundaryIdx = i;\n\n const overChars = cuTextLen >= MAX_CUE_CHARS;\n const overTime = cueDuration >= MAX_CUE_SECONDS;\n\n if ((overChars || overTime) && lastBoundaryIdx > -1) {\n // Split at the last word boundary; keep everything after for the next cue\n const cutAt = lastBoundaryIdx;\n cueChars = cueChars.slice(0, cutAt - i + cueChars.length);\n pushCue(cutAt);\n // Reset for next cue\n cueStart = starts[cutAt + 1] ?? starts[i]!;\n cueChars = [];\n // continue from cutAt + 1\n i = cutAt + 1;\n lastBoundaryIdx = -1;\n continue;\n }\n\n i++;\n }\n\n // Final cue\n if (cueChars.length > 0) {\n pushCue(chars.length - 1);\n }\n\n return cues;\n}\n\nfunction renderSrt(cues: Cue[]): string {\n return cues\n .map((c) => `${c.index}\\n${fmtSrt(c.startSec)} --> ${fmtSrt(c.endSec)}\\n${c.text}\\n`)\n .join('\\n');\n}\n\nfunction renderVtt(cues: Cue[]): string {\n return ['WEBVTT', '', ...cues.map((c) => `${fmtVtt(c.startSec)} --> ${fmtVtt(c.endSec)}\\n${c.text}\\n`)].join(\n '\\n',\n );\n}\n\nfunction fmtSrt(sec: number): string {\n const h = Math.floor(sec / 3600);\n const m = Math.floor((sec % 3600) / 60);\n const s = Math.floor(sec % 60);\n const ms = Math.round((sec - Math.floor(sec)) * 1000);\n return `${pad(h, 2)}:${pad(m, 2)}:${pad(s, 2)},${pad(ms, 3)}`;\n}\n\nfunction fmtVtt(sec: number): string {\n const h = Math.floor(sec / 3600);\n const m = Math.floor((sec % 3600) / 60);\n const s = Math.floor(sec % 60);\n const ms = Math.round((sec - Math.floor(sec)) * 1000);\n return `${pad(h, 2)}:${pad(m, 2)}:${pad(s, 2)}.${pad(ms, 3)}`;\n}\n\nfunction pad(n: number, w: number): string {\n return n.toString().padStart(w, '0');\n}\n\nfunction collapse(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n}\n","import type { ShowrunnerConfig } from '../config/schema.js';\n\nexport const STAGE_NAMES = ['comprehension', 'script', 'voiceover', 'record', 'mux'] as const;\nexport type StageName = (typeof STAGE_NAMES)[number];\n\nexport interface PipelineOverrides {\n /** Force headed recording regardless of `recording.headless` in config. */\n headed?: boolean;\n}\n\nexport interface PipelineContext {\n config: ShowrunnerConfig;\n configPath: string;\n configDir: string;\n runId: string;\n interactive: boolean;\n forced: Set<StageName>;\n overrides: PipelineOverrides;\n}\n\nexport interface StageResult {\n stage: StageName;\n skipped: boolean;\n reason?: string;\n durationMs: number;\n artifacts?: Record<string, string>;\n warnings?: string[];\n meta?: Record<string, unknown>;\n halt?: boolean;\n}\n\nexport interface PipelineOptions {\n stages?: StageName[];\n force?: StageName[];\n interactive?: boolean;\n resume?: boolean;\n dryRun?: boolean;\n json?: boolean;\n overrides?: PipelineOverrides;\n}\n\nexport interface PipelineResult {\n runId: string;\n outputPath: string;\n stages: StageResult[];\n buildManifestPath: string;\n}\n\nexport interface Stage {\n name: StageName;\n run(ctx: PipelineContext): Promise<StageResult>;\n}\n"],"mappings":"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","names":["mkdir","writeFile","dirname","resolve","resolve","resolve","stat","writeFile","resolve","readFile","z","readFile","readFile","dirname","z","readFile","dirname","mkdir","writeFile","dirname","mkdir","readFile","writeFile","dirname","z","z","DEFAULT_MAX_TOKENS","DEFAULT_MAX_TOKENS","mkdir","readFile","stat","writeFile","zodToJsonSchema","stat","isAbsolute","resolve","isAbsolute","resolve","stat","zodToJsonSchema","mkdir","writeFile","fileExists","readFile","stat","resolve","isAbsolute","resolve","isAbsolute","resolve","resolve","fileExists","writeFile","stat","mkdir","stat","writeFile","dirname","resolve","mkdir","join","resolve","chromium","firefox","webkit","readFile","readFile","isAbsolute","resolve","pathToFileURL","isAbsolute","resolve","pathToFileURL","readFile","mkdir","dirname","join","state","join","mkdir","dirname","browserMap","chromium","firefox","webkit","resolve","join","mkdir","resolve","fileExists","mkdir","dirname","writeFile","stat","mkdir","stat","writeFile","join","resolve","spawn","readFile","writeFile","join","readFile","writeFile","join","sleep","OpenAI","OpenAI","isAbsolute","resolve","pathToFileURL","isAbsolute","resolve","pathToFileURL","configToSpec","resolve","mkdir","fileExists","writeFile","join","stat","mkdir","rename","dirname","isAbsolute","join","resolve","readFile","stat","join","z","z","readFile","join","fileExists","out","stat","writeFile","join","join","writeFile","stat","fileExists","stat","writeFile","writeFile","resolve","fileExists","join","mkdir","dirname","rename","isAbsolute","resolve","dirname","mkdir","writeFile"]}
|