@kadj-amoah/showrunner 1.1.3 → 1.1.5

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/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/util/logger.ts","../src/commands/run.ts","../src/config/loader.ts","../src/config/schema.ts","../src/pipeline/run.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","../src/commands/doctor.ts","../src/config/providerEnv.ts","../src/util/resolutionPresets.ts","../src/commands/init.ts","../src/commands/installBrowser.ts","../src/commands/validate.ts","../src/commands/printVo.ts","../src/commands/approveVo.ts","../src/commands/rerunSegment.ts","../src/commands/captureAuth.ts","../src/recording/headed.ts","../src/commands/trace.ts","../src/commands/preview.ts","../src/commands/understand.ts","../src/productModel/prompts.ts","../src/productModel/generate.ts","../src/productModel/interactive.ts","../src/commands/instrument.ts","../src/instrument/scan.ts","../src/instrument/suggest.ts","../src/instrument/diff.ts","../src/commands/recordActions.ts","../src/recording/captureEvents.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, Option } from 'commander';\nimport { logger } from './util/logger.js';\nimport { runCommand } from './commands/run.js';\nimport { initCommand } from './commands/init.js';\nimport { installBrowserCommand } from './commands/installBrowser.js';\nimport { validateCommand } from './commands/validate.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { printVoCommand } from './commands/printVo.js';\nimport { approveVoCommand } from './commands/approveVo.js';\nimport { rerunSegmentCommand } from './commands/rerunSegment.js';\nimport { captureAuthCommand } from './commands/captureAuth.js';\nimport { traceCommand } from './commands/trace.js';\nimport { previewCommand } from './commands/preview.js';\nimport { understandCommand } from './commands/understand.js';\nimport { instrumentCommand } from './commands/instrument.js';\nimport { recordActionsCommand } from './commands/recordActions.js';\nimport { notImplemented } from './commands/notImplemented.js';\nimport { STAGE_NAMES, type StageName } from './pipeline/types.js';\n\nconst program = new Command();\n\nprogram\n .name('showrunner')\n .description('Automated product demo recording & production tool')\n .version('1.1.3')\n .option('--json', 'emit structured JSON logs to stdout')\n .option('--log-level <level>', 'log level (debug|info|warn|error)')\n .hook('preAction', (thisCmd) => {\n const opts = thisCmd.opts<{ json?: boolean; logLevel?: string }>();\n if (opts.json) logger.setJson(true);\n if (opts.logLevel) logger.setLevel(opts.logLevel as 'debug' | 'info' | 'warn' | 'error');\n })\n .action(async () => {\n // Bare `showrunner` with no subcommand: print a context-aware welcome\n // instead of falling through to `--help`.\n await printWelcome();\n });\n\nconst stageChoices = [...STAGE_NAMES];\n\nprogram\n .command('run')\n .description('Run the full Showrunner pipeline')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .addOption(\n new Option('--stages <stages>', 'comma-separated subset of stages to run').argParser((v) =>\n parseStages(v),\n ),\n )\n .addOption(\n new Option('--force <stages>', 'comma-separated stages whose artifacts to regenerate').argParser(\n (v) => parseStages(v),\n ),\n )\n .option('--no-interactive', 'disable interactive prompts (agent mode)')\n .option('--resume', 'resume a previously-failed run from the last successful stage')\n .option('--dry-run', 'generate scripts without recording, synthesizing, or muxing')\n .option('--estimate', 'print API cost estimate and exit')\n .option('--output-path <path>', 'override output_path from config')\n .option('--watch', 'run the recording stage in headed mode (overrides config.recording.headless)')\n .option('--skip-doctor', 'skip the implicit preflight doctor checks')\n .option(\n '--resolution <preset>',\n 'override resolution for this run: low (854x480), standard (720p), high (1080p), extreme (4K)',\n )\n .action(runCommand);\n\nprogram\n .command('init')\n .description('Scaffold a new Showrunner project')\n .option('--name <name>', 'project name', 'showrunner-demo')\n .option('--url <url>', 'target URL of the product to demo', 'http://localhost:3000')\n .option('--dir <dir>', 'parent directory in which to create the project', process.cwd())\n .option('--force', 'overwrite an existing directory', false)\n .option(\n '--llm-provider <name>',\n 'LLM provider for comprehension + script + instrument (anthropic | openai | agent_bridge)',\n 'anthropic',\n )\n .option(\n '--tts-provider <name>',\n 'TTS provider for voiceover (elevenlabs | openai | custom)',\n 'elevenlabs',\n )\n .option(\n '--resolution <preset>',\n 'scaffold resolution: low (854x480) | standard (720p) | high (1080p) | extreme (4K)',\n 'standard',\n )\n .action(initCommand);\n\nprogram\n .command('install-browser')\n .description('Install the Playwright browser binary (chromium by default) — wraps playwright-core install')\n .option('--browser <name>', 'browser to install: chromium | firefox | webkit', 'chromium')\n .action(installBrowserCommand);\n\nprogram\n .command('doctor')\n .description('Run preflight checks on the current config + environment')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--json', 'emit results as JSON instead of human-readable rows')\n .action(doctorCommand);\n\nprogram\n .command('validate')\n .description('Validate a demo.yaml config file')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--strict', 'exit nonzero on any warning (e.g. missing provider env var)')\n .action(validateCommand);\n\nprogram\n .command('understand')\n .description('Build product_model.json from documents or interactive Q&A')\n .option('-c, --config <path>', 'path to demo.yaml')\n .option('--interactive', 'use interactive Q&A mode')\n .option('--output <path>', 'output path for product_model.json')\n .action(understandCommand);\n\nprogram\n .command('instrument')\n .description('Suggest data-testid attributes for a codebase')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .requiredOption('--output <path>', 'unified diff output path')\n .option('--glob <pattern>', 'override comprehension.sources with an ad-hoc glob (relative to configDir)')\n .action(instrumentCommand);\n\nprogram\n .command('record-actions')\n .description('Author manifest actions by demonstrating them in a live browser')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--segment <id>', 'replace actions for an existing segment id')\n .option('--output <path>', 'manifest output path (default ./scripts/manifest.json)')\n .action(recordActionsCommand);\n\nprogram\n .command('preview')\n .description('Preview the generated Playwright script in UI Mode')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(previewCommand);\n\nprogram\n .command('trace')\n .description('Open the Playwright Trace Viewer for a recording')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--segment <id>', 'open trace for one segment')\n .option('--all', 'open traces for all segments from the last run')\n .action(traceCommand);\n\nprogram\n .command('rerun-segment')\n .description('Re-record a single segment (runs reset_script first)')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .requiredOption('--segment <id>', 'segment to re-run')\n .action(rerunSegmentCommand);\n\nprogram\n .command('print-vo')\n .description('Print the generated VO script for review')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(printVoCommand);\n\nprogram\n .command('capture-auth')\n .description('Capture an auth session interactively (run once during setup)')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--output-cookies <path>', 'storageState output path', './auth/session.json')\n .action(captureAuthCommand);\n\nprogram\n .command('approve-vo')\n .description('Approve edited VO script and resume the pipeline')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(approveVoCommand);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(message);\n process.exit(1);\n});\n\nasync function printWelcome(): Promise<void> {\n const { access } = await import('node:fs/promises');\n const { resolve } = await import('node:path');\n const demoYaml = resolve(process.cwd(), 'demo.yaml');\n let inProject = false;\n try {\n await access(demoYaml);\n inProject = true;\n } catch {\n // not in a Showrunner project root\n }\n\n const browserMissing = await isChromiumMissing();\n\n const lines: string[] = ['', `Showrunner v1.1.3`, ''];\n\n // Surface one state at a time. Higher-priority states short-circuit lower ones.\n if (browserMissing) {\n lines.push(`Showrunner records using Chromium. You haven't installed it yet.`);\n lines.push(``);\n lines.push(` showrunner install-browser`);\n lines.push(``);\n lines.push(`(~150 MB, one-off. Re-run \\`showrunner\\` after it finishes for the next step.)`);\n } else if (inProject) {\n lines.push(`This is a Showrunner project (found demo.yaml).`);\n lines.push(``);\n lines.push(` showrunner doctor -c demo.yaml # check everything is wired correctly`);\n lines.push(` showrunner run -c demo.yaml # then run the full pipeline`);\n lines.push(``);\n lines.push(`Full command list: \\`showrunner --help\\``);\n } else {\n lines.push(`No Showrunner project in this directory. To create one:`);\n lines.push(``);\n lines.push(` showrunner init`);\n lines.push(``);\n lines.push(`\\`init\\` scaffolds the project and prints the next 4 commands tailored to your provider choice.`);\n }\n\n lines.push('');\n process.stdout.write(lines.join('\\n'));\n}\n\nasync function isChromiumMissing(): Promise<boolean> {\n try {\n const { chromium } = await import('playwright-core');\n const exec = chromium.executablePath();\n const { stat } = await import('node:fs/promises');\n await stat(exec);\n return false;\n } catch {\n return true;\n }\n}\n\nfunction parseStages(value: string): StageName[] {\n const requested = value.split(',').map((s) => s.trim());\n const invalid = requested.filter((s) => !stageChoices.includes(s as StageName));\n if (invalid.length > 0) {\n throw new Error(\n `Unknown stage(s): ${invalid.join(', ')}. Valid stages: ${stageChoices.join(', ')}`,\n );\n }\n return requested as StageName[];\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 { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { run, PipelineStageError } from '../pipeline/run.js';\nimport { logger } from '../util/logger.js';\nimport type { StageName } from '../pipeline/types.js';\nimport { runDoctorChecks } from './doctor.js';\nimport { formatResolution, resolvePreset } from '../util/resolutionPresets.js';\n\nconst STAGE_REMEDIATION: Record<StageName, string> = {\n comprehension:\n 'Check the LLM provider env (or switch llm.default.provider to agent_bridge in demo.yaml). ' +\n 'If you already have a product_model.json, skip this stage: --stages script,record,voiceover,mux',\n script:\n 'Manifest generation failed. Inspect scripts/manifest.json if it was partially written. ' +\n 'If the LLM is misbehaving, hand-author scripts/manifest.json and resume: --stages record,voiceover,mux',\n record:\n 'Playwright recording failed. Inspect with `showrunner trace -c <config> --all` or `--segment <id>`. ' +\n 'Demo a problem segment manually with `showrunner record-actions -c <config> --segment <id>`.',\n voiceover:\n 'TTS synthesis or alignment failed. Check your TTS provider env. ' +\n 'If alignment is the issue, set voiceover.alignment_strategy: best_effort in demo.yaml.',\n mux:\n 'ffmpeg mux failed. Check the `doctor` row about free disk + RAM. ' +\n 'Cap libx264 threads with `SHOWRUNNER_FFMPEG_THREADS=1` if RAM is tight.',\n};\n\nexport interface RunOpts {\n config: string;\n stages?: StageName[];\n force?: StageName[];\n interactive?: boolean;\n resume?: boolean;\n dryRun?: boolean;\n estimate?: boolean;\n outputPath?: string;\n watch?: boolean;\n skipDoctor?: boolean;\n resolution?: string;\n}\n\nexport async function runCommand(opts: RunOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n logger.debug(`loaded env from ${envFile}`);\n } catch {\n // No .env in project dir — fine, env vars may come from the shell.\n }\n\n if (opts.outputPath) {\n loaded.config.output.output_path = opts.outputPath;\n }\n\n if (opts.resolution) {\n let r;\n try {\n r = resolvePreset(opts.resolution);\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err));\n process.exit(2);\n }\n loaded.config.recording.viewport.width = r.width;\n loaded.config.recording.viewport.height = r.height;\n loaded.config.output.resolution = formatResolution(r);\n logger.info(`Resolution override: ${opts.resolution} → ${formatResolution(r)} (recording + output)`);\n }\n\n if (opts.estimate) {\n logger.warn('--estimate is not yet implemented; running the pipeline.');\n }\n\n // Implicit pre-flight via doctor. Bail on FAIL unless --skip-doctor was passed.\n if (!opts.skipDoctor) {\n const results = await runDoctorChecks(opts.config);\n const fails = results.filter((r) => r.status === 'FAIL');\n if (fails.length > 0) {\n for (const f of fails) {\n logger.error(`[doctor] ${f.label}${f.detail ? ` — ${f.detail}` : ''}`);\n }\n logger.error(\n `Doctor reported ${fails.length} FAIL row(s). Run \\`showrunner doctor -c ${opts.config}\\` for details, or pass --skip-doctor to bypass.`,\n );\n process.exit(1);\n }\n const warns = results.filter((r) => r.status === 'WARN');\n for (const w of warns) {\n logger.warn(`[doctor] ${w.label}${w.detail ? ` — ${w.detail}` : ''}`);\n }\n }\n\n try {\n const result = await run(loaded, {\n stages: opts.stages,\n force: opts.force,\n interactive: opts.interactive ?? true,\n resume: opts.resume ?? false,\n dryRun: opts.dryRun ?? false,\n overrides: { headed: opts.watch ?? false },\n });\n logger.info('Pipeline complete', {\n runId: result.runId,\n output: result.outputPath,\n buildManifest: result.buildManifestPath,\n });\n } catch (err) {\n if (err instanceof PipelineStageError) {\n logger.error(`Pipeline failed in stage \\`${err.stage}\\`: ${err.message}`);\n const remediation = STAGE_REMEDIATION[err.stage];\n if (remediation) logger.error(`To fix: ${remediation}`);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Pipeline failed: ${message}`);\n process.exit(1);\n }\n}\n","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","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","import { spawn } from 'node:child_process';\nimport { stat, access, constants, readdir } from 'node:fs/promises';\nimport { isAbsolute, resolve, dirname, join } from 'node:path';\nimport { homedir, platform as osPlatform } from 'node:os';\nimport { request as undiciRequest } from 'undici';\nimport { chromium, firefox, webkit } from 'playwright-core';\nimport type { ShowrunnerConfig } from '../config/schema.js';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { inspectProviderEnv } from '../config/providerEnv.js';\nimport { logger } from '../util/logger.js';\nimport {\n computeThreadCap,\n formatBytes,\n getFreeDiskBytes,\n getFreeMemoryBytes,\n getTotalMemoryBytes,\n} from '../util/resources.js';\n\nexport type CheckStatus = 'PASS' | 'WARN' | 'FAIL';\n\nexport interface CheckResult {\n status: CheckStatus;\n label: string;\n detail?: string;\n}\n\ninterface DoctorOpts {\n config: string;\n json?: boolean;\n}\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function doctorCommand(opts: DoctorOpts): Promise<void> {\n // Load .env from the config's directory so env-var checks see what `run` would see.\n const envFile = resolve(dirname(resolve(opts.config)), '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // No .env in project dir — env vars may come from the shell or fail the check below.\n }\n\n const results = await runDoctorChecks(opts.config);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify({ results, summary: summarize(results) }, null, 2) + '\\n');\n } else {\n for (const r of results) printRow(r);\n const summary = summarize(results);\n if (summary.fail > 0) {\n printFixOrder(results);\n logger.error(`doctor: ${summary.fail} FAIL, ${summary.warn} WARN, ${summary.pass} PASS`);\n } else if (summary.warn > 0) {\n logger.warn(`doctor: ${summary.warn} WARN, ${summary.pass} PASS`);\n } else {\n logger.info(`doctor: ${summary.pass}/${results.length} checks passed. ready to run.`);\n }\n }\n\n if (results.some((r) => r.status === 'FAIL')) {\n process.exit(1);\n }\n}\n\n/**\n * Reusable from `run` for the implicit pre-flight (with `--skip-doctor` escape).\n * Returns the full results array; caller decides whether to bail on FAIL.\n */\nexport async function runDoctorChecks(configPath: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // 1. Config loads cleanly.\n let loaded;\n try {\n loaded = await loadConfig(configPath);\n results.push({ status: 'PASS', label: `config syntactically valid: ${configPath}` });\n } catch (err) {\n const msg = err instanceof ConfigError ? err.message : err instanceof Error ? err.message : String(err);\n results.push({ status: 'FAIL', label: `config invalid: ${configPath}`, detail: msg });\n return results;\n }\n const { config, configDir } = loaded;\n\n // 2. Provider env vars.\n for (const row of inspectProviderEnv(config)) {\n const suffix = row.stage ? ` (${row.stage} override)` : '';\n if (row.set) {\n results.push({\n status: 'PASS',\n label: `${row.slot} provider=${row.provider}${suffix}, ${row.envVar} set`,\n });\n } else {\n results.push({\n status: 'FAIL',\n label: `${row.slot} provider=${row.provider}${suffix}, ${row.envVar} NOT set`,\n detail: providerEnvHint(row.slot, row.provider, row.envVar),\n });\n }\n }\n\n // 3. ffmpeg + ffprobe.\n results.push(await checkBinary('ffmpeg', ['-version']));\n results.push(await checkBinary('ffprobe', ['-version']));\n\n // 4. Playwright chromium present.\n results.push(await checkPlaywrightBrowser(config));\n\n // 5. Target URL reachable.\n results.push(await checkTargetReachable(config.recording.target_url));\n\n // 6. Free disk on the dirs we write into.\n const dirsToCheck: Array<{ relPath: string; label: string }> = [\n { relPath: config.recording.output_dir, label: 'recording.output_dir' },\n { relPath: config.voiceover.output_dir, label: 'voiceover.output_dir' },\n { relPath: dirname(config.output.output_path), label: 'output.output_path parent' },\n ];\n for (const d of dirsToCheck) {\n const abs = isAbsolute(d.relPath) ? d.relPath : resolve(configDir, d.relPath);\n const parent = await firstExistingAncestor(abs);\n const free = await getFreeDiskBytes(parent);\n const enough = free > 1024 * 1024 * 1024; // 1 GB rule of thumb\n results.push({\n status: enough ? 'PASS' : 'WARN',\n label: `free disk ${d.label} (${parent}): ${formatBytes(free)}`,\n });\n }\n\n // 7. Free memory + thread cap.\n const freeMem = getFreeMemoryBytes();\n const totalMem = getTotalMemoryBytes();\n const [widthStr, heightStr] = config.output.resolution.split('x');\n const width = Number.parseInt(widthStr ?? '1920', 10);\n const height = Number.parseInt(heightStr ?? '1080', 10);\n const threads = computeThreadCap({\n width,\n height,\n fps: config.output.fps,\n quality: config.output.quality,\n freeMemBytes: freeMem,\n });\n results.push({\n status: freeMem > 1024 * 1024 * 1024 ? 'PASS' : 'WARN',\n label: `free memory: ${formatBytes(freeMem)} of ${formatBytes(totalMem)} (ffmpeg thread cap: ${threads})`,\n });\n\n // 8. Lifecycle scripts exist + (on POSIX) are executable.\n for (const [label, p] of [\n ['recording.state.seed_script', config.recording.state.seed_script],\n ['recording.state.reset_script', config.recording.state.reset_script],\n ['recording.state.teardown_script', config.recording.state.teardown_script],\n ] as const) {\n if (!p) continue;\n const abs = isAbsolute(p) ? p : resolve(configDir, p);\n results.push(await checkScript(label, abs));\n }\n\n return results;\n}\n\nfunction summarize(results: CheckResult[]): { pass: number; warn: number; fail: number } {\n return {\n pass: results.filter((r) => r.status === 'PASS').length,\n warn: results.filter((r) => r.status === 'WARN').length,\n fail: results.filter((r) => r.status === 'FAIL').length,\n };\n}\n\nfunction printFixOrder(results: CheckResult[]): void {\n const fails = results.filter((r) => r.status === 'FAIL');\n if (fails.length === 0) return;\n process.stdout.write('\\n');\n logger.info('To fix:');\n fails.forEach((r, i) => {\n const hint = r.detail ? ` — ${r.detail}` : '';\n logger.info(` ${i + 1}. ${r.label}${hint}`);\n });\n process.stdout.write('\\n');\n}\n\nfunction printRow(r: CheckResult): void {\n const tag = `[${r.status}]`;\n const line = `${tag} ${r.label}${r.detail ? ` — ${r.detail}` : ''}`;\n if (r.status === 'FAIL') logger.error(line);\n else if (r.status === 'WARN') logger.warn(line);\n else logger.info(line);\n}\n\nasync function checkBinary(name: string, args: string[]): Promise<CheckResult> {\n return new Promise((resolve) => {\n const child = spawn(name, args, { stdio: ['ignore', 'pipe', 'pipe'] });\n let stdout = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.on('error', () => {\n resolve({\n status: 'FAIL',\n label: `${name} not on PATH`,\n detail: installHintFor(name),\n });\n });\n child.on('exit', (code) => {\n if (code === 0) {\n const firstLine = stdout.split('\\n')[0]?.trim() ?? '';\n resolve({ status: 'PASS', label: `${name} present`, detail: firstLine });\n } else {\n resolve({\n status: 'FAIL',\n label: `${name} exited with code ${code}`,\n detail: installHintFor(name),\n });\n }\n });\n });\n}\n\nfunction providerEnvHint(slot: 'llm' | 'tts', provider: string, envVar: string): string {\n const dashboards: Record<string, string> = {\n anthropic: 'https://console.anthropic.com/settings/keys',\n openai: 'https://platform.openai.com/api-keys',\n elevenlabs: 'https://elevenlabs.io/app/settings/api-keys',\n };\n const dash = dashboards[provider];\n const dashHint = dash ? ` (get a key from ${dash})` : '';\n const altHint =\n slot === 'llm'\n ? ` — or switch llm.default.provider to \"agent_bridge\" in demo.yaml to use a local CLI agent (no API key needed)`\n : '';\n return `add ${envVar}=... to your project's .env file${dashHint}${altHint}`;\n}\n\nfunction installHintFor(binary: string): string {\n const p = osPlatform();\n if (binary !== 'ffmpeg' && binary !== 'ffprobe') return '';\n // ffprobe ships alongside ffmpeg in every distro's ffmpeg package, so the hint is the same.\n if (p === 'darwin') return 'install via `brew install ffmpeg`';\n if (p === 'win32') return 'install via `winget install Gyan.FFmpeg` or `choco install ffmpeg`';\n // linux — show the three common package managers\n return 'install via `apt install ffmpeg` (Debian/Ubuntu), `pacman -S ffmpeg` (Arch), or `dnf install ffmpeg` (Fedora)';\n}\n\nasync function checkPlaywrightBrowser(config: ShowrunnerConfig): Promise<CheckResult> {\n const browserName = config.recording.browser;\n try {\n const exec = browserMap[browserName].executablePath();\n await stat(exec);\n return {\n status: 'PASS',\n label: `playwright ${browserName} binary present`,\n detail: exec,\n };\n } catch (err) {\n // Probe the sudo/root cache to give a better hint when the user ran\n // `sudo npx playwright install` and the browser landed in /root/.cache\n // (or %SystemRoot%\\System32\\config\\systemprofile\\AppData\\Local on Windows).\n const sudoHit = await probeRootCache(browserName);\n const fallback = `run \\`npx playwright install ${browserName}\\``;\n if (sudoHit) {\n return {\n status: 'FAIL',\n label: `playwright ${browserName} binary missing for current user, but found in root/admin cache`,\n detail:\n `${sudoHit} — re-run install WITHOUT sudo so the browser lands in your user cache: ${fallback}`,\n };\n }\n return {\n status: 'FAIL',\n label: `playwright ${browserName} binary missing`,\n detail: `${fallback} (${err instanceof Error ? err.message : String(err)})`,\n };\n }\n}\n\nasync function probeRootCache(browserName: string): Promise<string | null> {\n const candidates: string[] = [];\n const home = homedir();\n const p = osPlatform();\n\n if (p === 'linux') {\n candidates.push('/root/.cache/ms-playwright');\n } else if (p === 'darwin') {\n candidates.push('/var/root/Library/Caches/ms-playwright');\n } else if (p === 'win32') {\n const systemRoot = process.env['SystemRoot'] ?? 'C:\\\\Windows';\n candidates.push(join(systemRoot, 'System32', 'config', 'systemprofile', 'AppData', 'Local', 'ms-playwright'));\n }\n\n // Don't flag if the current user is root — the executablePath() above would have hit.\n if (candidates.length === 0) return null;\n if (home === '/root' || home === '/var/root') return null;\n\n for (const dir of candidates) {\n try {\n const entries = await readdir(dir);\n const match = entries.find((e) => e.toLowerCase().startsWith(browserName.toLowerCase()));\n if (match) {\n return `found at ${join(dir, match)}`;\n }\n } catch {\n // dir doesn't exist or unreadable — fine, try next\n }\n }\n return null;\n}\n\nasync function checkTargetReachable(url: string): Promise<CheckResult> {\n try {\n const start = Date.now();\n const res = await undiciRequest(url, {\n method: 'HEAD',\n bodyTimeout: 5000,\n headersTimeout: 5000,\n });\n const elapsed = Date.now() - start;\n if (res.statusCode >= 200 && res.statusCode < 500) {\n return {\n status: 'PASS',\n label: `target ${url} reachable (HTTP ${res.statusCode}, ${elapsed}ms)`,\n };\n }\n return {\n status: 'WARN',\n label: `target ${url} returned HTTP ${res.statusCode}`,\n };\n } catch (err) {\n const reason = err instanceof Error ? err.message.trim() : String(err).trim();\n const prefix = reason ? `${reason} — ` : '';\n return {\n status: 'FAIL',\n label: `target ${url} not reachable`,\n detail: `${prefix}start your dev server on this URL, or change \\`recording.target_url\\` in demo.yaml`,\n };\n }\n}\n\nasync function checkScript(label: string, abs: string): Promise<CheckResult> {\n try {\n await stat(abs);\n } catch {\n return {\n status: 'FAIL',\n label: `${label} not found`,\n detail: `expected at ${abs} — re-scaffold (\\`showrunner init\\` writes these) or remove the entry from demo.yaml's recording.state block`,\n };\n }\n if (process.platform !== 'win32') {\n try {\n await access(abs, constants.X_OK);\n } catch {\n return {\n status: 'WARN',\n label: `${label} found but not executable`,\n detail: `chmod +x ${abs}`,\n };\n }\n }\n return { status: 'PASS', label: `${label} ok`, detail: abs };\n}\n\nasync function firstExistingAncestor(p: string): Promise<string> {\n let current = p;\n while (true) {\n try {\n await stat(current);\n return current;\n } catch {\n const parent = dirname(current);\n if (parent === current) return current;\n current = parent;\n }\n }\n}\n","import type { ShowrunnerConfig, LLMProviderConfig, TTSProviderConfig } from './schema.js';\n\nexport interface ProviderEnvCheck {\n provider: string;\n slot: 'llm' | 'tts';\n stage?: string;\n envVar: string;\n set: boolean;\n}\n\n/**\n * Inspect the config and return one row per provider env var that needs to be\n * set. Used by `validate` (warnings) and `doctor` (PASS/FAIL rows). Providers\n * that don't need an env var (agent_bridge, custom) are skipped.\n */\nexport function inspectProviderEnv(config: ShowrunnerConfig): ProviderEnvCheck[] {\n const rows: ProviderEnvCheck[] = [];\n\n // LLM default\n const llmRow = inspectLLMSpec(config.llm.default);\n if (llmRow) rows.push(llmRow);\n\n // LLM per-stage overrides\n if (config.llm.overrides) {\n for (const [stage, spec] of Object.entries(config.llm.overrides)) {\n if (!spec) continue;\n const row = inspectLLMSpec(spec);\n if (row) rows.push({ ...row, stage });\n }\n }\n\n // TTS\n const ttsRow = inspectTTSSpec(config.voiceover.provider);\n if (ttsRow) rows.push(ttsRow);\n\n return rows;\n}\n\nfunction inspectLLMSpec(spec: LLMProviderConfig): Omit<ProviderEnvCheck, 'stage'> | null {\n switch (spec.provider) {\n case 'anthropic':\n case 'openai':\n return {\n provider: spec.provider,\n slot: 'llm',\n envVar: spec.api_key_env,\n set: Boolean(process.env[spec.api_key_env]),\n };\n case 'agent_bridge':\n case 'custom':\n return null;\n }\n}\n\nfunction inspectTTSSpec(spec: TTSProviderConfig): Omit<ProviderEnvCheck, 'stage'> | null {\n switch (spec.name) {\n case 'elevenlabs':\n case 'openai':\n return {\n provider: spec.name,\n slot: 'tts',\n envVar: spec.api_key_env,\n set: Boolean(process.env[spec.api_key_env]),\n };\n case 'custom':\n return null;\n }\n}\n\nexport function formatMissingEnvVars(rows: ProviderEnvCheck[]): string[] {\n return rows\n .filter((r) => !r.set)\n .map(\n (r) =>\n `${r.slot} provider \"${r.provider}\"${r.stage ? ` (stage: ${r.stage})` : ''} expects ${r.envVar} but it is not set`,\n );\n}\n","export type ResolutionPreset = 'low' | 'standard' | 'high' | 'extreme';\n\nexport const RESOLUTION_PRESETS: readonly ResolutionPreset[] = [\n 'low',\n 'standard',\n 'high',\n 'extreme',\n] as const;\n\nexport interface Resolution {\n width: number;\n height: number;\n}\n\nconst PRESET_MAP: Record<ResolutionPreset, Resolution> = {\n low: { width: 854, height: 480 },\n standard: { width: 1280, height: 720 },\n high: { width: 1920, height: 1080 },\n extreme: { width: 3840, height: 2160 },\n};\n\nexport function resolvePreset(value: string): Resolution {\n if (!RESOLUTION_PRESETS.includes(value as ResolutionPreset)) {\n throw new Error(\n `--resolution must be one of: ${RESOLUTION_PRESETS.join(', ')} (got \"${value}\")`,\n );\n }\n return PRESET_MAP[value as ResolutionPreset];\n}\n\nexport function formatResolution(r: Resolution): string {\n return `${r.width}x${r.height}`;\n}\n","import { mkdir, writeFile, access } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { logger } from '../util/logger.js';\nimport {\n RESOLUTION_PRESETS,\n formatResolution,\n resolvePreset,\n type Resolution,\n type ResolutionPreset,\n} from '../util/resolutionPresets.js';\n\nexport type LLMProviderChoice = 'anthropic' | 'openai' | 'agent_bridge';\nexport type TTSProviderChoice = 'elevenlabs' | 'openai' | 'custom';\n\nconst LLM_CHOICES: LLMProviderChoice[] = ['anthropic', 'openai', 'agent_bridge'];\nconst TTS_CHOICES: TTSProviderChoice[] = ['elevenlabs', 'openai', 'custom'];\n\ninterface InitOpts {\n name: string;\n url: string;\n dir: string;\n force: boolean;\n llmProvider?: string;\n ttsProvider?: string;\n resolution?: string;\n}\n\ninterface ResolvedInitOpts extends Omit<InitOpts, 'resolution'> {\n llm: LLMProviderChoice;\n tts: TTSProviderChoice;\n resolutionPreset: ResolutionPreset;\n resolution: Resolution;\n}\n\nconst PLACEHOLDER_FILES = [\n 'auth/.gitkeep',\n 'assets/fonts/.gitkeep',\n 'scripts/.gitkeep',\n 'segments/audio/.gitkeep',\n 'segments/video/.gitkeep',\n 'output/.gitkeep',\n];\n\nexport async function initCommand(opts: InitOpts): Promise<void> {\n const resolutionPreset = validateChoice<ResolutionPreset>(\n opts.resolution,\n [...RESOLUTION_PRESETS],\n 'standard',\n '--resolution',\n );\n const resolved: ResolvedInitOpts = {\n ...opts,\n llm: validateChoice<LLMProviderChoice>(opts.llmProvider, LLM_CHOICES, 'anthropic', '--llm-provider'),\n tts: validateChoice<TTSProviderChoice>(opts.ttsProvider, TTS_CHOICES, 'elevenlabs', '--tts-provider'),\n resolutionPreset,\n resolution: resolvePreset(resolutionPreset),\n };\n\n const parent = isAbsolute(opts.dir) ? opts.dir : resolve(process.cwd(), opts.dir);\n const projectRoot = join(parent, opts.name);\n\n if (!opts.force && (await pathExists(projectRoot))) {\n logger.error(\n `Directory already exists: ${projectRoot}. Pass --force to overwrite, or choose a different --name/--dir.`,\n );\n process.exit(1);\n }\n\n await mkdir(projectRoot, { recursive: true });\n\n for (const rel of PLACEHOLDER_FILES) {\n const dest = join(projectRoot, rel);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, '', 'utf8');\n }\n\n await writeFile(join(projectRoot, 'demo.yaml'), demoYamlTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, '.env.example'), envExampleTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, '.gitignore'), gitignoreTemplate(), 'utf8');\n await mkdir(join(projectRoot, 'docs'), { recursive: true });\n await writeFile(join(projectRoot, 'docs/PRD.md'), prdStubTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, 'scripts/manifest.json'), starterManifest(resolved), 'utf8');\n await writeFile(join(projectRoot, 'scripts/seed_demo_data.sh'), seedScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'scripts/reset_demo_data.sh'), resetScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'scripts/teardown.sh'), teardownScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'README.md'), readmeTemplate(resolved), 'utf8');\n\n logger.info(`Showrunner project scaffolded at ${projectRoot} (llm=${resolved.llm}, tts=${resolved.tts})`);\n printNextSteps(opts.name, resolved);\n}\n\nfunction printNextSteps(projectName: string, resolved: ResolvedInitOpts): void {\n const envVars = requiredEnvVars(resolved);\n const lines: string[] = ['', `Next:`, ''];\n\n let step = 1;\n lines.push(` ${step++}. cd ${projectName}`);\n\n if (envVars.length > 0) {\n lines.push(` ${step++}. cp .env.example .env`);\n lines.push(` ${step++}. Edit .env to fill in:`);\n for (const v of envVars) {\n const dash = PROVIDER_DASHBOARDS[v];\n lines.push(` ${v}${dash ? ` (get it at ${dash})` : ''}`);\n }\n lines.push(\n ` (No keys? Switch llm.default.provider to \\`agent_bridge\\` in demo.yaml — uses your local Claude CLI instead.)`,\n );\n } else {\n lines.push(\n ` ${step++}. (.env not needed — agent_bridge LLM + ${resolved.tts} TTS don't use API keys.)`,\n );\n }\n\n lines.push(` ${step++}. Edit docs/PRD.md (the stub explains what each section is for).`);\n lines.push(` ${step++}. showrunner doctor -c demo.yaml`);\n lines.push(` ${step++}. showrunner run -c demo.yaml # → output/demo_final.mp4`);\n lines.push('');\n lines.push(\n `Don't want to write a PRD? Run \\`showrunner understand -c demo.yaml --interactive\\` instead — it asks 5 questions and builds the product model from your answers.`,\n );\n lines.push('');\n\n process.stdout.write(lines.join('\\n'));\n}\n\nconst PROVIDER_DASHBOARDS: Record<string, string> = {\n ANTHROPIC_API_KEY: 'https://console.anthropic.com/settings/keys',\n OPENAI_API_KEY: 'https://platform.openai.com/api-keys',\n ELEVENLABS_API_KEY: 'https://elevenlabs.io/app/settings/api-keys',\n};\n\nfunction requiredEnvVars(resolved: ResolvedInitOpts): string[] {\n const vars = new Set<string>();\n if (resolved.llm === 'anthropic') vars.add('ANTHROPIC_API_KEY');\n if (resolved.llm === 'openai') vars.add('OPENAI_API_KEY');\n if (resolved.tts === 'elevenlabs') vars.add('ELEVENLABS_API_KEY');\n if (resolved.tts === 'openai') vars.add('OPENAI_API_KEY');\n return [...vars];\n}\n\nfunction validateChoice<T extends string>(\n value: string | undefined,\n allowed: T[],\n defaultValue: T,\n flagName: string,\n): T {\n if (!value) return defaultValue;\n if (!allowed.includes(value as T)) {\n throw new Error(\n `${flagName} must be one of: ${allowed.join(', ')} (got \"${value}\")`,\n );\n }\n return value as T;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction demoYamlTemplate(opts: ResolvedInitOpts): string {\n return `# Showrunner demo config — edit me.\n# See https://github.com/your-org/showrunner for the full schema reference.\n\nproject:\n name: ${opts.name}\n # product_model: ./product_model.json # uncomment to skip comprehension\n\ncomprehension:\n mode: documents\n sources:\n - type: prd\n path: ./docs/PRD.md\n # - type: readme\n # path: ./README.md\n # - type: codebase\n # path: ./src\n # include: [\"**/*.ts\", \"**/*.tsx\"]\n\nscript:\n style: matter-of-fact\n duration_target_seconds: 90\n highlight_features: []\n # Set to true if you want the pipeline to halt after the script stage so you\n # can hand-edit scripts/vo_script.txt before voice synthesis runs. Resume\n # with: showrunner approve-vo -c demo.yaml\n vo_review_gate: false\n\nrecording:\n target_url: ${opts.url}\n # Resolution preset: ${opts.resolutionPreset} (${formatResolution(opts.resolution)}).\n # Rescaffold with --resolution low|standard|high|extreme, or change here and\n # keep output.resolution below in sync. \"showrunner doctor\" shows the live\n # ffmpeg thread cap so you can tell whether bigger is safe on your box.\n viewport:\n width: ${opts.resolution.width}\n height: ${opts.resolution.height}\n browser: chromium\n headless: false\n output_dir: ./segments/video\n state:\n seed_script: ./scripts/seed_demo_data.sh\n reset_script: ./scripts/reset_demo_data.sh\n teardown_script: ./scripts/teardown.sh\n # auth:\n # type: session\n # cookies_file: ./auth/session.json\n # local_storage_file: ./auth/storage.json\n\n${llmYamlBlock(opts.llm)}\n${voiceoverYamlBlock(opts.tts)}\noutput:\n format: mp4\n # Matches recording.viewport above (preset: ${opts.resolutionPreset}). Keep\n # these two values in sync to avoid upscaling artifacts during mux.\n resolution: ${formatResolution(opts.resolution)}\n fps: 30\n branding:\n title_card:\n enabled: true\n text: \"${opts.name}\"\n duration_seconds: 2\n font_size: 48\n text_color: \"#FFFFFF\"\n background_color: \"#0F172A\"\n logo_position: top_center\n outro_card:\n enabled: true\n text: \"thanks for watching\"\n duration_seconds: 2\n # background_music:\n # path: ./assets/bg_music.mp3\n # volume_db: -22\n output_path: ./output/demo_final.mp4\n`;\n}\n\nfunction llmYamlBlock(choice: LLMProviderChoice): string {\n switch (choice) {\n case 'anthropic':\n return `llm:\n default:\n provider: anthropic\n model: claude-opus-4-7\n api_key_env: ANTHROPIC_API_KEY\n # overrides:\n # script:\n # provider: agent_bridge\n # bridge:\n # mode: spawn\n # command: claude\n # args: [\"-p\", \"--output-format\", \"json\"]\n`;\n case 'openai':\n return `llm:\n default:\n provider: openai\n model: gpt-4o\n api_key_env: OPENAI_API_KEY\n`;\n case 'agent_bridge':\n return `llm:\n default:\n provider: agent_bridge\n bridge:\n mode: spawn\n # Headless agent CLI. Default is \\`claude -p --output-format json\\`.\n # Override per your installation.\n command: claude\n args: [\"-p\", \"--output-format\", \"json\"]\n # timeout_ms: 120000\n`;\n }\n}\n\nfunction voiceoverYamlBlock(choice: TTSProviderChoice): string {\n const tail = ` output_dir: ./segments/audio\n alignment_dir: ./segments/alignment\n duration_drift_threshold_pct: 15\n drift_strategy: adjust_timing\n tail_padding_ms: 500\n post_process:\n debreath: true\n pause_placement:\n strategy: action_boundaries\n min_silence_ms: 250\n snap_window_ms: 1200\n\n`;\n switch (choice) {\n case 'elevenlabs':\n return `voiceover:\n provider:\n name: elevenlabs\n voice_id: \"21m00Tcm4TlvDq8ikWAM\" # ElevenLabs default — replace with your chosen voice\n model: eleven_multilingual_v2\n api_key_env: ELEVENLABS_API_KEY\n endpoint: with_timestamps\n stability: 0.55\n similarity_boost: 0.75\n style: 0.0\n use_speaker_boost: true\n speed: 1.0\n # required: only ElevenLabs returns character alignment. Use best_effort with\n # other providers — captions degrade to whole-segment cues and at_word\n # actions fall back to at-time.\n alignment_strategy: required\n${tail}`;\n case 'openai':\n return `voiceover:\n provider:\n name: openai\n voice: alloy\n model: tts-1-hd\n api_key_env: OPENAI_API_KEY\n # base_url: https://api.openai.com/v1 # override for self-hosted gateways\n # OpenAI TTS does not return character alignment — must be best_effort.\n alignment_strategy: best_effort\n${tail}`;\n case 'custom':\n return `voiceover:\n provider:\n name: custom\n # Dynamic-import path resolved relative to this demo.yaml. The module's\n # default export must conform to the TTSProvider interface\n # (see src/providers/tts/types.ts in the Showrunner repo).\n module_path: ./tts_provider.mjs\n # options:\n # any_keys_you_want: true\n alignment_strategy: best_effort\n${tail}`;\n }\n}\n\nfunction envExampleTemplate(opts: ResolvedInitOpts): string {\n const vars = new Set<string>();\n if (opts.llm === 'anthropic') vars.add('ANTHROPIC_API_KEY');\n if (opts.llm === 'openai') vars.add('OPENAI_API_KEY');\n if (opts.tts === 'elevenlabs') vars.add('ELEVENLABS_API_KEY');\n if (opts.tts === 'openai') vars.add('OPENAI_API_KEY');\n\n const lines = [`# Showrunner secrets — copy to .env and fill in.`];\n for (const v of vars) lines.push(`${v}=`);\n if (vars.size === 0) {\n lines.push(`# (agent_bridge LLM + custom TTS — no provider env vars required)`);\n }\n lines.push('');\n lines.push(`# Optional: used by form / setup_script auth strategies.`);\n lines.push(`DEMO_EMAIL=`);\n lines.push(`DEMO_PASSWORD=`);\n lines.push('');\n lines.push(`# Optional log level: debug | info | warn | error`);\n lines.push(`SHOWRUNNER_LOG_LEVEL=info`);\n lines.push('');\n lines.push(`# Optional: cap libx264 threads when free memory is tight (e.g. WSL boxes).`);\n lines.push(`# SHOWRUNNER_FFMPEG_THREADS=2`);\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction gitignoreTemplate(): string {\n return `.env\n.env.local\n.env.*.local\n\n# Recording artifacts (large binaries)\nsegments/\noutput/\n\n# Captured auth state may contain sensitive tokens — uncomment if so\n# auth/*.json\n\n.showrunner-lock\n.showrunner-cache/\n\nplaywright-report/\ntest-results/\n\n*.log\n.DS_Store\n`;\n}\n\nfunction seedScript(): string {\n return `#!/usr/bin/env bash\n# seed_demo_data.sh — runs once before the recording session begins.\n# Use this to create demo users, seed records, and establish baseline state.\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID — unique identifier for this pipeline run\n#\n# Exit non-zero to halt the pipeline before recording starts.\n\nset -euo pipefail\n\necho \"[seed] noop — replace this script with your demo data seeding\"\n`;\n}\n\nfunction resetScript(): string {\n return `#!/usr/bin/env bash\n# reset_demo_data.sh — runs before each segment re-take.\n# Use this to undo mutations that previous takes may have introduced.\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID\n# SHOWRUNNER_SEGMENT_ID\n#\n# Not run on the initial full pipeline pass.\n\nset -euo pipefail\n\necho \"[reset] noop — replace this script with your per-segment reset logic\"\n`;\n}\n\nfunction teardownScript(): string {\n return `#!/usr/bin/env bash\n# teardown.sh — runs after the full session completes (success or failure).\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID\n# SHOWRUNNER_STATUS — \"success\" or \"failure\"\n#\n# Use this to clean up seeded data, close background processes, etc.\n\nset -euo pipefail\n\necho \"[teardown] noop (status=${'${SHOWRUNNER_STATUS:-unknown}'})\"\n`;\n}\n\nfunction starterManifest(opts: ResolvedInitOpts): string {\n const manifest = {\n total_duration_seconds: 8,\n generated_from: 'init-scaffold',\n segments: [\n {\n id: 'intro',\n label: 'Introduction',\n start: 0,\n end: 4,\n vo_line: `Welcome to ${opts.name}.`,\n actions: [{ type: 'idle', at: 0 }],\n transition: 'fade_in',\n },\n {\n id: 'outro',\n label: 'Outro',\n start: 4,\n end: 8,\n vo_line: 'Thanks for watching.',\n actions: [{ type: 'idle', at: 0 }],\n transition: 'fade_out',\n },\n ],\n };\n return JSON.stringify(manifest, null, 2) + '\\n';\n}\n\nfunction prdStubTemplate(opts: ResolvedInitOpts): string {\n return `# ${opts.name} — product brief\n\n> Fill in each section below. Showrunner's \\`understand\\` stage reads this file\n> and turns it into \\`product_model.json\\`, which the \\`script\\` stage then turns\n> into the manifest that drives recording + voiceover. The more concrete you\n> are here, the less you'll need to hand-edit the manifest afterwards.\n>\n> Delete these blockquote hints once you've replaced them with real content.\n\n## Elevator pitch\n\n> One paragraph (3–5 sentences). What is this product, who is it for, and what\n> single thing should a viewer walk away understanding? Write it like you'd\n> say it to a colleague over coffee, not like marketing copy.\n\n_Example:_ \"Atlas is a developer-facing log-tailing platform. It's for backend\nengineers who are tired of grepping through ssh sessions. The pitch is: paste a\nservice name, get a live, structured, queryable tail in under five seconds.\"\n\n## Primary user\n\n> One sentence on who the demo is for. Be specific about the role and the\n> moment they'd be watching this video.\n\n_Example:_ \"A backend engineer evaluating logging tools during a team-tooling\nreview.\"\n\n## Top 3 user flows (the demo's spine)\n\n> List the flows in the order the demo should walk through them. For each:\n> name the flow, one sentence describing what the user accomplishes, and any\n> selectors you already know are stable (data-testid is best). The script\n> stage will use this list as its outline.\n\n1. **Flow name** — what the user does (e.g. \"create their first project\").\n - Key selectors: \\`[data-testid=\"...\"]\\`, \\`[data-testid=\"...\"]\\`\n2. **Flow name** — what the user does.\n - Key selectors: ...\n3. **Flow name** — what the user does.\n - Key selectors: ...\n\n## Features to highlight\n\n> Bullet list. These get prioritized in the voiceover and on-screen timing.\n> Leave empty if you want the model to choose.\n\n- Feature A\n- Feature B\n\n## What this demo is NOT\n\n> Optional but useful. Things to *avoid* spending time on — admin pages,\n> settings, the auth flow, anything aspirational.\n\n- Don't show the settings page.\n- Don't mention pricing.\n\n## Tone / style\n\n> One line. Matches \\`script.style\\` in demo.yaml.\n\n_Default:_ matter-of-fact, technical, no marketing fluff.\n`;\n}\n\nfunction readmeTemplate(opts: ResolvedInitOpts): string {\n return `# ${opts.name}\n\nA Showrunner project. The pipeline runs in stages:\n\n1. **Comprehension** — reads docs and code, builds \\`product_model.json\\` (LLM: ${opts.llm})\n2. **Script** — turns the product model into \\`scripts/manifest.json\\` (LLM: ${opts.llm})\n3. **Record + Voiceover** — runs Playwright against ${opts.url} while synthesizing VO (TTS: ${opts.tts})\n4. **Mux** — combines everything into \\`output/demo_final.mp4\\`\n\n## First run\n\n\\`\\`\\`bash\ncp .env.example .env # then fill in keys\n$EDITOR docs/PRD.md # replace the stub with your product brief\nshowrunner doctor --config demo.yaml # preflight\nshowrunner understand --config demo.yaml # build product_model.json\nshowrunner run --config demo.yaml # script → record → voiceover → mux\nopen output/demo_final.mp4\n\\`\\`\\`\n\nIf \\`understand\\` doesn't feel ready, swap it for \\`showrunner understand --config demo.yaml --interactive\\`\nand answer five questions — it'll generate the product model without needing a PRD.\n\n## Customize\n\n- \\`demo.yaml\\` — main config (LLM + TTS provider sections are at the top of the file)\n- \\`docs/PRD.md\\` — product brief consumed by \\`understand\\`. Replace the stub with real content.\n- \\`scripts/seed_demo_data.sh\\` — environment prep before recording\n- \\`scripts/reset_demo_data.sh\\` — per-segment re-take prep\n- \\`scripts/teardown.sh\\` — cleanup\n\n## Re-record a single segment\n\nIf the LLM-generated manifest picks a busted selector and one segment fails,\ndemonstrate the right interaction in a live browser instead:\n\n\\`\\`\\`bash\nshowrunner record-actions --config demo.yaml --segment <segment-id>\n\\`\\`\\`\n\nShowrunner will replace that segment's actions with what you did.\n\n## Swap providers\n\nYou can change provider per-section in \\`demo.yaml\\` without re-running init. The\nschema accepts:\n\n- **LLM** (\\`llm.default.provider\\`): \\`anthropic\\`, \\`openai\\`, \\`agent_bridge\\`, \\`custom\\`\n- **TTS** (\\`voiceover.provider.name\\`): \\`elevenlabs\\`, \\`openai\\`, \\`custom\\`\n\nOnly ElevenLabs returns per-character alignment. Other TTS providers force\n\\`voiceover.alignment_strategy: best_effort\\` (captions become whole-segment cues\nand \\`at_word\\` actions degrade to \\`at\\`).\n`;\n}\n","import { spawn } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { logger } from '../util/logger.js';\n\ninterface InstallBrowserOpts {\n browser?: string;\n}\n\nconst DEFAULT_BROWSER = 'chromium';\n\nexport async function installBrowserCommand(opts: InstallBrowserOpts): Promise<void> {\n const browser = opts.browser ?? DEFAULT_BROWSER;\n const cli = await resolvePlaywrightCoreCli();\n\n logger.info(`installing Playwright ${browser} (via bundled playwright-core, no project required)`);\n // playwright-core's cli.js skips the \"install your project's dependencies first\" warning\n // that plain `npx playwright install` shows when invoked outside a project.\n const child = spawn(process.execPath, [cli, 'install', browser], {\n stdio: 'inherit',\n env: process.env,\n });\n const code: number = await new Promise((resolve, reject) => {\n child.on('error', reject);\n child.on('close', (c) => resolve(c ?? 0));\n });\n if (code !== 0) {\n logger.error(`playwright install exited with code ${code}`);\n process.exit(code);\n }\n logger.info(`${browser} installed. Try \\`showrunner doctor -c demo.yaml\\` next.`);\n}\n\nasync function resolvePlaywrightCoreCli(): Promise<string> {\n // Walk up from this module to the showrunner package root, then locate\n // playwright-core inside its node_modules. This works both when showrunner\n // is installed globally and when invoked via tsx during development.\n const here = fileURLToPath(import.meta.url);\n let dir = dirname(here);\n const root = dir.split(/[\\\\/]/)[0] + '/';\n while (dir && dir !== root) {\n const candidate = join(dir, 'node_modules', 'playwright-core', 'cli.js');\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next ancestor\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n 'Could not locate playwright-core CLI inside Showrunner\\'s node_modules. ' +\n 'This is a packaging bug — please file an issue.',\n );\n}\n","import { stat } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { logger } from '../util/logger.js';\nimport type { ShowrunnerConfig } from '../config/schema.js';\nimport { formatMissingEnvVars, inspectProviderEnv } from '../config/providerEnv.js';\n\ninterface ValidateOpts {\n config: string;\n strict?: boolean;\n}\n\nexport async function validateCommand(opts: ValidateOpts): Promise<void> {\n // Load .env so api_key_env vars resolve the same way `run` would see them.\n try {\n process.loadEnvFile?.();\n } catch {\n // No .env present — fine.\n }\n\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const warnings: string[] = [];\n warnings.push(...(await checkReferencedPaths(loaded.config, loaded.configDir)));\n warnings.push(...formatMissingEnvVars(inspectProviderEnv(loaded.config)));\n\n if (warnings.length > 0) {\n for (const w of warnings) logger.warn(w);\n logger.info(\n `Config is structurally valid but ${warnings.length} issue(s) found.`,\n );\n if (opts.strict) {\n process.exit(1);\n }\n } else {\n logger.info('Config is valid.');\n }\n}\n\nasync function checkReferencedPaths(config: ShowrunnerConfig, configDir: string): Promise<string[]> {\n const warnings: string[] = [];\n const check = async (relPath: string | undefined, label: string): Promise<void> => {\n if (!relPath) return;\n const abs = isAbsolute(relPath) ? relPath : resolve(configDir, relPath);\n try {\n await stat(abs);\n } catch {\n warnings.push(`${label} not found: ${abs}`);\n }\n };\n\n await check(config.project.product_model, 'project.product_model');\n for (const s of config.comprehension.sources) {\n await check(s.path, `comprehension.sources[${s.type}].path`);\n }\n\n if (config.recording.auth?.type === 'session') {\n await check(config.recording.auth.cookies_file, 'recording.auth.cookies_file');\n if (config.recording.auth.local_storage_file) {\n await check(config.recording.auth.local_storage_file, 'recording.auth.local_storage_file');\n }\n }\n if (config.recording.auth?.type === 'setup_script') {\n await check(config.recording.auth.path, 'recording.auth.path');\n }\n\n await check(config.recording.state.seed_script, 'recording.state.seed_script');\n await check(config.recording.state.reset_script, 'recording.state.reset_script');\n await check(config.recording.state.teardown_script, 'recording.state.teardown_script');\n\n await check(config.output.branding.title_card?.font, 'output.branding.title_card.font');\n await check(config.output.branding.title_card?.logo, 'output.branding.title_card.logo');\n await check(config.output.background_music?.path, 'output.background_music.path');\n\n return warnings;\n}\n","import { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { renderVoScript } from '../manifest/voScript.js';\nimport { logger } from '../util/logger.js';\n\ninterface PrintVoOpts {\n config: string;\n}\n\nexport async function printVoCommand(opts: PrintVoOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const manifestPath = resolve(loaded.configDir, './scripts/manifest.json');\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const text = renderVoScript(manifest, { projectName: loaded.config.project.name });\n process.stdout.write(text);\n}\n","import { rm, stat } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport { readAndMergeVoScript, VoScriptMergeError } from '../manifest/voScript.js';\nimport { logger } from '../util/logger.js';\n\ninterface ApproveVoOpts {\n config: string;\n}\n\nexport async function approveVoCommand(opts: ApproveVoOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const manifestPath = resolve(loaded.configDir, './scripts/manifest.json');\n const voScriptPath = resolve(loaded.configDir, './scripts/vo_script.txt');\n const lockPath = resolve(loaded.configDir, '.showrunner-lock');\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n if (!(await pathExists(voScriptPath))) {\n logger.error(`VO script not found: ${voScriptPath}. Run \\`showrunner run\\` first.`);\n process.exit(1);\n }\n\n let merged;\n try {\n merged = await readAndMergeVoScript(voScriptPath, manifest);\n } catch (err) {\n if (err instanceof VoScriptMergeError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n await writeManifest(manifestPath, merged);\n if (await pathExists(lockPath)) {\n await rm(lockPath);\n }\n\n logger.info('VO edits merged into manifest. Resume with `showrunner run --config <path>`.');\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { chromium, firefox, webkit } from 'playwright-core';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { buildAuthPlan, AuthError } from '../recording/auth.js';\nimport { executeAction } from '../recording/actions.js';\nimport { ensureCursorInstalled, installCursorOverlay } from '../recording/cursorOverlay.js';\nimport {\n runLifecycleScript,\n LifecycleScriptError,\n} from '../recording/lifecycle.js';\nimport { generateRunId } from '../util/runId.js';\nimport { logger } from '../util/logger.js';\nimport type { Segment } from '../manifest/schema.js';\n\ninterface RerunOpts {\n config: string;\n segment: string;\n}\n\nconst RERUN_BUFFER_MS = 500;\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function rerunSegmentCommand(opts: RerunOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const { config, configDir } = loaded;\n const manifestPath = resolve(configDir, './scripts/manifest.json');\n const videoDir = resolve(configDir, config.recording.output_dir);\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const segment: Segment | undefined = manifest.segments.find((s) => s.id === opts.segment);\n if (!segment) {\n logger.error(\n `Segment \"${opts.segment}\" not found in manifest. Known: ${manifest.segments.map((s) => s.id).join(', ')}`,\n );\n process.exit(1);\n }\n\n const runId = generateRunId();\n const baseEnv = { SHOWRUNNER_RUN_ID: runId, SHOWRUNNER_SEGMENT_ID: segment.id };\n\n if (config.recording.state.reset_script) {\n try {\n await runLifecycleScript({\n scriptPath: config.recording.state.reset_script,\n configDir,\n env: baseEnv,\n label: 'reset',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n logger.error(`reset script failed: ${err.message}`);\n process.exit(1);\n }\n throw err;\n }\n }\n\n await mkdir(videoDir, { recursive: true });\n\n let authPlan;\n try {\n authPlan = await buildAuthPlan(config.recording.auth, configDir);\n } catch (err) {\n if (err instanceof AuthError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const browser = await browserMap[config.recording.browser].launch({\n headless: config.recording.headless,\n });\n try {\n let storageState = authPlan.storageState;\n if (storageState === undefined && authPlan.postLaunch) {\n const authCtx = await browser.newContext({\n viewport: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n });\n try {\n const authPage = await authCtx.newPage();\n await authPage.goto(config.recording.target_url);\n await authPlan.postLaunch(authPage);\n storageState = await authCtx.storageState();\n } finally {\n await authCtx.close();\n }\n }\n\n const ctx = await browser.newContext({\n viewport: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n recordVideo: {\n dir: videoDir,\n size: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n },\n storageState,\n });\n if (config.recording.cursor_highlight) {\n await installCursorOverlay(ctx);\n }\n await ctx.tracing.start({ screenshots: true, snapshots: true, sources: true });\n\n const page = await ctx.newPage();\n await page.goto(config.recording.target_url);\n if (config.recording.cursor_highlight) {\n await ensureCursorInstalled(page);\n }\n await page.waitForTimeout(RERUN_BUFFER_MS);\n\n await ctx.tracing.startChunk({ title: segment.id });\n let failure: string | undefined;\n const warnings: string[] = [];\n for (const action of segment.actions) {\n const outcome = await executeAction(page, action, {\n cursorEnabled: config.recording.cursor_highlight,\n });\n if (outcome.status === 'skipped') {\n warnings.push(`${action.type}: ${outcome.reason}`);\n logger.warn(`${action.type} skipped`, { reason: outcome.reason });\n } else if (outcome.status === 'segment_failed') {\n failure = outcome.reason;\n logger.error(`segment ${segment.id} failed`, { reason: outcome.reason });\n break;\n }\n }\n await page.waitForTimeout(config.recording.segment_buffer_ms);\n const traceDir = resolve(configDir, config.recording.trace_dir);\n await mkdir(traceDir, { recursive: true });\n await ctx.tracing.stopChunk({ path: join(traceDir, `${segment.id}.zip`) });\n\n const videoHandle = page.video();\n await ctx.close();\n\n if (!videoHandle) {\n logger.error('No video captured — recordVideo may have been ignored');\n process.exit(1);\n }\n const original = await videoHandle.path();\n const dest = join(videoDir, `${segment.id}.webm`);\n await rename(original, dest);\n\n const metadataPath = join(videoDir, `${segment.id}.rerun.json`);\n await writeFile(\n metadataPath,\n JSON.stringify(\n {\n segment_id: segment.id,\n run_id: runId,\n recorded_at: new Date().toISOString(),\n rerun_buffer_ms: RERUN_BUFFER_MS,\n status: failure ? 'failed' : 'ok',\n failure_reason: failure,\n warnings,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n logger.info(`Segment ${segment.id} re-recorded → ${dest}`, { metadata: metadataPath });\n if (failure) {\n process.exit(1);\n }\n } finally {\n await browser.close();\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { launchHeadedSession } from '../recording/headed.js';\nimport { logger } from '../util/logger.js';\n\nexport interface CaptureAuthOpts {\n config: string;\n outputCookies?: string;\n outputStorage?: string;\n}\n\nexport async function captureAuthCommand(opts: CaptureAuthOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const cookiesRel = opts.outputCookies ?? './auth/session.json';\n const cookiesPath = isAbsolute(cookiesRel) ? cookiesRel : resolve(loaded.configDir, cookiesRel);\n await mkdir(dirname(cookiesPath), { recursive: true });\n\n logger.info('Launching headed browser for auth capture', {\n target: loaded.config.recording.target_url,\n output: cookiesPath,\n });\n\n const session = await launchHeadedSession({\n recording: loaded.config.recording,\n configDir: loaded.configDir,\n recordVideo: false,\n withCursor: false,\n applyAuth: false,\n });\n\n try {\n await session.page.goto(loaded.config.recording.target_url);\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n process.stdout.write(\n '\\nLog in to the target app in the browser window, then return here.\\n' +\n 'Press Enter to capture the session state (or Ctrl+C to abort): ',\n );\n await rl.question('');\n rl.close();\n\n await session.context.storageState({ path: cookiesPath });\n logger.info('Captured storage state', { path: cookiesPath });\n\n process.stdout.write(\n `\\nDone. To use this session, set the following in your demo.yaml:\\n\\n` +\n ` recording:\\n` +\n ` auth:\\n` +\n ` type: session\\n` +\n ` cookies_file: ${cookiesRel}\\n\\n` +\n `Then re-run \\`showrunner run --config <demo.yaml>\\`.\\n`,\n );\n } finally {\n await session.close();\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type BrowserContextOptions,\n type Page,\n} from 'playwright-core';\nimport type { RecordingConfig } from '../config/schema.js';\nimport { buildAuthPlan } from './auth.js';\nimport {\n ensureCursorInstalled,\n installCursorOverlay,\n verifyCursorMounted,\n} from './cursorOverlay.js';\nimport { logger } from '../util/logger.js';\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport interface HeadedSessionOptions {\n recording: RecordingConfig;\n configDir: string;\n /** When true, record video to recording.output_dir. Defaults to false. */\n recordVideo?: boolean;\n /** When true, install the showrunner cursor overlay. Defaults to false. */\n withCursor?: boolean;\n /**\n * When true, run any pre-configured `auth` plan before returning the page.\n * Defaults to false — most interactive commands (capture-auth, record-actions)\n * want a fresh, unauthenticated browser so the operator can drive it.\n */\n applyAuth?: boolean;\n}\n\nexport interface HeadedSession {\n browser: Browser;\n context: BrowserContext;\n page: Page;\n close(): Promise<void>;\n}\n\nexport async function launchHeadedSession(opts: HeadedSessionOptions): Promise<HeadedSession> {\n const { recording, configDir } = opts;\n const browser = await browserMap[recording.browser].launch({ headless: false });\n\n const contextOptions: BrowserContextOptions = {\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n };\n\n if (opts.recordVideo) {\n const videoDir = resolve(configDir, recording.output_dir);\n await mkdir(videoDir, { recursive: true });\n contextOptions.recordVideo = {\n dir: videoDir,\n size: { width: recording.viewport.width, height: recording.viewport.height },\n };\n }\n\n if (opts.applyAuth) {\n const authPlan = await buildAuthPlan(recording.auth, configDir);\n if (authPlan.storageState !== undefined) {\n contextOptions.storageState = authPlan.storageState;\n } else if (authPlan.postLaunch) {\n const authContext = 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 contextOptions.storageState = await authContext.storageState();\n } finally {\n await authContext.close();\n }\n }\n }\n\n const context = await browser.newContext(contextOptions);\n\n if (opts.withCursor) {\n await installCursorOverlay(context);\n }\n\n const page = await context.newPage();\n\n if (opts.withCursor) {\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\n return {\n browser,\n context,\n page,\n async close() {\n await context.close();\n await browser.close();\n },\n };\n}\n\nexport async function ensureCursorForHeaded(page: Page): Promise<void> {\n await ensureCursorInstalled(page);\n const mounted = await verifyCursorMounted(page);\n logger.debug(`cursor overlay mount check: ${mounted ? 'OK' : 'NOT FOUND'}`);\n}\n","import { readdir, stat } from 'node:fs/promises';\nimport { isAbsolute, join, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readSlicePlan } from '../mux/slice.js';\nimport { runCommand, LifecycleScriptError } from '../recording/lifecycle.js';\nimport { logger } from '../util/logger.js';\n\nexport interface TraceOpts {\n config: string;\n segment?: string;\n all?: boolean;\n}\n\nexport async function traceCommand(opts: TraceOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const traceDir = resolve(loaded.configDir, loaded.config.recording.trace_dir);\n const videoDir = resolve(loaded.configDir, loaded.config.recording.output_dir);\n const slicePlanPath = join(videoDir, 'slice_plan.json');\n\n if (opts.all) {\n let plan;\n try {\n plan = await readSlicePlan(slicePlanPath);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n logger.error(`Could not read slice_plan.json at ${slicePlanPath}: ${cause}`);\n process.exit(1);\n }\n for (const seg of plan.segments) {\n const tracePath = seg.trace_path && isAbsolute(seg.trace_path)\n ? seg.trace_path\n : seg.trace_path\n ? resolve(loaded.configDir, seg.trace_path)\n : join(traceDir, `${seg.id}.zip`);\n logger.info(`Opening trace for ${seg.id}`, { path: tracePath });\n await openTrace(tracePath);\n }\n return;\n }\n\n if (opts.segment) {\n const tracePath = join(traceDir, `${opts.segment}.zip`);\n if (!(await fileExists(tracePath))) {\n logger.error(`No trace found at ${tracePath}`);\n process.exit(1);\n }\n await openTrace(tracePath);\n return;\n }\n\n const available = await listTraces(traceDir);\n if (available.length === 0) {\n logger.error(`No .zip traces in ${traceDir}. Run \\`showrunner run\\` first.`);\n process.exit(1);\n }\n process.stdout.write(`Available traces in ${traceDir}:\\n`);\n for (const name of available) process.stdout.write(` ${name}\\n`);\n process.stdout.write(\n `\\nRe-run with --segment <id> to open one, or --all to open every trace.\\n`,\n );\n}\n\nasync function openTrace(tracePath: string): Promise<void> {\n try {\n await runCommand({\n cmd: 'npx',\n args: ['playwright', 'show-trace', tracePath],\n label: 'trace',\n inherit: true,\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n // exit code from show-trace can be non-zero on window close; not fatal\n logger.debug(`trace viewer exited`, { code: err.exitCode });\n } else {\n throw err;\n }\n }\n}\n\nasync function listTraces(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir);\n return entries.filter((e) => e.endsWith('.zip')).sort();\n } catch {\n return [];\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 } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { runCommand, LifecycleScriptError } from '../recording/lifecycle.js';\nimport { logger } from '../util/logger.js';\n\nexport interface PreviewOpts {\n config: string;\n}\n\nexport async function previewCommand(opts: PreviewOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const previewSpec = resolve(loaded.configDir, './scripts/playwright_demo.spec.ts');\n if (!(await fileExists(previewSpec))) {\n logger.error(\n `No preview spec at ${previewSpec}. Run \\`showrunner run --stages script\\` first to generate it.`,\n );\n process.exit(1);\n }\n\n logger.info('Opening Playwright UI Mode for preview', { spec: previewSpec });\n\n try {\n await runCommand({\n cmd: 'npx',\n args: ['playwright', 'test', '--ui', previewSpec],\n cwd: loaded.configDir,\n label: 'preview',\n inherit: true,\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n logger.debug(`preview UI exited`, { code: err.exitCode });\n } else {\n throw err;\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, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport {\n generateProductModelFromDocs,\n generateProductModelFromInteractive,\n ProductModelGenerationError,\n} from '../productModel/generate.js';\nimport { runInteractiveQA } from '../productModel/interactive.js';\nimport type { DocSource } from '../productModel/prompts.js';\nimport { resolveDefaultLLMProvider } from '../providers/llm/resolveFromContext.js';\nimport { logger } from '../util/logger.js';\n\nexport interface UnderstandOpts {\n config?: string;\n interactive?: boolean;\n output?: string;\n}\n\nexport async function understandCommand(opts: UnderstandOpts): Promise<void> {\n let configDir = process.cwd();\n let outputRel = opts.output ?? './product_model.json';\n let sources: { path: string; type: string }[] = [];\n let llmConfig: import('../config/schema.js').LLMConfig | undefined;\n\n if (opts.config) {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n configDir = loaded.configDir;\n // Precedence: explicit --output > config.project.product_model > default.\n if (!opts.output && loaded.config.project.product_model) {\n outputRel = loaded.config.project.product_model;\n }\n sources = loaded.config.comprehension.sources.map((s) => ({ path: s.path, type: s.type }));\n llmConfig = loaded.config.llm;\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n }\n\n const outputPath = isAbsolute(outputRel) ? outputRel : resolve(configDir, outputRel);\n await mkdir(dirname(outputPath), { recursive: true });\n\n let productModel;\n const provider = resolveDefaultLLMProvider({ configDir, llm: llmConfig });\n try {\n if (opts.interactive) {\n const answers = await runInteractiveQA();\n logger.info('Generating product_model from interactive answers');\n productModel = await generateProductModelFromInteractive({ answers, provider });\n } else {\n if (sources.length === 0) {\n logger.error(\n 'No `comprehension.sources` configured in demo.yaml. Add at least one source ' +\n '(prd, readme, codebase, etc.) or re-run with --interactive.',\n );\n process.exit(2);\n }\n const docs: DocSource[] = [];\n for (const src of sources) {\n const abs = isAbsolute(src.path) ? src.path : resolve(configDir, src.path);\n try {\n const content = await readFile(abs, 'utf8');\n docs.push({ path: src.path, type: src.type, content });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n logger.warn(`Skipping source ${abs}: ${cause}`);\n }\n }\n if (docs.length === 0) {\n logger.error('No comprehension sources could be read.');\n process.exit(2);\n }\n logger.info('Generating product_model from documents', {\n sources: docs.map((d) => d.path),\n });\n productModel = await generateProductModelFromDocs({ sources: docs, provider });\n }\n } catch (err) {\n if (err instanceof ProductModelGenerationError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n await writeFile(outputPath, JSON.stringify(productModel, null, 2) + '\\n', 'utf8');\n logger.info('Wrote product_model.json', { path: outputPath });\n}\n","export const PRODUCT_MODEL_SYSTEM_PROMPT = `You build product_model.json for Showrunner, an automated product demo recorder.\n\nA product model is a tight, structured description of a web app: what it is, who uses it, and the 2–4 most important flows worth demoing. Showrunner later uses this to write a 60–90 second demo script.\n\nRules:\n- product_name: short, exact product name as branded.\n- tagline: one sentence, 8–15 words, plain language.\n- primary_user: one short phrase describing who the product is for.\n- core_flows: 2–4 flows. Each flow has an id (kebab-case), a name, a steps array (3–6 imperative steps from the user's POV), and an optional entry_url.\n- key_features: 3–6 short bullets, no marketing fluff.\n- demo_recommendation.suggested_flows: ids drawn from core_flows, in the order they should appear in the demo.\n- demo_recommendation.suggested_duration_seconds: realistic total runtime including intro and outro. Typical: 60–90.\n- confidence: 'high' if the source materials clearly describe the product; 'medium' if you had to infer; 'low' if you mostly guessed.\n- source: 'documents' when synthesized from supplied text; 'interactive' when from Q&A answers.\n- generated_at: ISO-8601 timestamp.\n\nOutput exactly the structured JSON requested. No prose, no commentary.`;\n\nexport interface DocSource {\n path: string;\n type: string;\n content: string;\n}\n\nexport function renderProductModelDocPrompt(sources: DocSource[]): string {\n const blocks = sources\n .map((s) => {\n const trimmed = s.content.length > 12000 ? s.content.slice(0, 12000) + '\\n…[truncated]' : s.content;\n return `=== ${s.type.toUpperCase()} ${s.path} ===\\n${trimmed}\\n=== END ${s.path} ===`;\n })\n .join('\\n\\n');\n\n return `You have the following source documents describing a product. Synthesize them into a product_model.json. Set source to 'documents'.\\n\\n${blocks}`;\n}\n\nexport interface InteractiveAnswers {\n productName: string;\n primaryUser: string;\n tagline: string;\n topFeatures: string[];\n topFlows: { name: string; steps: string[] }[];\n suggestedDurationSeconds: number;\n}\n\nexport function renderProductModelInteractivePrompt(a: InteractiveAnswers): string {\n return `An operator answered the following questions about their product. Build a product_model.json from their answers. Set source to 'interactive'. If an answer is sparse, make reasonable inferences but keep confidence honest ('medium' or 'low').\n\nproduct_name: ${a.productName}\nprimary_user: ${a.primaryUser}\ntagline: ${a.tagline}\ntop_features:\n${a.topFeatures.map((f) => ` - ${f}`).join('\\n')}\ntop_flows:\n${a.topFlows\n .map(\n (f, i) => ` ${i + 1}. ${f.name}\\n steps:\\n${f.steps.map((s) => ` - ${s}`).join('\\n')}`,\n )\n .join('\\n')}\nsuggested_duration_seconds: ${a.suggestedDurationSeconds}`;\n}\n","import { productModelSchema, type ProductModel } from './schema.js';\nimport { logger } from '../util/logger.js';\nimport {\n PRODUCT_MODEL_SYSTEM_PROMPT,\n renderProductModelDocPrompt,\n renderProductModelInteractivePrompt,\n type DocSource,\n type InteractiveAnswers,\n} from './prompts.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\nimport { generateWithRetry } from '../providers/llm/withRetry.js';\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nexport class ProductModelGenerationError extends Error {\n override readonly name = 'ProductModelGenerationError';\n}\n\nexport interface GenerateFromDocsOptions {\n sources: DocSource[];\n provider: LLMProvider;\n}\n\nexport interface GenerateFromInteractiveOptions {\n answers: InteractiveAnswers;\n provider: LLMProvider;\n}\n\nexport async function generateProductModelFromDocs(\n opts: GenerateFromDocsOptions,\n): Promise<ProductModel> {\n if (opts.sources.length === 0) {\n throw new ProductModelGenerationError(\n 'No source documents provided. Add entries under `comprehension.sources` in demo.yaml.',\n );\n }\n const userPrompt = renderProductModelDocPrompt(opts.sources);\n return callProvider(opts.provider, userPrompt, 'documents');\n}\n\nexport async function generateProductModelFromInteractive(\n opts: GenerateFromInteractiveOptions,\n): Promise<ProductModel> {\n const userPrompt = renderProductModelInteractivePrompt(opts.answers);\n return callProvider(opts.provider, userPrompt, 'interactive');\n}\n\nasync function callProvider(\n provider: LLMProvider,\n userPrompt: string,\n sourceTag: 'documents' | 'interactive',\n): Promise<ProductModel> {\n logger.debug('Generating product_model via LLM provider', { source: sourceTag });\n try {\n return await generateWithRetry(provider, {\n systemPrompt: PRODUCT_MODEL_SYSTEM_PROMPT,\n userPrompt,\n schema: productModelSchema,\n schemaName: 'product_model',\n maxTokens: DEFAULT_MAX_TOKENS,\n retryRenderer: (errorText, prevUserPrompt) =>\n `${prevUserPrompt}\\n\\nYour previous output failed validation with this error:\\n${errorText}\\n\\nRegenerate the product_model strictly matching the schema.`,\n });\n } catch (err) {\n throw new ProductModelGenerationError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { createInterface, type Interface as ReadlineInterface } from 'node:readline';\nimport type { InteractiveAnswers } from './prompts.js';\n\n/**\n * Buffered line reader on top of readline.Interface. Two reasons to queue\n * rather than use `rl.question()` / `rl.once('line')` directly:\n *\n * 1. `readline/promises` `rl.question()` has a documented edge case where\n * the second-or-third call silently exits when stdin is piped (non-TTY).\n * 2. With piped stdin, all lines arrive in a burst; if we only register a\n * one-shot 'line' listener per ask(), every line after the first fires\n * with no listener and is lost. Queueing preserves them for later asks.\n */\nclass LineReader {\n private queue: string[] = [];\n private waiter: ((line: string) => void) | null = null;\n private rejecter: ((err: Error) => void) | null = null;\n private closed = false;\n\n constructor(rl: ReadlineInterface) {\n rl.on('line', (line: string) => {\n if (this.waiter) {\n const cb = this.waiter;\n this.waiter = null;\n this.rejecter = null;\n cb(line);\n } else {\n this.queue.push(line);\n }\n });\n rl.on('close', () => {\n this.closed = true;\n if (this.rejecter) {\n const rej = this.rejecter;\n this.waiter = null;\n this.rejecter = null;\n rej(new Error('stdin closed before answer was provided'));\n }\n });\n }\n\n read(): Promise<string> {\n if (this.queue.length > 0) {\n return Promise.resolve(this.queue.shift()!);\n }\n if (this.closed) {\n return Promise.reject(new Error('stdin closed before answer was provided'));\n }\n return new Promise<string>((resolve, reject) => {\n this.waiter = resolve;\n this.rejecter = reject;\n });\n }\n}\n\nasync function ask(reader: LineReader, prompt: string): Promise<string> {\n process.stdout.write(prompt);\n return reader.read();\n}\n\nexport async function runInteractiveQA(): Promise<InteractiveAnswers> {\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false });\n const reader = new LineReader(rl);\n\n try {\n process.stdout.write(\n '\\nLet\\'s build a product_model interactively. Answer each prompt with a short line.\\n\\n',\n );\n const productName = (await ask(reader, '1. Product name: ')).trim();\n if (!productName) throw new Error('product name is required');\n\n const tagline = (await ask(reader, '2. One-sentence tagline: ')).trim();\n const primaryUser = (await ask(reader, '3. Who is the primary user? ')).trim();\n\n const featuresLine = (\n await ask(reader, '4. Top 3-6 features, comma-separated:\\n ')\n ).trim();\n const topFeatures = featuresLine\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const flowCountStr = (\n await ask(reader, '5. How many flows would you like to demo (2-4)? ')\n ).trim();\n const flowCount = clamp(parseInt(flowCountStr, 10) || 2, 2, 4);\n const topFlows: { name: string; steps: string[] }[] = [];\n for (let i = 0; i < flowCount; i++) {\n const name = (await ask(reader, ` Flow ${i + 1} name: `)).trim();\n const stepsLine = (\n await ask(reader, ` Flow ${i + 1} steps, '|' separated:\\n `)\n ).trim();\n const steps = stepsLine\n .split('|')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n topFlows.push({ name, steps });\n }\n\n const durationStr = (\n await ask(reader, '6. Target demo duration in seconds (60-120, default 75): ')\n ).trim();\n const suggestedDurationSeconds = clamp(parseInt(durationStr, 10) || 75, 30, 180);\n\n return {\n productName,\n primaryUser,\n tagline,\n topFeatures,\n topFlows,\n suggestedDurationSeconds,\n };\n } finally {\n rl.close();\n }\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n));\n}\n","import { mkdir, readdir, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve, relative } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { scanFile, type InstrumentCandidate } from '../instrument/scan.js';\nimport { suggestTestIds, InstrumentSuggestionError } from '../instrument/suggest.js';\nimport { buildDiff } from '../instrument/diff.js';\nimport { resolveDefaultLLMProvider } from '../providers/llm/resolveFromContext.js';\nimport { logger } from '../util/logger.js';\n\nexport interface InstrumentOpts {\n config: string;\n output: string;\n glob?: string;\n}\n\nexport async function instrumentCommand(opts: InstrumentOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const codebaseSources = loaded.config.comprehension.sources.filter((s) => s.type === 'codebase');\n if (codebaseSources.length === 0 && !opts.glob) {\n logger.error(\n 'No `comprehension.sources` with type=codebase found in demo.yaml, and no --glob provided.',\n );\n process.exit(2);\n }\n\n const filesToScan = new Set<string>();\n const IGNORED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'out']);\n\n async function walk(root: string, accept: (rel: string) => boolean): Promise<void> {\n const entries = await readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const abs = join(root, entry.name);\n if (entry.isDirectory()) {\n if (IGNORED_DIRS.has(entry.name)) continue;\n await walk(abs, accept);\n } else if (entry.isFile() && accept(relative(root, abs))) {\n filesToScan.add(abs);\n }\n }\n }\n\n const isJsxFile = (p: string): boolean => /\\.(tsx|jsx)$/.test(p);\n\n if (opts.glob) {\n // Lightweight glob: treat the pattern as \"match if path contains the pattern\n // stripped of leading **/ or trailing /**\", with extension filter via isJsxFile.\n // For accurate glob matching, users can be explicit with file extensions.\n const root = loaded.configDir;\n await walk(root, isJsxFile);\n } else {\n for (const src of codebaseSources) {\n const root = isAbsolute(src.path) ? src.path : resolve(loaded.configDir, src.path);\n await walk(root, isJsxFile);\n }\n }\n\n if (filesToScan.size === 0) {\n logger.error('No JSX/TSX files matched. Check comprehension.sources or --glob.');\n process.exit(2);\n }\n\n logger.info('Scanning files for instrumentation candidates', { files: filesToScan.size });\n\n const candidates: InstrumentCandidate[] = [];\n for (const file of filesToScan) {\n const found = await scanFile(file);\n candidates.push(...found);\n }\n\n if (candidates.length === 0) {\n logger.info('No unstable elements found — every targetable element already has data-testid or aria-label.');\n process.exit(0);\n }\n logger.info('Found instrumentation candidates', { count: candidates.length });\n\n let suggestions;\n try {\n const provider = resolveDefaultLLMProvider({\n configDir: loaded.configDir,\n llm: loaded.config.llm,\n });\n suggestions = await suggestTestIds({ candidates, provider });\n } catch (err) {\n if (err instanceof InstrumentSuggestionError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n if (suggestions.length === 0) {\n logger.info('Anthropic returned no suggestions.');\n process.exit(0);\n }\n\n const { patch, skipped } = await buildDiff(suggestions, { basePath: loaded.configDir });\n for (const s of skipped) {\n logger.warn(`Skipped suggestion at ${s.file}:${s.line} — ${s.reason}`);\n }\n\n const outputPath = isAbsolute(opts.output) ? opts.output : resolve(loaded.configDir, opts.output);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, patch, 'utf8');\n logger.info('Wrote instrumentation patch', { path: outputPath, suggestions: suggestions.length });\n process.stdout.write(`\\nApply with: cd ${loaded.configDir} && git apply ${opts.output}\\n\\n`);\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse } from '@babel/parser';\nimport _traverse from '@babel/traverse';\nimport type { NodePath } from '@babel/traverse';\nimport type {\n JSXAttribute,\n JSXOpeningElement,\n JSXIdentifier,\n} from '@babel/types';\n\n// @babel/traverse ships CJS default in an ESM-incompatible way; unwrap it.\nconst traverse = (_traverse as unknown as { default: typeof _traverse }).default ?? _traverse;\n\nconst TARGET_TAGS = new Set([\n 'button',\n 'a',\n 'input',\n 'textarea',\n 'select',\n 'form',\n 'Button',\n 'Link',\n 'Input',\n 'TextField',\n 'Form',\n]);\n\nexport interface InstrumentCandidate {\n file: string;\n line: number;\n column: number;\n tag: string;\n snippet: string;\n hasRole: boolean;\n hasTestId: boolean;\n hasAriaLabel: boolean;\n}\n\nexport async function scanFile(filePath: string): Promise<InstrumentCandidate[]> {\n const source = await readFile(filePath, 'utf8');\n let ast;\n try {\n ast = parse(source, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n errorRecovery: true,\n });\n } catch {\n return [];\n }\n\n const lines = source.split(/\\r?\\n/);\n const candidates: InstrumentCandidate[] = [];\n\n traverse(ast, {\n JSXOpeningElement(path: NodePath<JSXOpeningElement>) {\n const tag = jsxTagName(path.node);\n if (!tag) return;\n const hasRole = pickAttr(path.node, 'role') !== null;\n const hasTestId =\n pickAttr(path.node, 'data-testid') !== null || pickAttr(path.node, 'data-test-id') !== null;\n const hasAriaLabel = pickAttr(path.node, 'aria-label') !== null;\n\n const isTargetTag = TARGET_TAGS.has(tag);\n const isTargetByRole = hasRole;\n if (!isTargetTag && !isTargetByRole) return;\n\n if (hasTestId || hasAriaLabel) return; // already labeled\n\n const loc = path.node.loc;\n if (!loc) return;\n const lineIdx = loc.start.line - 1;\n const snippet = lines[lineIdx] ?? '';\n\n candidates.push({\n file: filePath,\n line: loc.start.line,\n column: loc.start.column,\n tag,\n snippet,\n hasRole,\n hasTestId,\n hasAriaLabel,\n });\n },\n });\n\n return candidates;\n}\n\nfunction jsxTagName(node: JSXOpeningElement): string | null {\n const name = node.name;\n if (name.type === 'JSXIdentifier') {\n return (name as JSXIdentifier).name;\n }\n return null;\n}\n\nfunction pickAttr(node: JSXOpeningElement, attr: string): JSXAttribute | null {\n for (const a of node.attributes) {\n if (a.type !== 'JSXAttribute') continue;\n if (a.name.type !== 'JSXIdentifier') continue;\n if (a.name.name === attr) return a;\n }\n return null;\n}\n","import { z } from 'zod';\nimport type { InstrumentCandidate } from './scan.js';\nimport { logger } from '../util/logger.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nconst suggestionSchema = z.object({\n suggestions: z.array(\n z.object({\n file: z.string(),\n line: z.number().int().positive(),\n original: z.string(),\n replacement: z.string(),\n reasoning: z.string().default(''),\n }),\n ),\n});\n\nexport type Suggestion = z.infer<typeof suggestionSchema>['suggestions'][number];\n\nexport class InstrumentSuggestionError extends Error {\n override readonly name = 'InstrumentSuggestionError';\n}\n\nexport interface SuggestOptions {\n candidates: InstrumentCandidate[];\n provider: LLMProvider;\n}\n\nconst SYSTEM_PROMPT = `You add data-testid attributes to JSX elements so they can be reliably targeted by automated demo tools.\n\nRules:\n- For each candidate, propose a stable kebab-case data-testid based on visible text, surrounding context, or the element's role. Examples: \"login-submit\", \"new-article-button\", \"todo-item-toggle\".\n- Prefer short, semantic ids over verbose ones.\n- Output a single-line replacement: take the original line and insert data-testid=\"...\" just before the closing > of the opening tag. Preserve all existing whitespace and other attributes.\n- Skip elements where you can't infer a meaningful name (e.g. truly generic wrappers). In that case omit them from the output rather than guessing.\n- Never duplicate an existing data-testid on the page; if two candidates would collide, suffix the second with an index (\"-2\").\n- Reasoning: one short line explaining the chosen name.\n\nReturn JSON matching the requested schema.`;\n\nexport async function suggestTestIds(opts: SuggestOptions): Promise<Suggestion[]> {\n if (opts.candidates.length === 0) return [];\n\n const candidateBlock = opts.candidates\n .map(\n (c, i) =>\n `[${i + 1}] file=${c.file} line=${c.line} tag=${c.tag}\\n ${c.snippet.trim()}`,\n )\n .join('\\n');\n\n const userPrompt = `Suggest data-testid attributes for the following JSX elements:\\n\\n${candidateBlock}\\n\\nFor each, return {file, line, original (exact source line), replacement (source line with data-testid inserted), reasoning}.`;\n\n logger.debug('Calling LLM provider for instrument suggestions', {\n candidates: opts.candidates.length,\n });\n\n try {\n const result = await opts.provider.generateStructured({\n systemPrompt: SYSTEM_PROMPT,\n userPrompt,\n schema: suggestionSchema,\n schemaName: 'instrument_suggestions',\n maxTokens: DEFAULT_MAX_TOKENS,\n });\n return result.suggestions;\n } catch (err) {\n throw new InstrumentSuggestionError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative } from 'node:path';\nimport type { Suggestion } from './suggest.js';\n\nexport interface DiffOptions {\n /** When set, paths in the diff are written relative to this dir. */\n basePath?: string;\n}\n\n/**\n * Build a unified diff from per-file single-line replacements. Each suggestion\n * is treated independently; lines that don't match the suggestion's `original`\n * exactly are skipped with a warning header but don't block the rest.\n */\nexport async function buildDiff(\n suggestions: Suggestion[],\n opts: DiffOptions = {},\n): Promise<{ patch: string; skipped: { file: string; line: number; reason: string }[] }> {\n const byFile = new Map<string, Suggestion[]>();\n for (const s of suggestions) {\n const arr = byFile.get(s.file) ?? [];\n arr.push(s);\n byFile.set(s.file, arr);\n }\n\n const skipped: { file: string; line: number; reason: string }[] = [];\n const fileDiffs: string[] = [];\n\n for (const [file, perFile] of byFile) {\n let source: string;\n try {\n source = await readFile(file, 'utf8');\n } catch (err) {\n for (const s of perFile) {\n skipped.push({\n file,\n line: s.line,\n reason: `read failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n continue;\n }\n const lines = source.split('\\n');\n const sorted = [...perFile].sort((a, b) => a.line - b.line);\n\n const hunks: string[] = [];\n for (const s of sorted) {\n const idx = s.line - 1;\n const actual = lines[idx];\n if (actual === undefined) {\n skipped.push({ file, line: s.line, reason: 'line out of range' });\n continue;\n }\n if (actual.trim() !== s.original.trim()) {\n skipped.push({\n file,\n line: s.line,\n reason: `source line drifted from suggestion (expected \"${s.original.trim()}\", saw \"${actual.trim()}\")`,\n });\n continue;\n }\n hunks.push(\n `@@ -${s.line},1 +${s.line},1 @@\\n-${actual}\\n+${s.replacement}`,\n );\n }\n\n if (hunks.length === 0) continue;\n const displayPath = opts.basePath ? relative(opts.basePath, file).replace(/\\\\/g, '/') : file;\n fileDiffs.push(`--- a/${displayPath}\\n+++ b/${displayPath}\\n${hunks.join('\\n')}`);\n }\n\n return { patch: fileDiffs.join('\\n') + (fileDiffs.length > 0 ? '\\n' : ''), skipped };\n}\n","import { createInterface } from 'node:readline/promises';\nimport { resolve } from 'node:path';\nimport { stat } from 'node:fs/promises';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { launchHeadedSession } from '../recording/headed.js';\nimport {\n attachNavigationCapture,\n coalesceEvents,\n installCaptureBinding,\n type RecordedEvent,\n} from '../recording/captureEvents.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport type { Action, Manifest } from '../manifest/schema.js';\nimport { logger } from '../util/logger.js';\n\nexport interface RecordActionsOpts {\n config: string;\n segment?: string;\n output?: string;\n}\n\nexport async function recordActionsCommand(opts: RecordActionsOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const manifestPath = opts.output\n ? resolve(loaded.configDir, opts.output)\n : resolve(loaded.configDir, './scripts/manifest.json');\n\n logger.info('Launching headed browser for action capture', {\n target: loaded.config.recording.target_url,\n });\n\n const events: RecordedEvent[] = [];\n const interleavedNavigations: Action[] = [];\n const sessionEnd = new AbortController();\n\n const session = await launchHeadedSession({\n recording: loaded.config.recording,\n configDir: loaded.configDir,\n recordVideo: false,\n withCursor: false,\n applyAuth: true,\n });\n\n try {\n await installCaptureBinding(session.context, (evt) => events.push(evt));\n attachNavigationCapture(session.page, (action) => interleavedNavigations.push(action));\n\n await session.page.goto(loaded.config.recording.target_url);\n\n process.stdout.write(\n '\\nDrive the demo in the browser window. Click, type, navigate.\\n' +\n 'When you\\'re done, return here and press Enter to write the manifest (or Ctrl+C to abort).\\n',\n );\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const closed = new Promise<void>((resolveClose) => {\n sessionEnd.signal.addEventListener('abort', () => resolveClose());\n });\n const userPrompt = rl.question('Press Enter to save: ');\n await Promise.race([userPrompt, closed]);\n rl.close();\n } finally {\n await session.close();\n }\n\n const coalesced = coalesceEvents(events);\n const actions = mergeWithNavigations(coalesced, interleavedNavigations);\n logger.info('Coalesced action stream', {\n raw_events: events.length,\n navigations: interleavedNavigations.length,\n actions: actions.length,\n });\n\n if (actions.length === 0) {\n logger.warn('No actions captured — manifest not modified.');\n return;\n }\n\n const updatedManifest = await mergeIntoManifest({\n manifestPath,\n segmentId: opts.segment,\n actions,\n projectName: loaded.config.project.name,\n });\n\n await writeManifest(manifestPath, updatedManifest);\n logger.info('Wrote manifest', { path: manifestPath, segments: updatedManifest.segments.length });\n}\n\n/**\n * Insert navigation events into the action stream by timestamp. Navigations\n * arrive on their own channel from Playwright; the click/input events come from\n * the in-page binding. Cheap interleave: append navigations to the end. (For\n * v1 this is fine — the typical pattern is \"fill form → submit → navigate\".)\n */\nfunction mergeWithNavigations(coalesced: Action[], navigations: Action[]): Action[] {\n return [...coalesced, ...navigations];\n}\n\ninterface MergeOptions {\n manifestPath: string;\n segmentId?: string;\n actions: Action[];\n projectName: string;\n}\n\nasync function mergeIntoManifest(opts: MergeOptions): Promise<Manifest> {\n const exists = await fileExists(opts.manifestPath);\n if (!exists) {\n // Build a one-segment skeleton.\n const segmentId = opts.segmentId ?? 'recorded';\n const duration = Math.max(8, opts.actions.length * 2);\n return {\n total_duration_seconds: duration,\n generated_from: 'record-actions',\n segments: [\n {\n id: segmentId,\n label: 'Recorded',\n start: 0,\n end: duration,\n vo_line: `Recorded walkthrough of ${opts.projectName}.`,\n actions: opts.actions,\n transition: 'cut',\n },\n ],\n };\n }\n\n let existing;\n try {\n existing = await readManifest(opts.manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`record-actions: existing manifest invalid — ${err.message}`);\n }\n throw err;\n }\n\n if (!opts.segmentId) {\n // Append a new \"recorded\" segment at the end.\n const lastEnd = existing.segments[existing.segments.length - 1]!.end;\n const newStart = lastEnd;\n const newEnd = newStart + Math.max(8, opts.actions.length * 2);\n existing.segments.push({\n id: `recorded-${existing.segments.length}`,\n label: 'Recorded',\n start: newStart,\n end: newEnd,\n vo_line: 'Recorded walkthrough.',\n actions: opts.actions,\n transition: 'cut',\n });\n existing.total_duration_seconds = newEnd;\n return existing;\n }\n\n const target = existing.segments.find((s) => s.id === opts.segmentId);\n if (!target) {\n throw new Error(\n `record-actions: segment \"${opts.segmentId}\" not found in ${opts.manifestPath}. ` +\n `Available: ${existing.segments.map((s) => s.id).join(', ')}`,\n );\n }\n target.actions = opts.actions;\n return existing;\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 type { BrowserContext, Page } from 'playwright-core';\nimport type { Action } from '../manifest/schema.js';\nimport { logger } from '../util/logger.js';\nimport { SELECTOR_FOR_FN_SOURCE } from './selectorHeuristic.js';\n\nexport interface RecordedEvent {\n kind: 'click' | 'input' | 'keydown' | 'submit' | 'change' | 'scroll';\n selector: string;\n /** For input/change: the field's current value. For keydown: the key. For scroll: 'up'|'down'. */\n payload?: string;\n /** Wall-clock timestamp captured in the page. */\n ts: number;\n /** True if the field is a contenteditable (treat differently from inputs). */\n contenteditable?: boolean;\n /** For scroll events: accumulated deltaY since the last emit. */\n deltaY?: number;\n}\n\n/**\n * Install a small in-page script that listens for user interactions and posts\n * each one back to Node via the `__srRecordEvent` binding. Selector preference:\n * 1. [data-testid=\"X\"]\n * 2. [name=\"X\"] (form fields)\n * 3. [placeholder=\"X\"]\n * 4. [aria-label=\"X\"]\n * 5. #id (if id is stable-looking)\n * 6. text=<visible text> for buttons/links\n * 7. minimal CSS path\n */\nexport async function installCaptureBinding(\n context: BrowserContext,\n onEvent: (evt: RecordedEvent) => void,\n): Promise<void> {\n await context.exposeBinding('__srRecordEvent', (_source, evt: unknown) => {\n if (!isRecordedEvent(evt)) return;\n onEvent(evt);\n });\n\n await context.addInitScript(IN_PAGE_SCRIPT);\n}\n\nfunction isRecordedEvent(value: unknown): value is RecordedEvent {\n if (!value || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.kind === 'string' &&\n typeof v.selector === 'string' &&\n typeof v.ts === 'number'\n );\n}\n\nconst IN_PAGE_SCRIPT = `\n(() => {\n if (window.__srRecordingInstalled) return;\n window.__srRecordingInstalled = true;\n\n ${SELECTOR_FOR_FN_SOURCE}\n\n function send(kind, el, payload, extra) {\n const sel = selectorFor(el);\n if (!sel) return;\n const evt = Object.assign({\n kind: kind,\n selector: sel,\n payload: payload,\n ts: Date.now(),\n contenteditable: el && el.isContentEditable === true,\n }, extra || {});\n if (window.__srRecordEvent) {\n try { window.__srRecordEvent(evt); } catch {}\n }\n }\n\n document.addEventListener('click', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('click', el, null);\n }, true);\n\n document.addEventListener('input', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n const value = (el.value !== undefined && el.value !== null) ? String(el.value) : (el.textContent || '');\n send('input', el, value);\n }, true);\n\n document.addEventListener('change', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n if (el.tagName !== 'SELECT') return;\n send('change', el, String(el.value));\n }, true);\n\n document.addEventListener('keydown', (e) => {\n if (e.key !== 'Enter' && e.key !== 'Escape' && e.key !== 'Tab') return;\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('keydown', el, e.key);\n }, true);\n\n document.addEventListener('submit', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('submit', el, null);\n }, true);\n\n // Scroll capture — debounce 250ms, coalesce within window, emit direction + accumulated deltaY.\n let scrollLastY = window.scrollY;\n let scrollAccum = 0;\n let scrollTimer = null;\n let scrollTarget = null;\n function flushScroll() {\n scrollTimer = null;\n if (scrollAccum === 0) return;\n const direction = scrollAccum > 0 ? 'down' : 'up';\n const deltaY = Math.abs(scrollAccum);\n scrollAccum = 0;\n const el = scrollTarget || document.scrollingElement || document.body;\n send('scroll', el, direction, { deltaY: deltaY });\n }\n document.addEventListener('scroll', (e) => {\n const target = (e.target === document ? (document.scrollingElement || document.body) : e.target);\n if (!target || target.nodeType !== 1) return;\n const currentY = target === document.scrollingElement || target === document.body\n ? window.scrollY\n : (target.scrollTop || 0);\n const delta = currentY - scrollLastY;\n scrollLastY = currentY;\n if (delta === 0) return;\n // Direction change → flush the previous burst immediately.\n if (scrollAccum !== 0 && Math.sign(delta) !== Math.sign(scrollAccum)) {\n if (scrollTimer !== null) { clearTimeout(scrollTimer); scrollTimer = null; }\n flushScroll();\n }\n scrollAccum += delta;\n scrollTarget = target;\n if (scrollTimer === null) {\n scrollTimer = setTimeout(flushScroll, 250);\n }\n }, true);\n})();\n`;\n\n/**\n * Stream of RecordedEvents → coalesced Action[] suitable for a manifest segment.\n * Rules:\n * - Contiguous `input` events on the same selector collapse into one `type`\n * action carrying the final value.\n * - `keydown:Enter` after an input on the same selector becomes a `press: Enter`.\n * - Standalone `click` events become `click` actions, unless the next event is\n * an input on the same selector (then the click is just focus — drop it).\n * - `submit` is dropped (Enter or button-click already triggered it).\n * - `change` on a `<select>` becomes `fill` with the value.\n */\nexport function coalesceEvents(events: RecordedEvent[]): Action[] {\n const out: Action[] = [];\n let pendingInputSelector: string | undefined;\n\n for (let i = 0; i < events.length; i++) {\n const evt = events[i]!;\n const next = events[i + 1];\n\n if (evt.kind === 'click') {\n // If the next event is an input on the same selector, this click was\n // just focusing the field — drop it.\n if (next && next.kind === 'input' && next.selector === evt.selector) {\n continue;\n }\n out.push({ type: 'click', selector: evt.selector });\n pendingInputSelector = undefined;\n continue;\n }\n\n if (evt.kind === 'input') {\n // Find the last value across the run of consecutive inputs on this selector.\n let lastValue = evt.payload ?? '';\n let j = i;\n while (j + 1 < events.length) {\n const peek = events[j + 1]!;\n if (peek.kind === 'input' && peek.selector === evt.selector) {\n lastValue = peek.payload ?? '';\n j++;\n continue;\n }\n break;\n }\n i = j;\n out.push({ type: 'type', selector: evt.selector, value: lastValue });\n pendingInputSelector = evt.selector;\n continue;\n }\n\n if (evt.kind === 'keydown' && evt.payload === 'Enter') {\n // Press Enter on the field, attached to current selector if known.\n out.push({ type: 'press', key: 'Enter', selector: evt.selector });\n pendingInputSelector = undefined;\n continue;\n }\n if (evt.kind === 'keydown' && evt.payload === 'Escape') {\n out.push({ type: 'press', key: 'Escape', selector: evt.selector });\n continue;\n }\n if (evt.kind === 'keydown' && evt.payload === 'Tab') {\n out.push({ type: 'press', key: 'Tab', selector: evt.selector });\n continue;\n }\n\n if (evt.kind === 'change') {\n out.push({ type: 'fill', selector: evt.selector, value: evt.payload ?? '' });\n continue;\n }\n\n if (evt.kind === 'scroll') {\n // Coalesce consecutive scroll bursts on the same selector + direction\n // into a single scroll action. A direction change ends the run.\n const direction = evt.payload === 'up' ? 'up' : 'down';\n let j = i;\n while (j + 1 < events.length) {\n const peek = events[j + 1]!;\n if (\n peek.kind === 'scroll' &&\n peek.selector === evt.selector &&\n (peek.payload === 'up' ? 'up' : 'down') === direction\n ) {\n j++;\n continue;\n }\n break;\n }\n i = j;\n out.push({ type: 'scroll', selector: evt.selector, direction });\n continue;\n }\n // submit: dropped intentionally\n }\n\n void pendingInputSelector;\n return out;\n}\n\n/**\n * Watch navigations on the page and emit wait_for_url actions when the URL changes.\n * Returns a function that drains current navigation events into the action array.\n */\nexport function attachNavigationCapture(\n page: Page,\n pushEvent: (action: Action) => void,\n): void {\n let lastUrl = page.url();\n page.on('framenavigated', (frame) => {\n if (frame !== page.mainFrame()) return;\n const url = frame.url();\n if (url === lastUrl) return;\n lastUrl = url;\n if (url === 'about:blank') return;\n pushEvent({ type: 'wait_for_url', pattern: url });\n logger.debug(`captured navigation`, { url });\n });\n}\n"],"mappings":"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","names":["resolve","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","spawn","stat","isAbsolute","resolve","dirname","join","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","dirname","isAbsolute","spawn","stat","join","runCommand","resolve","mkdir","writeFile","access","dirname","isAbsolute","join","resolve","isAbsolute","resolve","join","mkdir","dirname","writeFile","access","spawn","access","dirname","join","spawn","resolve","dirname","join","access","stat","isAbsolute","resolve","isAbsolute","resolve","stat","resolve","resolve","rm","stat","resolve","resolve","pathExists","rm","stat","mkdir","rename","writeFile","join","resolve","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","mkdir","join","rename","writeFile","mkdir","dirname","isAbsolute","resolve","mkdir","resolve","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","mkdir","resolve","isAbsolute","mkdir","dirname","readdir","stat","isAbsolute","join","resolve","resolve","join","isAbsolute","fileExists","readdir","stat","stat","resolve","resolve","fileExists","stat","mkdir","readFile","writeFile","dirname","isAbsolute","resolve","DEFAULT_MAX_TOKENS","createInterface","resolve","resolve","isAbsolute","mkdir","dirname","readFile","writeFile","mkdir","readdir","writeFile","dirname","isAbsolute","join","resolve","relative","readFile","z","DEFAULT_MAX_TOKENS","z","readFile","resolve","readdir","join","relative","isAbsolute","mkdir","dirname","writeFile","createInterface","resolve","stat","resolve","createInterface","fileExists","stat","runCommand","access","resolve","chromium","stat"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/util/logger.ts","../src/commands/run.ts","../src/config/loader.ts","../src/config/schema.ts","../src/pipeline/run.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","../src/commands/doctor.ts","../src/config/providerEnv.ts","../src/util/resolutionPresets.ts","../src/commands/init.ts","../src/setup/detect.ts","../src/setup/wizard.ts","../src/setup/targetProbe.ts","../src/setup/portScan.ts","../src/setup/agentDiscover.ts","../src/setup/projectSnapshot.ts","../src/setup/spawnDevServer.ts","../src/commands/installBrowser.ts","../src/commands/setTarget.ts","../src/commands/validate.ts","../src/commands/printVo.ts","../src/commands/approveVo.ts","../src/commands/rerunSegment.ts","../src/commands/captureAuth.ts","../src/recording/headed.ts","../src/commands/trace.ts","../src/commands/preview.ts","../src/commands/understand.ts","../src/productModel/prompts.ts","../src/productModel/generate.ts","../src/productModel/interactive.ts","../src/commands/instrument.ts","../src/instrument/scan.ts","../src/instrument/suggest.ts","../src/instrument/diff.ts","../src/commands/recordActions.ts","../src/recording/captureEvents.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, Option } from 'commander';\nimport { logger } from './util/logger.js';\nimport { runCommand } from './commands/run.js';\nimport { initCommand } from './commands/init.js';\nimport { installBrowserCommand } from './commands/installBrowser.js';\nimport { setTargetCommand } from './commands/setTarget.js';\nimport { validateCommand } from './commands/validate.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { printVoCommand } from './commands/printVo.js';\nimport { approveVoCommand } from './commands/approveVo.js';\nimport { rerunSegmentCommand } from './commands/rerunSegment.js';\nimport { captureAuthCommand } from './commands/captureAuth.js';\nimport { traceCommand } from './commands/trace.js';\nimport { previewCommand } from './commands/preview.js';\nimport { understandCommand } from './commands/understand.js';\nimport { instrumentCommand } from './commands/instrument.js';\nimport { recordActionsCommand } from './commands/recordActions.js';\nimport { notImplemented } from './commands/notImplemented.js';\nimport { STAGE_NAMES, type StageName } from './pipeline/types.js';\n\nconst program = new Command();\n\nprogram\n .name('showrunner')\n .description('Automated product demo recording & production tool')\n .version('1.1.5')\n .option('--json', 'emit structured JSON logs to stdout')\n .option('--log-level <level>', 'log level (debug|info|warn|error)')\n .hook('preAction', (thisCmd) => {\n const opts = thisCmd.opts<{ json?: boolean; logLevel?: string }>();\n if (opts.json) logger.setJson(true);\n if (opts.logLevel) logger.setLevel(opts.logLevel as 'debug' | 'info' | 'warn' | 'error');\n })\n .action(async () => {\n // Bare `showrunner` with no subcommand: print a context-aware welcome\n // instead of falling through to `--help`.\n await printWelcome();\n });\n\nconst stageChoices = [...STAGE_NAMES];\n\nprogram\n .command('run')\n .description('Run the full Showrunner pipeline')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .addOption(\n new Option('--stages <stages>', 'comma-separated subset of stages to run').argParser((v) =>\n parseStages(v),\n ),\n )\n .addOption(\n new Option('--force <stages>', 'comma-separated stages whose artifacts to regenerate').argParser(\n (v) => parseStages(v),\n ),\n )\n .option('--no-interactive', 'disable interactive prompts (agent mode)')\n .option('--resume', 'resume a previously-failed run from the last successful stage')\n .option('--dry-run', 'generate scripts without recording, synthesizing, or muxing')\n .option('--estimate', 'print API cost estimate and exit')\n .option('--output-path <path>', 'override output_path from config')\n .option('--watch', 'run the recording stage in headed mode (overrides config.recording.headless)')\n .option('--skip-doctor', 'skip the implicit preflight doctor checks')\n .option(\n '--resolution <preset>',\n 'override resolution for this run: low (854x480), standard (720p), high (1080p), extreme (4K)',\n )\n .action(runCommand);\n\nprogram\n .command('init')\n .description('Scaffold a new Showrunner project (interactive by default; use --yes to skip prompts)')\n .option('--name <name>', 'project name', 'showrunner-demo')\n .option('--url <url>', 'target URL of the product to demo', 'http://localhost:3000')\n .option('--dir <dir>', 'parent directory in which to create the project', process.cwd())\n .option('--force', 'overwrite an existing directory', false)\n .option('--yes', 'skip interactive prompts and use defaults / passed flags', false)\n .option(\n '--llm-provider <name>',\n 'LLM provider for comprehension + script + instrument (anthropic | openai | agent_bridge)',\n 'anthropic',\n )\n .option(\n '--tts-provider <name>',\n 'TTS provider for voiceover (elevenlabs | openai | custom)',\n 'elevenlabs',\n )\n .option(\n '--resolution <preset>',\n 'scaffold resolution: low (854x480) | standard (720p) | high (1080p) | extreme (4K)',\n 'standard',\n )\n .action(initCommand);\n\nprogram\n .command('set-target')\n .description(\"Update demo.yaml's recording.target_url and re-probe it\")\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .requiredOption('--url <url>', 'new target URL (e.g. http://localhost:5173)')\n .option('--force', 'skip the reachability probe and update the URL anyway', false)\n .action(setTargetCommand);\n\nprogram\n .command('install-browser')\n .description('Install the Playwright browser binary (chromium by default) — wraps playwright-core install')\n .option('--browser <name>', 'browser to install: chromium | firefox | webkit', 'chromium')\n .action(installBrowserCommand);\n\nprogram\n .command('doctor')\n .description('Run preflight checks on the current config + environment')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--json', 'emit results as JSON instead of human-readable rows')\n .action(doctorCommand);\n\nprogram\n .command('validate')\n .description('Validate a demo.yaml config file')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--strict', 'exit nonzero on any warning (e.g. missing provider env var)')\n .action(validateCommand);\n\nprogram\n .command('understand')\n .description('Build product_model.json from documents or interactive Q&A')\n .option('-c, --config <path>', 'path to demo.yaml')\n .option('--interactive', 'use interactive Q&A mode')\n .option('--output <path>', 'output path for product_model.json')\n .action(understandCommand);\n\nprogram\n .command('instrument')\n .description('Suggest data-testid attributes for a codebase')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .requiredOption('--output <path>', 'unified diff output path')\n .option('--glob <pattern>', 'override comprehension.sources with an ad-hoc glob (relative to configDir)')\n .action(instrumentCommand);\n\nprogram\n .command('record-actions')\n .description('Author manifest actions by demonstrating them in a live browser')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--segment <id>', 'replace actions for an existing segment id')\n .option('--output <path>', 'manifest output path (default ./scripts/manifest.json)')\n .action(recordActionsCommand);\n\nprogram\n .command('preview')\n .description('Preview the generated Playwright script in UI Mode')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(previewCommand);\n\nprogram\n .command('trace')\n .description('Open the Playwright Trace Viewer for a recording')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--segment <id>', 'open trace for one segment')\n .option('--all', 'open traces for all segments from the last run')\n .action(traceCommand);\n\nprogram\n .command('rerun-segment')\n .description('Re-record a single segment (runs reset_script first)')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .requiredOption('--segment <id>', 'segment to re-run')\n .action(rerunSegmentCommand);\n\nprogram\n .command('print-vo')\n .description('Print the generated VO script for review')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(printVoCommand);\n\nprogram\n .command('capture-auth')\n .description('Capture an auth session interactively (run once during setup)')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .option('--output-cookies <path>', 'storageState output path', './auth/session.json')\n .action(captureAuthCommand);\n\nprogram\n .command('approve-vo')\n .description('Approve edited VO script and resume the pipeline')\n .requiredOption('-c, --config <path>', 'path to demo.yaml')\n .action(approveVoCommand);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(message);\n process.exit(1);\n});\n\nasync function printWelcome(): Promise<void> {\n const { access } = await import('node:fs/promises');\n const { resolve } = await import('node:path');\n const demoYaml = resolve(process.cwd(), 'demo.yaml');\n let inProject = false;\n try {\n await access(demoYaml);\n inProject = true;\n } catch {\n // not in a Showrunner project root\n }\n\n const browserMissing = await isChromiumMissing();\n\n const lines: string[] = ['', `Showrunner v1.1.5`, ''];\n\n // Surface one state at a time. Higher-priority states short-circuit lower ones.\n if (browserMissing) {\n lines.push(`Showrunner records using Chromium. You haven't installed it yet.`);\n lines.push(``);\n lines.push(` showrunner install-browser`);\n lines.push(``);\n lines.push(`(~150 MB, one-off. Re-run \\`showrunner\\` after it finishes for the next step.)`);\n } else if (inProject) {\n lines.push(`This is a Showrunner project (found demo.yaml).`);\n lines.push(``);\n lines.push(` showrunner doctor -c demo.yaml # check everything is wired correctly`);\n lines.push(` showrunner run -c demo.yaml # then run the full pipeline`);\n lines.push(``);\n lines.push(`Full command list: \\`showrunner --help\\``);\n } else {\n lines.push(`No Showrunner project in this directory. To create one:`);\n lines.push(``);\n lines.push(` showrunner init`);\n lines.push(``);\n lines.push(`\\`init\\` scaffolds the project and prints the next 4 commands tailored to your provider choice.`);\n }\n\n lines.push('');\n process.stdout.write(lines.join('\\n'));\n}\n\nasync function isChromiumMissing(): Promise<boolean> {\n try {\n const { chromium } = await import('playwright-core');\n const exec = chromium.executablePath();\n const { stat } = await import('node:fs/promises');\n await stat(exec);\n return false;\n } catch {\n return true;\n }\n}\n\nfunction parseStages(value: string): StageName[] {\n const requested = value.split(',').map((s) => s.trim());\n const invalid = requested.filter((s) => !stageChoices.includes(s as StageName));\n if (invalid.length > 0) {\n throw new Error(\n `Unknown stage(s): ${invalid.join(', ')}. Valid stages: ${stageChoices.join(', ')}`,\n );\n }\n return requested as StageName[];\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 { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { run, PipelineStageError } from '../pipeline/run.js';\nimport { logger } from '../util/logger.js';\nimport type { StageName } from '../pipeline/types.js';\nimport { runDoctorChecks } from './doctor.js';\nimport { formatResolution, resolvePreset } from '../util/resolutionPresets.js';\n\nconst STAGE_REMEDIATION: Record<StageName, string> = {\n comprehension:\n 'Check the LLM provider env (or switch llm.default.provider to agent_bridge in demo.yaml). ' +\n 'If you already have a product_model.json, skip this stage: --stages script,record,voiceover,mux',\n script:\n 'Manifest generation failed. Inspect scripts/manifest.json if it was partially written. ' +\n 'If the LLM is misbehaving, hand-author scripts/manifest.json and resume: --stages record,voiceover,mux',\n record:\n 'Playwright recording failed. Inspect with `showrunner trace -c <config> --all` or `--segment <id>`. ' +\n 'Demo a problem segment manually with `showrunner record-actions -c <config> --segment <id>`.',\n voiceover:\n 'TTS synthesis or alignment failed. Check your TTS provider env. ' +\n 'If alignment is the issue, set voiceover.alignment_strategy: best_effort in demo.yaml.',\n mux:\n 'ffmpeg mux failed. Check the `doctor` row about free disk + RAM. ' +\n 'Cap libx264 threads with `SHOWRUNNER_FFMPEG_THREADS=1` if RAM is tight.',\n};\n\nexport interface RunOpts {\n config: string;\n stages?: StageName[];\n force?: StageName[];\n interactive?: boolean;\n resume?: boolean;\n dryRun?: boolean;\n estimate?: boolean;\n outputPath?: string;\n watch?: boolean;\n skipDoctor?: boolean;\n resolution?: string;\n}\n\nexport async function runCommand(opts: RunOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n logger.debug(`loaded env from ${envFile}`);\n } catch {\n // No .env in project dir — fine, env vars may come from the shell.\n }\n\n if (opts.outputPath) {\n loaded.config.output.output_path = opts.outputPath;\n }\n\n if (opts.resolution) {\n let r;\n try {\n r = resolvePreset(opts.resolution);\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err));\n process.exit(2);\n }\n loaded.config.recording.viewport.width = r.width;\n loaded.config.recording.viewport.height = r.height;\n loaded.config.output.resolution = formatResolution(r);\n logger.info(`Resolution override: ${opts.resolution} → ${formatResolution(r)} (recording + output)`);\n }\n\n if (opts.estimate) {\n logger.warn('--estimate is not yet implemented; running the pipeline.');\n }\n\n // Implicit pre-flight via doctor. Bail on FAIL unless --skip-doctor was passed.\n if (!opts.skipDoctor) {\n const results = await runDoctorChecks(opts.config);\n const fails = results.filter((r) => r.status === 'FAIL');\n if (fails.length > 0) {\n for (const f of fails) {\n logger.error(`[doctor] ${f.label}${f.detail ? ` — ${f.detail}` : ''}`);\n }\n logger.error(\n `Doctor reported ${fails.length} FAIL row(s). Run \\`showrunner doctor -c ${opts.config}\\` for details, or pass --skip-doctor to bypass.`,\n );\n process.exit(1);\n }\n const warns = results.filter((r) => r.status === 'WARN');\n for (const w of warns) {\n logger.warn(`[doctor] ${w.label}${w.detail ? ` — ${w.detail}` : ''}`);\n }\n }\n\n try {\n const result = await run(loaded, {\n stages: opts.stages,\n force: opts.force,\n interactive: opts.interactive ?? true,\n resume: opts.resume ?? false,\n dryRun: opts.dryRun ?? false,\n overrides: { headed: opts.watch ?? false },\n });\n logger.info('Pipeline complete', {\n runId: result.runId,\n output: result.outputPath,\n buildManifest: result.buildManifestPath,\n });\n } catch (err) {\n if (err instanceof PipelineStageError) {\n logger.error(`Pipeline failed in stage \\`${err.stage}\\`: ${err.message}`);\n const remediation = STAGE_REMEDIATION[err.stage];\n if (remediation) logger.error(`To fix: ${remediation}`);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Pipeline failed: ${message}`);\n process.exit(1);\n }\n}\n","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","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","import { spawn } from 'node:child_process';\nimport { stat, access, constants, readdir } from 'node:fs/promises';\nimport { isAbsolute, resolve, dirname, join } from 'node:path';\nimport { homedir, platform as osPlatform } from 'node:os';\nimport { request as undiciRequest } from 'undici';\nimport { chromium, firefox, webkit } from 'playwright-core';\nimport type { ShowrunnerConfig } from '../config/schema.js';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { inspectProviderEnv } from '../config/providerEnv.js';\nimport { logger } from '../util/logger.js';\nimport {\n computeThreadCap,\n formatBytes,\n getFreeDiskBytes,\n getFreeMemoryBytes,\n getTotalMemoryBytes,\n} from '../util/resources.js';\n\nexport type CheckStatus = 'PASS' | 'WARN' | 'FAIL';\n\nexport interface CheckResult {\n status: CheckStatus;\n label: string;\n detail?: string;\n}\n\ninterface DoctorOpts {\n config: string;\n json?: boolean;\n}\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function doctorCommand(opts: DoctorOpts): Promise<void> {\n // Load .env from the config's directory so env-var checks see what `run` would see.\n const envFile = resolve(dirname(resolve(opts.config)), '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // No .env in project dir — env vars may come from the shell or fail the check below.\n }\n\n const results = await runDoctorChecks(opts.config);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify({ results, summary: summarize(results) }, null, 2) + '\\n');\n } else {\n for (const r of results) printRow(r);\n const summary = summarize(results);\n if (summary.fail > 0) {\n printFixOrder(results);\n logger.error(`doctor: ${summary.fail} FAIL, ${summary.warn} WARN, ${summary.pass} PASS`);\n } else if (summary.warn > 0) {\n logger.warn(`doctor: ${summary.warn} WARN, ${summary.pass} PASS`);\n } else {\n logger.info(`doctor: ${summary.pass}/${results.length} checks passed. ready to run.`);\n }\n }\n\n if (results.some((r) => r.status === 'FAIL')) {\n process.exit(1);\n }\n}\n\n/**\n * Reusable from `run` for the implicit pre-flight (with `--skip-doctor` escape).\n * Returns the full results array; caller decides whether to bail on FAIL.\n */\nexport async function runDoctorChecks(configPath: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // 1. Config loads cleanly.\n let loaded;\n try {\n loaded = await loadConfig(configPath);\n results.push({ status: 'PASS', label: `config syntactically valid: ${configPath}` });\n } catch (err) {\n const msg = err instanceof ConfigError ? err.message : err instanceof Error ? err.message : String(err);\n results.push({ status: 'FAIL', label: `config invalid: ${configPath}`, detail: msg });\n return results;\n }\n const { config, configDir } = loaded;\n\n // 2. Provider env vars.\n for (const row of inspectProviderEnv(config)) {\n const suffix = row.stage ? ` (${row.stage} override)` : '';\n if (row.set) {\n results.push({\n status: 'PASS',\n label: `${row.slot} provider=${row.provider}${suffix}, ${row.envVar} set`,\n });\n } else {\n results.push({\n status: 'FAIL',\n label: `${row.slot} provider=${row.provider}${suffix}, ${row.envVar} NOT set`,\n detail: providerEnvHint(row.slot, row.provider, row.envVar),\n });\n }\n }\n\n // 3. ffmpeg + ffprobe.\n results.push(await checkBinary('ffmpeg', ['-version']));\n results.push(await checkBinary('ffprobe', ['-version']));\n\n // 4. Playwright chromium present.\n results.push(await checkPlaywrightBrowser(config));\n\n // 5. Target URL reachable.\n results.push(await checkTargetReachable(config.recording.target_url));\n\n // 6. Free disk on the dirs we write into.\n const dirsToCheck: Array<{ relPath: string; label: string }> = [\n { relPath: config.recording.output_dir, label: 'recording.output_dir' },\n { relPath: config.voiceover.output_dir, label: 'voiceover.output_dir' },\n { relPath: dirname(config.output.output_path), label: 'output.output_path parent' },\n ];\n for (const d of dirsToCheck) {\n const abs = isAbsolute(d.relPath) ? d.relPath : resolve(configDir, d.relPath);\n const parent = await firstExistingAncestor(abs);\n const free = await getFreeDiskBytes(parent);\n const enough = free > 1024 * 1024 * 1024; // 1 GB rule of thumb\n results.push({\n status: enough ? 'PASS' : 'WARN',\n label: `free disk ${d.label} (${parent}): ${formatBytes(free)}`,\n });\n }\n\n // 7. Free memory + thread cap.\n const freeMem = getFreeMemoryBytes();\n const totalMem = getTotalMemoryBytes();\n const [widthStr, heightStr] = config.output.resolution.split('x');\n const width = Number.parseInt(widthStr ?? '1920', 10);\n const height = Number.parseInt(heightStr ?? '1080', 10);\n const threads = computeThreadCap({\n width,\n height,\n fps: config.output.fps,\n quality: config.output.quality,\n freeMemBytes: freeMem,\n });\n results.push({\n status: freeMem > 1024 * 1024 * 1024 ? 'PASS' : 'WARN',\n label: `free memory: ${formatBytes(freeMem)} of ${formatBytes(totalMem)} (ffmpeg thread cap: ${threads})`,\n });\n\n // 8. Lifecycle scripts exist + (on POSIX) are executable.\n for (const [label, p] of [\n ['recording.state.seed_script', config.recording.state.seed_script],\n ['recording.state.reset_script', config.recording.state.reset_script],\n ['recording.state.teardown_script', config.recording.state.teardown_script],\n ] as const) {\n if (!p) continue;\n const abs = isAbsolute(p) ? p : resolve(configDir, p);\n results.push(await checkScript(label, abs));\n }\n\n return results;\n}\n\nfunction summarize(results: CheckResult[]): { pass: number; warn: number; fail: number } {\n return {\n pass: results.filter((r) => r.status === 'PASS').length,\n warn: results.filter((r) => r.status === 'WARN').length,\n fail: results.filter((r) => r.status === 'FAIL').length,\n };\n}\n\nfunction printFixOrder(results: CheckResult[]): void {\n const fails = results.filter((r) => r.status === 'FAIL');\n if (fails.length === 0) return;\n process.stdout.write('\\n');\n logger.info('To fix:');\n fails.forEach((r, i) => {\n const hint = r.detail ? ` — ${r.detail}` : '';\n logger.info(` ${i + 1}. ${r.label}${hint}`);\n });\n process.stdout.write('\\n');\n}\n\nfunction printRow(r: CheckResult): void {\n const tag = `[${r.status}]`;\n const line = `${tag} ${r.label}${r.detail ? ` — ${r.detail}` : ''}`;\n if (r.status === 'FAIL') logger.error(line);\n else if (r.status === 'WARN') logger.warn(line);\n else logger.info(line);\n}\n\nasync function checkBinary(name: string, args: string[]): Promise<CheckResult> {\n return new Promise((resolve) => {\n const child = spawn(name, args, { stdio: ['ignore', 'pipe', 'pipe'] });\n let stdout = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.on('error', () => {\n resolve({\n status: 'FAIL',\n label: `${name} not on PATH`,\n detail: installHintFor(name),\n });\n });\n child.on('exit', (code) => {\n if (code === 0) {\n const firstLine = stdout.split('\\n')[0]?.trim() ?? '';\n resolve({ status: 'PASS', label: `${name} present`, detail: firstLine });\n } else {\n resolve({\n status: 'FAIL',\n label: `${name} exited with code ${code}`,\n detail: installHintFor(name),\n });\n }\n });\n });\n}\n\nfunction providerEnvHint(slot: 'llm' | 'tts', provider: string, envVar: string): string {\n const dashboards: Record<string, string> = {\n anthropic: 'https://console.anthropic.com/settings/keys',\n openai: 'https://platform.openai.com/api-keys',\n elevenlabs: 'https://elevenlabs.io/app/settings/api-keys',\n };\n const dash = dashboards[provider];\n const dashHint = dash ? ` (get a key from ${dash})` : '';\n const altHint =\n slot === 'llm'\n ? ` — or switch llm.default.provider to \"agent_bridge\" in demo.yaml to use a local CLI agent (no API key needed)`\n : '';\n return `add ${envVar}=... to your project's .env file${dashHint}${altHint}`;\n}\n\nfunction installHintFor(binary: string): string {\n const p = osPlatform();\n if (binary !== 'ffmpeg' && binary !== 'ffprobe') return '';\n // ffprobe ships alongside ffmpeg in every distro's ffmpeg package, so the hint is the same.\n if (p === 'darwin') return 'install via `brew install ffmpeg`';\n if (p === 'win32') return 'install via `winget install Gyan.FFmpeg` or `choco install ffmpeg`';\n // linux — show the three common package managers\n return 'install via `apt install ffmpeg` (Debian/Ubuntu), `pacman -S ffmpeg` (Arch), or `dnf install ffmpeg` (Fedora)';\n}\n\nasync function checkPlaywrightBrowser(config: ShowrunnerConfig): Promise<CheckResult> {\n const browserName = config.recording.browser;\n try {\n const exec = browserMap[browserName].executablePath();\n await stat(exec);\n return {\n status: 'PASS',\n label: `playwright ${browserName} binary present`,\n detail: exec,\n };\n } catch (err) {\n // Probe the sudo/root cache to give a better hint when the user ran\n // `sudo npx playwright install` and the browser landed in /root/.cache\n // (or %SystemRoot%\\System32\\config\\systemprofile\\AppData\\Local on Windows).\n const sudoHit = await probeRootCache(browserName);\n const fallback = `run \\`npx playwright install ${browserName}\\``;\n if (sudoHit) {\n return {\n status: 'FAIL',\n label: `playwright ${browserName} binary missing for current user, but found in root/admin cache`,\n detail:\n `${sudoHit} — re-run install WITHOUT sudo so the browser lands in your user cache: ${fallback}`,\n };\n }\n return {\n status: 'FAIL',\n label: `playwright ${browserName} binary missing`,\n detail: `${fallback} (${err instanceof Error ? err.message : String(err)})`,\n };\n }\n}\n\nasync function probeRootCache(browserName: string): Promise<string | null> {\n const candidates: string[] = [];\n const home = homedir();\n const p = osPlatform();\n\n if (p === 'linux') {\n candidates.push('/root/.cache/ms-playwright');\n } else if (p === 'darwin') {\n candidates.push('/var/root/Library/Caches/ms-playwright');\n } else if (p === 'win32') {\n const systemRoot = process.env['SystemRoot'] ?? 'C:\\\\Windows';\n candidates.push(join(systemRoot, 'System32', 'config', 'systemprofile', 'AppData', 'Local', 'ms-playwright'));\n }\n\n // Don't flag if the current user is root — the executablePath() above would have hit.\n if (candidates.length === 0) return null;\n if (home === '/root' || home === '/var/root') return null;\n\n for (const dir of candidates) {\n try {\n const entries = await readdir(dir);\n const match = entries.find((e) => e.toLowerCase().startsWith(browserName.toLowerCase()));\n if (match) {\n return `found at ${join(dir, match)}`;\n }\n } catch {\n // dir doesn't exist or unreadable — fine, try next\n }\n }\n return null;\n}\n\nasync function checkTargetReachable(url: string): Promise<CheckResult> {\n try {\n const start = Date.now();\n const res = await undiciRequest(url, {\n method: 'HEAD',\n bodyTimeout: 5000,\n headersTimeout: 5000,\n });\n const elapsed = Date.now() - start;\n if (res.statusCode >= 200 && res.statusCode < 500) {\n return {\n status: 'PASS',\n label: `target ${url} reachable (HTTP ${res.statusCode}, ${elapsed}ms)`,\n };\n }\n return {\n status: 'WARN',\n label: `target ${url} returned HTTP ${res.statusCode}`,\n };\n } catch (err) {\n const reason = err instanceof Error ? err.message.trim() : String(err).trim();\n const prefix = reason ? `${reason} — ` : '';\n return {\n status: 'FAIL',\n label: `target ${url} not reachable`,\n detail: `${prefix}start your dev server on this URL, or change \\`recording.target_url\\` in demo.yaml`,\n };\n }\n}\n\nasync function checkScript(label: string, abs: string): Promise<CheckResult> {\n try {\n await stat(abs);\n } catch {\n return {\n status: 'FAIL',\n label: `${label} not found`,\n detail: `expected at ${abs} — re-scaffold (\\`showrunner init\\` writes these) or remove the entry from demo.yaml's recording.state block`,\n };\n }\n if (process.platform !== 'win32') {\n try {\n await access(abs, constants.X_OK);\n } catch {\n return {\n status: 'WARN',\n label: `${label} found but not executable`,\n detail: `chmod +x ${abs}`,\n };\n }\n }\n return { status: 'PASS', label: `${label} ok`, detail: abs };\n}\n\nasync function firstExistingAncestor(p: string): Promise<string> {\n let current = p;\n while (true) {\n try {\n await stat(current);\n return current;\n } catch {\n const parent = dirname(current);\n if (parent === current) return current;\n current = parent;\n }\n }\n}\n","import type { ShowrunnerConfig, LLMProviderConfig, TTSProviderConfig } from './schema.js';\n\nexport interface ProviderEnvCheck {\n provider: string;\n slot: 'llm' | 'tts';\n stage?: string;\n envVar: string;\n set: boolean;\n}\n\n/**\n * Inspect the config and return one row per provider env var that needs to be\n * set. Used by `validate` (warnings) and `doctor` (PASS/FAIL rows). Providers\n * that don't need an env var (agent_bridge, custom) are skipped.\n */\nexport function inspectProviderEnv(config: ShowrunnerConfig): ProviderEnvCheck[] {\n const rows: ProviderEnvCheck[] = [];\n\n // LLM default\n const llmRow = inspectLLMSpec(config.llm.default);\n if (llmRow) rows.push(llmRow);\n\n // LLM per-stage overrides\n if (config.llm.overrides) {\n for (const [stage, spec] of Object.entries(config.llm.overrides)) {\n if (!spec) continue;\n const row = inspectLLMSpec(spec);\n if (row) rows.push({ ...row, stage });\n }\n }\n\n // TTS\n const ttsRow = inspectTTSSpec(config.voiceover.provider);\n if (ttsRow) rows.push(ttsRow);\n\n return rows;\n}\n\nfunction inspectLLMSpec(spec: LLMProviderConfig): Omit<ProviderEnvCheck, 'stage'> | null {\n switch (spec.provider) {\n case 'anthropic':\n case 'openai':\n return {\n provider: spec.provider,\n slot: 'llm',\n envVar: spec.api_key_env,\n set: Boolean(process.env[spec.api_key_env]),\n };\n case 'agent_bridge':\n case 'custom':\n return null;\n }\n}\n\nfunction inspectTTSSpec(spec: TTSProviderConfig): Omit<ProviderEnvCheck, 'stage'> | null {\n switch (spec.name) {\n case 'elevenlabs':\n case 'openai':\n return {\n provider: spec.name,\n slot: 'tts',\n envVar: spec.api_key_env,\n set: Boolean(process.env[spec.api_key_env]),\n };\n case 'custom':\n return null;\n }\n}\n\nexport function formatMissingEnvVars(rows: ProviderEnvCheck[]): string[] {\n return rows\n .filter((r) => !r.set)\n .map(\n (r) =>\n `${r.slot} provider \"${r.provider}\"${r.stage ? ` (stage: ${r.stage})` : ''} expects ${r.envVar} but it is not set`,\n );\n}\n","export type ResolutionPreset = 'low' | 'standard' | 'high' | 'extreme';\n\nexport const RESOLUTION_PRESETS: readonly ResolutionPreset[] = [\n 'low',\n 'standard',\n 'high',\n 'extreme',\n] as const;\n\nexport interface Resolution {\n width: number;\n height: number;\n}\n\nconst PRESET_MAP: Record<ResolutionPreset, Resolution> = {\n low: { width: 854, height: 480 },\n standard: { width: 1280, height: 720 },\n high: { width: 1920, height: 1080 },\n extreme: { width: 3840, height: 2160 },\n};\n\nexport function resolvePreset(value: string): Resolution {\n if (!RESOLUTION_PRESETS.includes(value as ResolutionPreset)) {\n throw new Error(\n `--resolution must be one of: ${RESOLUTION_PRESETS.join(', ')} (got \"${value}\")`,\n );\n }\n return PRESET_MAP[value as ResolutionPreset];\n}\n\nexport function formatResolution(r: Resolution): string {\n return `${r.width}x${r.height}`;\n}\n","import { mkdir, writeFile, access } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { logger } from '../util/logger.js';\nimport {\n RESOLUTION_PRESETS,\n formatResolution,\n resolvePreset,\n type Resolution,\n type ResolutionPreset,\n} from '../util/resolutionPresets.js';\nimport { detectEnvironment } from '../setup/detect.js';\nimport { runWizard } from '../setup/wizard.js';\n\nexport type LLMProviderChoice = 'anthropic' | 'openai' | 'agent_bridge';\nexport type TTSProviderChoice = 'elevenlabs' | 'openai' | 'custom';\n\nconst LLM_CHOICES: LLMProviderChoice[] = ['anthropic', 'openai', 'agent_bridge'];\nconst TTS_CHOICES: TTSProviderChoice[] = ['elevenlabs', 'openai', 'custom'];\n\ninterface InitOpts {\n name: string;\n url: string;\n dir: string;\n force: boolean;\n yes?: boolean;\n llmProvider?: string;\n ttsProvider?: string;\n resolution?: string;\n}\n\ninterface ResolvedInitOpts extends Omit<InitOpts, 'resolution'> {\n llm: LLMProviderChoice;\n tts: TTSProviderChoice;\n resolutionPreset: ResolutionPreset;\n resolution: Resolution;\n}\n\nconst PLACEHOLDER_FILES = [\n 'auth/.gitkeep',\n 'assets/fonts/.gitkeep',\n 'scripts/.gitkeep',\n 'segments/audio/.gitkeep',\n 'segments/video/.gitkeep',\n 'output/.gitkeep',\n];\n\nexport async function initCommand(opts: InitOpts): Promise<void> {\n const wantsInteractive = Boolean(process.stdout.isTTY) && !opts.yes;\n\n let resolved: ResolvedInitOpts;\n let collectedKeys: Record<string, string> = {};\n\n if (wantsInteractive) {\n const env = await detectEnvironment();\n const wiz = await runWizard(env);\n if (!wiz) return; // user cancelled\n resolved = {\n name: wiz.projectName,\n url: wiz.url,\n dir: opts.dir,\n force: opts.force,\n llm: wiz.llm,\n tts: wiz.tts,\n resolutionPreset: wiz.resolutionPreset,\n resolution: resolvePreset(wiz.resolutionPreset),\n };\n collectedKeys = wiz.collectedKeys;\n } else {\n const resolutionPreset = validateChoice<ResolutionPreset>(\n opts.resolution,\n [...RESOLUTION_PRESETS],\n 'standard',\n '--resolution',\n );\n resolved = {\n ...opts,\n llm: validateChoice<LLMProviderChoice>(\n opts.llmProvider,\n LLM_CHOICES,\n 'anthropic',\n '--llm-provider',\n ),\n tts: validateChoice<TTSProviderChoice>(\n opts.ttsProvider,\n TTS_CHOICES,\n 'elevenlabs',\n '--tts-provider',\n ),\n resolutionPreset,\n resolution: resolvePreset(resolutionPreset),\n };\n }\n\n const parent = isAbsolute(resolved.dir) ? resolved.dir : resolve(process.cwd(), resolved.dir);\n const projectRoot = join(parent, resolved.name);\n\n if (!resolved.force && (await pathExists(projectRoot))) {\n logger.error(\n `Directory already exists: ${projectRoot}. Pass --force to overwrite, or choose a different --name/--dir.`,\n );\n process.exit(1);\n }\n\n await mkdir(projectRoot, { recursive: true });\n\n for (const rel of PLACEHOLDER_FILES) {\n const dest = join(projectRoot, rel);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, '', 'utf8');\n }\n\n await writeFile(join(projectRoot, 'demo.yaml'), demoYamlTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, '.env.example'), envExampleTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, '.gitignore'), gitignoreTemplate(), 'utf8');\n await mkdir(join(projectRoot, 'docs'), { recursive: true });\n await writeFile(join(projectRoot, 'docs/PRD.md'), prdStubTemplate(resolved), 'utf8');\n await writeFile(join(projectRoot, 'scripts/manifest.json'), starterManifest(resolved), 'utf8');\n await writeFile(join(projectRoot, 'scripts/seed_demo_data.sh'), seedScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'scripts/reset_demo_data.sh'), resetScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'scripts/teardown.sh'), teardownScript(), {\n mode: 0o755,\n });\n await writeFile(join(projectRoot, 'README.md'), readmeTemplate(resolved), 'utf8');\n\n // If the wizard collected API keys, write a real .env (alongside .env.example).\n if (Object.keys(collectedKeys).length > 0) {\n await writeFile(join(projectRoot, '.env'), buildEnvFile(collectedKeys, resolved), 'utf8');\n }\n\n logger.info(`Showrunner project scaffolded at ${projectRoot} (llm=${resolved.llm}, tts=${resolved.tts})`);\n printNextSteps(resolved.name, resolved, collectedKeys);\n}\n\nfunction buildEnvFile(keys: Record<string, string>, resolved: ResolvedInitOpts): string {\n const lines: string[] = [`# Showrunner secrets — generated by \\`showrunner init\\`.`];\n for (const [k, v] of Object.entries(keys)) {\n lines.push(`${k}=${v}`);\n }\n lines.push('');\n lines.push(`# Optional: form / setup-script auth.`);\n lines.push(`DEMO_EMAIL=`);\n lines.push(`DEMO_PASSWORD=`);\n lines.push('');\n lines.push(`# Optional log level: debug | info | warn | error`);\n lines.push(`SHOWRUNNER_LOG_LEVEL=info`);\n lines.push('');\n if (resolved.llm === 'openai' || resolved.tts === 'openai') {\n // No-op block kept for parity with .env.example so the user sees the same shape.\n }\n return lines.join('\\n');\n}\n\nfunction printNextSteps(\n projectName: string,\n resolved: ResolvedInitOpts,\n collectedKeys: Record<string, string>,\n): void {\n const envVars = requiredEnvVars(resolved);\n const keysProvidedByWizard = Object.keys(collectedKeys);\n const remainingEnvVars = envVars.filter((v) => !keysProvidedByWizard.includes(v));\n\n const lines: string[] = ['', `Next:`, ''];\n\n let step = 1;\n lines.push(` ${step++}. cd ${projectName}`);\n\n if (envVars.length === 0) {\n lines.push(\n ` ${step++}. (.env not needed — agent_bridge LLM + ${resolved.tts} TTS don't use API keys.)`,\n );\n } else if (remainingEnvVars.length === 0) {\n // All keys already collected by the wizard and written to .env.\n lines.push(` ${step++}. .env is already populated with the keys you pasted.`);\n } else {\n if (keysProvidedByWizard.length === 0) {\n lines.push(` ${step++}. cp .env.example .env`);\n }\n lines.push(` ${step++}. Edit .env to fill in:`);\n for (const v of remainingEnvVars) {\n const dash = PROVIDER_DASHBOARDS[v];\n lines.push(` ${v}${dash ? ` (get it at ${dash})` : ''}`);\n }\n lines.push(\n ` (No keys? Switch llm.default.provider to \\`agent_bridge\\` in demo.yaml — uses your local Claude CLI instead.)`,\n );\n }\n\n lines.push(` ${step++}. Edit docs/PRD.md (the stub explains what each section is for).`);\n lines.push(` ${step++}. showrunner doctor -c demo.yaml`);\n lines.push(` ${step++}. showrunner run -c demo.yaml # → output/demo_final.mp4`);\n lines.push('');\n lines.push(\n `Don't want to write a PRD? Run \\`showrunner understand -c demo.yaml --interactive\\` instead — it asks 5 questions and builds the product model from your answers.`,\n );\n lines.push('');\n\n process.stdout.write(lines.join('\\n'));\n}\n\nconst PROVIDER_DASHBOARDS: Record<string, string> = {\n ANTHROPIC_API_KEY: 'https://console.anthropic.com/settings/keys',\n OPENAI_API_KEY: 'https://platform.openai.com/api-keys',\n ELEVENLABS_API_KEY: 'https://elevenlabs.io/app/settings/api-keys',\n};\n\nfunction requiredEnvVars(resolved: ResolvedInitOpts): string[] {\n const vars = new Set<string>();\n if (resolved.llm === 'anthropic') vars.add('ANTHROPIC_API_KEY');\n if (resolved.llm === 'openai') vars.add('OPENAI_API_KEY');\n if (resolved.tts === 'elevenlabs') vars.add('ELEVENLABS_API_KEY');\n if (resolved.tts === 'openai') vars.add('OPENAI_API_KEY');\n return [...vars];\n}\n\nfunction validateChoice<T extends string>(\n value: string | undefined,\n allowed: T[],\n defaultValue: T,\n flagName: string,\n): T {\n if (!value) return defaultValue;\n if (!allowed.includes(value as T)) {\n throw new Error(\n `${flagName} must be one of: ${allowed.join(', ')} (got \"${value}\")`,\n );\n }\n return value as T;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction demoYamlTemplate(opts: ResolvedInitOpts): string {\n return `# Showrunner demo config — edit me.\n# See https://github.com/your-org/showrunner for the full schema reference.\n\nproject:\n name: ${opts.name}\n # product_model: ./product_model.json # uncomment to skip comprehension\n\ncomprehension:\n mode: documents\n sources:\n - type: prd\n path: ./docs/PRD.md\n # - type: readme\n # path: ./README.md\n # - type: codebase\n # path: ./src\n # include: [\"**/*.ts\", \"**/*.tsx\"]\n\nscript:\n style: matter-of-fact\n duration_target_seconds: 90\n highlight_features: []\n # Set to true if you want the pipeline to halt after the script stage so you\n # can hand-edit scripts/vo_script.txt before voice synthesis runs. Resume\n # with: showrunner approve-vo -c demo.yaml\n vo_review_gate: false\n\nrecording:\n target_url: ${opts.url}\n # Resolution preset: ${opts.resolutionPreset} (${formatResolution(opts.resolution)}).\n # Rescaffold with --resolution low|standard|high|extreme, or change here and\n # keep output.resolution below in sync. \"showrunner doctor\" shows the live\n # ffmpeg thread cap so you can tell whether bigger is safe on your box.\n viewport:\n width: ${opts.resolution.width}\n height: ${opts.resolution.height}\n browser: chromium\n headless: false\n output_dir: ./segments/video\n state:\n seed_script: ./scripts/seed_demo_data.sh\n reset_script: ./scripts/reset_demo_data.sh\n teardown_script: ./scripts/teardown.sh\n # auth:\n # type: session\n # cookies_file: ./auth/session.json\n # local_storage_file: ./auth/storage.json\n\n${llmYamlBlock(opts.llm)}\n${voiceoverYamlBlock(opts.tts)}\noutput:\n format: mp4\n # Matches recording.viewport above (preset: ${opts.resolutionPreset}). Keep\n # these two values in sync to avoid upscaling artifacts during mux.\n resolution: ${formatResolution(opts.resolution)}\n fps: 30\n branding:\n title_card:\n enabled: true\n text: \"${opts.name}\"\n duration_seconds: 2\n font_size: 48\n text_color: \"#FFFFFF\"\n background_color: \"#0F172A\"\n logo_position: top_center\n outro_card:\n enabled: true\n text: \"thanks for watching\"\n duration_seconds: 2\n # background_music:\n # path: ./assets/bg_music.mp3\n # volume_db: -22\n output_path: ./output/demo_final.mp4\n`;\n}\n\nfunction llmYamlBlock(choice: LLMProviderChoice): string {\n switch (choice) {\n case 'anthropic':\n return `llm:\n default:\n provider: anthropic\n model: claude-opus-4-7\n api_key_env: ANTHROPIC_API_KEY\n # overrides:\n # script:\n # provider: agent_bridge\n # bridge:\n # mode: spawn\n # command: claude\n # args: [\"-p\", \"--output-format\", \"json\"]\n`;\n case 'openai':\n return `llm:\n default:\n provider: openai\n model: gpt-4o\n api_key_env: OPENAI_API_KEY\n`;\n case 'agent_bridge':\n return `llm:\n default:\n provider: agent_bridge\n bridge:\n mode: spawn\n # Headless agent CLI. Default is \\`claude -p --output-format json\\`.\n # Override per your installation.\n command: claude\n args: [\"-p\", \"--output-format\", \"json\"]\n # timeout_ms: 120000\n`;\n }\n}\n\nfunction voiceoverYamlBlock(choice: TTSProviderChoice): string {\n const tail = ` output_dir: ./segments/audio\n alignment_dir: ./segments/alignment\n duration_drift_threshold_pct: 15\n drift_strategy: adjust_timing\n tail_padding_ms: 500\n post_process:\n debreath: true\n pause_placement:\n strategy: action_boundaries\n min_silence_ms: 250\n snap_window_ms: 1200\n\n`;\n switch (choice) {\n case 'elevenlabs':\n return `voiceover:\n provider:\n name: elevenlabs\n voice_id: \"21m00Tcm4TlvDq8ikWAM\" # ElevenLabs default — replace with your chosen voice\n model: eleven_multilingual_v2\n api_key_env: ELEVENLABS_API_KEY\n endpoint: with_timestamps\n stability: 0.55\n similarity_boost: 0.75\n style: 0.0\n use_speaker_boost: true\n speed: 1.0\n # required: only ElevenLabs returns character alignment. Use best_effort with\n # other providers — captions degrade to whole-segment cues and at_word\n # actions fall back to at-time.\n alignment_strategy: required\n${tail}`;\n case 'openai':\n return `voiceover:\n provider:\n name: openai\n voice: alloy\n model: tts-1-hd\n api_key_env: OPENAI_API_KEY\n # base_url: https://api.openai.com/v1 # override for self-hosted gateways\n # OpenAI TTS does not return character alignment — must be best_effort.\n alignment_strategy: best_effort\n${tail}`;\n case 'custom':\n return `voiceover:\n provider:\n name: custom\n # Dynamic-import path resolved relative to this demo.yaml. The module's\n # default export must conform to the TTSProvider interface\n # (see src/providers/tts/types.ts in the Showrunner repo).\n module_path: ./tts_provider.mjs\n # options:\n # any_keys_you_want: true\n alignment_strategy: best_effort\n${tail}`;\n }\n}\n\nfunction envExampleTemplate(opts: ResolvedInitOpts): string {\n const vars = new Set<string>();\n if (opts.llm === 'anthropic') vars.add('ANTHROPIC_API_KEY');\n if (opts.llm === 'openai') vars.add('OPENAI_API_KEY');\n if (opts.tts === 'elevenlabs') vars.add('ELEVENLABS_API_KEY');\n if (opts.tts === 'openai') vars.add('OPENAI_API_KEY');\n\n const lines = [`# Showrunner secrets — copy to .env and fill in.`];\n for (const v of vars) lines.push(`${v}=`);\n if (vars.size === 0) {\n lines.push(`# (agent_bridge LLM + custom TTS — no provider env vars required)`);\n }\n lines.push('');\n lines.push(`# Optional: used by form / setup_script auth strategies.`);\n lines.push(`DEMO_EMAIL=`);\n lines.push(`DEMO_PASSWORD=`);\n lines.push('');\n lines.push(`# Optional log level: debug | info | warn | error`);\n lines.push(`SHOWRUNNER_LOG_LEVEL=info`);\n lines.push('');\n lines.push(`# Optional: cap libx264 threads when free memory is tight (e.g. WSL boxes).`);\n lines.push(`# SHOWRUNNER_FFMPEG_THREADS=2`);\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction gitignoreTemplate(): string {\n return `.env\n.env.local\n.env.*.local\n\n# Recording artifacts (large binaries)\nsegments/\noutput/\n\n# Captured auth state may contain sensitive tokens — uncomment if so\n# auth/*.json\n\n.showrunner-lock\n.showrunner-cache/\n\nplaywright-report/\ntest-results/\n\n*.log\n.DS_Store\n`;\n}\n\nfunction seedScript(): string {\n return `#!/usr/bin/env bash\n# seed_demo_data.sh — runs once before the recording session begins.\n# Use this to create demo users, seed records, and establish baseline state.\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID — unique identifier for this pipeline run\n#\n# Exit non-zero to halt the pipeline before recording starts.\n\nset -euo pipefail\n\necho \"[seed] noop — replace this script with your demo data seeding\"\n`;\n}\n\nfunction resetScript(): string {\n return `#!/usr/bin/env bash\n# reset_demo_data.sh — runs before each segment re-take.\n# Use this to undo mutations that previous takes may have introduced.\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID\n# SHOWRUNNER_SEGMENT_ID\n#\n# Not run on the initial full pipeline pass.\n\nset -euo pipefail\n\necho \"[reset] noop — replace this script with your per-segment reset logic\"\n`;\n}\n\nfunction teardownScript(): string {\n return `#!/usr/bin/env bash\n# teardown.sh — runs after the full session completes (success or failure).\n#\n# Environment variables provided by Showrunner:\n# SHOWRUNNER_RUN_ID\n# SHOWRUNNER_STATUS — \"success\" or \"failure\"\n#\n# Use this to clean up seeded data, close background processes, etc.\n\nset -euo pipefail\n\necho \"[teardown] noop (status=${'${SHOWRUNNER_STATUS:-unknown}'})\"\n`;\n}\n\nfunction starterManifest(opts: ResolvedInitOpts): string {\n const manifest = {\n total_duration_seconds: 8,\n generated_from: 'init-scaffold',\n segments: [\n {\n id: 'intro',\n label: 'Introduction',\n start: 0,\n end: 4,\n vo_line: `Welcome to ${opts.name}.`,\n actions: [{ type: 'idle', at: 0 }],\n transition: 'fade_in',\n },\n {\n id: 'outro',\n label: 'Outro',\n start: 4,\n end: 8,\n vo_line: 'Thanks for watching.',\n actions: [{ type: 'idle', at: 0 }],\n transition: 'fade_out',\n },\n ],\n };\n return JSON.stringify(manifest, null, 2) + '\\n';\n}\n\nfunction prdStubTemplate(opts: ResolvedInitOpts): string {\n return `# ${opts.name} — product brief\n\n> Fill in each section below. Showrunner's \\`understand\\` stage reads this file\n> and turns it into \\`product_model.json\\`, which the \\`script\\` stage then turns\n> into the manifest that drives recording + voiceover. The more concrete you\n> are here, the less you'll need to hand-edit the manifest afterwards.\n>\n> Delete these blockquote hints once you've replaced them with real content.\n\n## Elevator pitch\n\n> One paragraph (3–5 sentences). What is this product, who is it for, and what\n> single thing should a viewer walk away understanding? Write it like you'd\n> say it to a colleague over coffee, not like marketing copy.\n\n_Example:_ \"Atlas is a developer-facing log-tailing platform. It's for backend\nengineers who are tired of grepping through ssh sessions. The pitch is: paste a\nservice name, get a live, structured, queryable tail in under five seconds.\"\n\n## Primary user\n\n> One sentence on who the demo is for. Be specific about the role and the\n> moment they'd be watching this video.\n\n_Example:_ \"A backend engineer evaluating logging tools during a team-tooling\nreview.\"\n\n## Top 3 user flows (the demo's spine)\n\n> List the flows in the order the demo should walk through them. For each:\n> name the flow, one sentence describing what the user accomplishes, and any\n> selectors you already know are stable (data-testid is best). The script\n> stage will use this list as its outline.\n\n1. **Flow name** — what the user does (e.g. \"create their first project\").\n - Key selectors: \\`[data-testid=\"...\"]\\`, \\`[data-testid=\"...\"]\\`\n2. **Flow name** — what the user does.\n - Key selectors: ...\n3. **Flow name** — what the user does.\n - Key selectors: ...\n\n## Features to highlight\n\n> Bullet list. These get prioritized in the voiceover and on-screen timing.\n> Leave empty if you want the model to choose.\n\n- Feature A\n- Feature B\n\n## What this demo is NOT\n\n> Optional but useful. Things to *avoid* spending time on — admin pages,\n> settings, the auth flow, anything aspirational.\n\n- Don't show the settings page.\n- Don't mention pricing.\n\n## Tone / style\n\n> One line. Matches \\`script.style\\` in demo.yaml.\n\n_Default:_ matter-of-fact, technical, no marketing fluff.\n`;\n}\n\nfunction readmeTemplate(opts: ResolvedInitOpts): string {\n return `# ${opts.name}\n\nA Showrunner project. The pipeline runs in stages:\n\n1. **Comprehension** — reads docs and code, builds \\`product_model.json\\` (LLM: ${opts.llm})\n2. **Script** — turns the product model into \\`scripts/manifest.json\\` (LLM: ${opts.llm})\n3. **Record + Voiceover** — runs Playwright against ${opts.url} while synthesizing VO (TTS: ${opts.tts})\n4. **Mux** — combines everything into \\`output/demo_final.mp4\\`\n\n## First run\n\n\\`\\`\\`bash\ncp .env.example .env # then fill in keys\n$EDITOR docs/PRD.md # replace the stub with your product brief\nshowrunner doctor --config demo.yaml # preflight\nshowrunner understand --config demo.yaml # build product_model.json\nshowrunner run --config demo.yaml # script → record → voiceover → mux\nopen output/demo_final.mp4\n\\`\\`\\`\n\nIf \\`understand\\` doesn't feel ready, swap it for \\`showrunner understand --config demo.yaml --interactive\\`\nand answer five questions — it'll generate the product model without needing a PRD.\n\n## Customize\n\n- \\`demo.yaml\\` — main config (LLM + TTS provider sections are at the top of the file)\n- \\`docs/PRD.md\\` — product brief consumed by \\`understand\\`. Replace the stub with real content.\n- \\`scripts/seed_demo_data.sh\\` — environment prep before recording\n- \\`scripts/reset_demo_data.sh\\` — per-segment re-take prep\n- \\`scripts/teardown.sh\\` — cleanup\n\n## Re-record a single segment\n\nIf the LLM-generated manifest picks a busted selector and one segment fails,\ndemonstrate the right interaction in a live browser instead:\n\n\\`\\`\\`bash\nshowrunner record-actions --config demo.yaml --segment <segment-id>\n\\`\\`\\`\n\nShowrunner will replace that segment's actions with what you did.\n\n## Swap providers\n\nYou can change provider per-section in \\`demo.yaml\\` without re-running init. The\nschema accepts:\n\n- **LLM** (\\`llm.default.provider\\`): \\`anthropic\\`, \\`openai\\`, \\`agent_bridge\\`, \\`custom\\`\n- **TTS** (\\`voiceover.provider.name\\`): \\`elevenlabs\\`, \\`openai\\`, \\`custom\\`\n\nOnly ElevenLabs returns per-character alignment. Other TTS providers force\n\\`voiceover.alignment_strategy: best_effort\\` (captions become whole-segment cues\nand \\`at_word\\` actions degrade to \\`at\\`).\n`;\n}\n","import { spawn } from 'node:child_process';\nimport { access, stat } from 'node:fs/promises';\n\nexport interface DetectedEnvironment {\n claudeCli: boolean;\n ffmpeg: boolean;\n ffprobe: boolean;\n chromium: boolean;\n envVars: {\n anthropic: boolean;\n openai: boolean;\n elevenlabs: boolean;\n };\n}\n\nexport async function detectEnvironment(): Promise<DetectedEnvironment> {\n const [claudeCli, ffmpeg, ffprobe, chromium] = await Promise.all([\n isOnPath('claude'),\n isOnPath('ffmpeg'),\n isOnPath('ffprobe'),\n chromiumInstalled(),\n ]);\n\n return {\n claudeCli,\n ffmpeg,\n ffprobe,\n chromium,\n envVars: {\n anthropic: Boolean(process.env['ANTHROPIC_API_KEY']),\n openai: Boolean(process.env['OPENAI_API_KEY']),\n elevenlabs: Boolean(process.env['ELEVENLABS_API_KEY']),\n },\n };\n}\n\nasync function isOnPath(binary: string): Promise<boolean> {\n // We resolve via spawning the binary with --version (or similar) rather than\n // shelling out to `which`, so this works on Windows without bash.\n return new Promise((resolve) => {\n const useShell = process.platform === 'win32'; // .cmd/.ps1 shims\n const child = spawn(binary, ['--version'], {\n stdio: ['ignore', 'ignore', 'ignore'],\n shell: useShell,\n });\n let settled = false;\n const finish = (ok: boolean): void => {\n if (settled) return;\n settled = true;\n resolve(ok);\n };\n child.on('error', () => finish(false));\n child.on('exit', (code) => finish(code === 0));\n // Hard cap so a hung binary doesn't block setup.\n setTimeout(() => {\n if (!settled) {\n child.kill('SIGKILL');\n finish(false);\n }\n }, 4000);\n });\n}\n\nasync function chromiumInstalled(): Promise<boolean> {\n try {\n const { chromium } = await import('playwright-core');\n const exec = chromium.executablePath();\n await stat(exec);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import {\n intro,\n outro,\n text,\n password,\n select,\n confirm,\n note,\n spinner,\n isCancel,\n cancel,\n} from '@clack/prompts';\nimport type { DetectedEnvironment } from './detect.js';\nimport { probeUrl } from './targetProbe.js';\nimport { scanLocalPorts, type ScannedTarget } from './portScan.js';\nimport { discoverDevServer, type DevServerProposal } from './agentDiscover.js';\nimport { spawnAndWait } from './spawnDevServer.js';\nimport {\n RESOLUTION_PRESETS,\n type ResolutionPreset,\n} from '../util/resolutionPresets.js';\n\nexport type LLMProviderChoice = 'anthropic' | 'openai' | 'agent_bridge';\nexport type TTSProviderChoice = 'elevenlabs' | 'openai' | 'custom';\n\nexport interface WizardResult {\n projectName: string;\n url: string;\n llm: LLMProviderChoice;\n tts: TTSProviderChoice;\n resolutionPreset: ResolutionPreset;\n /** Map of env var → value. Empty if no keys needed or user skipped. */\n collectedKeys: Record<string, string>;\n}\n\nconst SLUG_RE = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/i;\n\nexport async function runWizard(env: DetectedEnvironment): Promise<WizardResult | null> {\n intro('Showrunner setup');\n\n note(formatDetection(env), 'Detected on this machine');\n\n const projectName = await ask(\n text({\n message: \"What's the project directory name?\",\n placeholder: 'showrunner-demo',\n defaultValue: 'showrunner-demo',\n validate: (v) => {\n if (!v) return undefined; // default applies\n if (!SLUG_RE.test(v)) {\n return 'Use letters/digits/dash/underscore/dot, starting & ending with alphanumeric.';\n }\n return undefined;\n },\n }),\n );\n if (projectName === null) return null;\n\n const resolutionPreset = (await ask(\n select<ResolutionPreset>({\n message: 'Recording resolution preset?',\n options: [\n { value: 'low', label: 'low (854×480) — draft / fast iteration' },\n { value: 'standard', label: 'standard (1280×720) — recommended default' },\n { value: 'high', label: 'high (1920×1080)' },\n { value: 'extreme', label: 'extreme (3840×2160) — needs serious RAM' },\n ],\n initialValue: 'standard' as ResolutionPreset,\n }),\n )) as ResolutionPreset | null;\n if (resolutionPreset === null) return null;\n if (!RESOLUTION_PRESETS.includes(resolutionPreset)) {\n cancel('Invalid resolution preset.');\n return null;\n }\n\n // LLM provider — bias toward agent_bridge if claude CLI is on PATH.\n const llmDefault: LLMProviderChoice = env.claudeCli ? 'agent_bridge' : 'anthropic';\n const llm = (await ask(\n select<LLMProviderChoice>({\n message: 'Which LLM provider should drive comprehension + script?',\n options: [\n {\n value: 'agent_bridge',\n label: env.claudeCli\n ? \"agent_bridge — uses your local `claude` CLI (detected). No API key required.\"\n : 'agent_bridge — uses a local headless agent CLI. No API key required.',\n },\n {\n value: 'anthropic',\n label: env.envVars.anthropic\n ? 'anthropic — Claude via API (ANTHROPIC_API_KEY already in env)'\n : 'anthropic — Claude via API (you\\'ll paste an API key in a moment)',\n },\n {\n value: 'openai',\n label: env.envVars.openai\n ? 'openai — GPT via API (OPENAI_API_KEY already in env)'\n : \"openai — GPT via API (you'll paste an API key in a moment)\",\n },\n ],\n initialValue: llmDefault,\n }),\n )) as LLMProviderChoice | null;\n if (llm === null) return null;\n\n const collectedKeys: Record<string, string> = {};\n if (llm === 'anthropic' && !env.envVars.anthropic) {\n const key = await askKey('ANTHROPIC_API_KEY', 'https://console.anthropic.com/settings/keys');\n if (key === null) return null;\n if (key.length > 0) collectedKeys['ANTHROPIC_API_KEY'] = key;\n }\n if (llm === 'openai' && !env.envVars.openai) {\n const key = await askKey('OPENAI_API_KEY', 'https://platform.openai.com/api-keys');\n if (key === null) return null;\n if (key.length > 0) collectedKeys['OPENAI_API_KEY'] = key;\n }\n\n // TTS provider — prefer elevenlabs for alignment; if user has agent_bridge LLM and no\n // OpenAI key, default to `custom` so they aren't forced to fill another key.\n const ttsDefault: TTSProviderChoice =\n llm === 'agent_bridge' && !env.envVars.openai && !env.envVars.elevenlabs\n ? 'custom'\n : 'elevenlabs';\n const tts = (await ask(\n select<TTSProviderChoice>({\n message: 'Which TTS provider for voiceover?',\n options: [\n {\n value: 'elevenlabs',\n label: env.envVars.elevenlabs\n ? 'elevenlabs — best alignment (ELEVENLABS_API_KEY already in env)'\n : \"elevenlabs — best alignment (you'll paste an API key)\",\n },\n {\n value: 'openai',\n label:\n env.envVars.openai || llm === 'openai'\n ? 'openai — tts-1-hd (reuses your OpenAI key)'\n : \"openai — tts-1-hd (you'll paste an API key)\",\n },\n {\n value: 'custom',\n label: 'custom — plug in your own TTSProvider module. No API key required here.',\n },\n ],\n initialValue: ttsDefault,\n }),\n )) as TTSProviderChoice | null;\n if (tts === null) return null;\n\n if (tts === 'elevenlabs' && !env.envVars.elevenlabs) {\n const key = await askKey('ELEVENLABS_API_KEY', 'https://elevenlabs.io/app/settings/api-keys');\n if (key === null) return null;\n if (key.length > 0) collectedKeys['ELEVENLABS_API_KEY'] = key;\n }\n if (tts === 'openai' && !env.envVars.openai && !collectedKeys['OPENAI_API_KEY']) {\n const key = await askKey('OPENAI_API_KEY', 'https://platform.openai.com/api-keys');\n if (key === null) return null;\n if (key.length > 0) collectedKeys['OPENAI_API_KEY'] = key;\n }\n\n // Target URL: full Phase B+C cascade — direct probe → port-scan suggestion →\n // optional agent discovery → fallback to user-entered URL with warning.\n const resolved = await resolveTargetUrl({\n env,\n llm,\n projectDir: process.cwd(),\n });\n if (resolved === null) return null;\n const url = resolved.url;\n\n const proceed = await ask(\n confirm({\n message: `Scaffold ${projectName}/ with these choices?`,\n initialValue: true,\n }),\n );\n if (proceed === null || proceed === false) {\n cancel('Setup cancelled. Nothing written.');\n return null;\n }\n\n outro('Scaffolding now...');\n\n return {\n projectName,\n url,\n llm,\n tts,\n resolutionPreset,\n collectedKeys,\n };\n}\n\nasync function askKey(envVar: string, dashUrl: string): Promise<string | null> {\n const value = await ask(\n password({\n message: `Paste your ${envVar} (or press enter to skip and fill .env later)`,\n }),\n );\n if (value === null) return null;\n return typeof value === 'string' ? value.trim() : '';\n}\n\nasync function ask<T>(promptResult: Promise<T | symbol>): Promise<T | null> {\n const result = await promptResult;\n if (isCancel(result)) {\n cancel('Setup cancelled.');\n return null;\n }\n return result as T;\n}\n\nfunction formatDetection(env: DetectedEnvironment): string {\n const lines: string[] = [];\n lines.push(`claude CLI: ${env.claudeCli ? 'found' : 'not found'}`);\n lines.push(`ffmpeg: ${env.ffmpeg ? 'found' : 'NOT found ← required for muxing'}`);\n lines.push(`ffprobe: ${env.ffprobe ? 'found' : 'NOT found ← required for muxing'}`);\n lines.push(`chromium: ${env.chromium ? 'installed' : 'NOT installed ← run `showrunner install-browser`'}`);\n lines.push('');\n lines.push('env vars:');\n lines.push(` ANTHROPIC_API_KEY: ${env.envVars.anthropic ? 'set' : 'unset'}`);\n lines.push(` OPENAI_API_KEY: ${env.envVars.openai ? 'set' : 'unset'}`);\n lines.push(` ELEVENLABS_API_KEY: ${env.envVars.elevenlabs ? 'set' : 'unset'}`);\n return lines.join('\\n');\n}\n\ninterface ResolveTargetUrlInput {\n env: DetectedEnvironment;\n llm: LLMProviderChoice;\n projectDir: string;\n}\n\ninterface ResolvedTarget {\n url: string;\n /** PID of a dev-server we spawned, if any. */\n spawnedPid?: number;\n /** Set when we ended up keeping the user's typed URL despite a failed probe. */\n warnedUnreachable?: boolean;\n}\n\n/**\n * Multi-step URL resolution. Returns null if the user cancels.\n *\n * Order:\n * 1. Ask URL; probe it.\n * 2. If unreachable, port-scan localhost; offer matches.\n * 3. If still nothing AND llm=agent_bridge AND claude detected, offer agent discovery.\n * 4. Fall through: keep user-typed URL with a warning.\n */\nasync function resolveTargetUrl(input: ResolveTargetUrlInput): Promise<ResolvedTarget | null> {\n const { env, llm, projectDir } = input;\n\n // Step 1: ask + probe.\n const initialUrl = await ask(\n text({\n message: 'What URL is your product dev server on?',\n placeholder: 'http://localhost:3000',\n defaultValue: 'http://localhost:3000',\n validate: (v) => {\n if (!v) return undefined;\n try {\n new URL(v);\n return undefined;\n } catch {\n return 'Must be a valid URL (e.g. http://localhost:3000).';\n }\n },\n }),\n );\n if (initialUrl === null) return null;\n\n const probeSpin = spinner();\n probeSpin.start(`Probing ${initialUrl} ...`);\n const directProbe = await probeUrl(initialUrl);\n if (directProbe.reachable) {\n probeSpin.stop(`${initialUrl} reachable (HTTP ${directProbe.statusCode}, ${directProbe.elapsedMs}ms).`);\n return { url: initialUrl };\n }\n probeSpin.stop(`${initialUrl} not reachable yet.`);\n\n // Step 2: port-scan localhost.\n const scanSpin = spinner();\n scanSpin.start('Scanning common dev-server ports on localhost...');\n let scanHits: ScannedTarget[] = [];\n try {\n scanHits = await scanLocalPorts('localhost');\n } catch {\n // best-effort — ignore scan failures\n }\n if (scanHits.length > 0) {\n scanSpin.stop(`Found ${scanHits.length} responding port${scanHits.length === 1 ? '' : 's'} on localhost.`);\n const pick = await ask(\n select<string>({\n message: 'Use one of the running servers?',\n options: [\n ...scanHits.map((h) => ({\n value: h.url,\n label: `${h.url} (HTTP ${h.statusCode})`,\n })),\n { value: '__keep__', label: `No — keep what I typed (${initialUrl})` },\n { value: '__agent__', label: 'No — let the agent figure it out (only useful with agent_bridge + claude)' },\n ],\n initialValue: scanHits[0]?.url ?? '__keep__',\n }),\n );\n if (pick === null) return null;\n if (pick !== '__keep__' && pick !== '__agent__') {\n return { url: pick };\n }\n if (pick === '__keep__') {\n warnFallback(initialUrl);\n return { url: initialUrl, warnedUnreachable: true };\n }\n // pick === '__agent__' falls through to step 3.\n } else {\n scanSpin.stop('No common dev ports responding on localhost.');\n }\n\n // Step 3: agent discovery (only if applicable).\n const agentAvailable = llm === 'agent_bridge' && env.claudeCli;\n if (!agentAvailable) {\n if (scanHits.length === 0) {\n // Didn't already prompt in the scan-hit branch — explicit fallback.\n warnFallback(initialUrl);\n return { url: initialUrl, warnedUnreachable: true };\n }\n return { url: initialUrl, warnedUnreachable: true };\n }\n\n const useAgent = await ask(\n confirm({\n message: 'Want me to inspect this directory with the `claude` agent and propose a dev-server command + URL?',\n initialValue: true,\n }),\n );\n if (useAgent === null) return null;\n if (useAgent === false) {\n warnFallback(initialUrl);\n return { url: initialUrl, warnedUnreachable: true };\n }\n\n const discoverSpin = spinner();\n discoverSpin.start('Asking the agent to read your project...');\n let proposal: DevServerProposal;\n try {\n proposal = await discoverDevServer(projectDir);\n discoverSpin.stop('Agent returned a proposal.');\n } catch (err) {\n discoverSpin.stop('Agent inspection failed.');\n note(\n `${err instanceof Error ? err.message : String(err)}\\n\\nKeeping your typed URL for now. Start your server, then run:\\n showrunner set-target -c demo.yaml --url ${initialUrl}`,\n 'Agent error',\n );\n return { url: initialUrl, warnedUnreachable: true };\n }\n\n note(formatProposal(proposal, projectDir), 'Agent proposal');\n\n const spawnIt = await ask(\n confirm({\n message: `Spawn \\`${proposal.command} ${proposal.args.join(' ')}\\` in ${projectDir} and wait for ${proposal.url}?`,\n initialValue: proposal.confidence !== 'low',\n }),\n );\n if (spawnIt === null) return null;\n if (spawnIt === false) {\n note(\n `OK — start the server yourself, then run:\\n showrunner set-target -c demo.yaml --url ${proposal.url}`,\n 'Skipping spawn',\n );\n return { url: proposal.url, warnedUnreachable: true };\n }\n\n const spawnSpin = spinner();\n spawnSpin.start(`Spawning and waiting for ${proposal.url} (up to 60s)...`);\n const spawnResult = await spawnAndWait({\n command: proposal.command,\n args: proposal.args,\n url: proposal.url,\n cwd: projectDir,\n });\n if (spawnResult.ok) {\n spawnSpin.stop(`Dev server up at ${proposal.url} (pid ${spawnResult.pid}).`);\n note(\n `When you're done, stop it with: kill ${spawnResult.pid}`,\n 'Server running',\n );\n return { url: proposal.url, spawnedPid: spawnResult.pid };\n }\n spawnSpin.stop(`Spawn or wait failed.`);\n note(\n `${spawnResult.reason ?? 'unknown error'}\\n\\nKeeping ${proposal.url} as the configured target. If the server eventually comes up, no action needed; otherwise run:\\n showrunner set-target -c demo.yaml --url <actual-url>`,\n 'Spawn issue',\n );\n return { url: proposal.url, warnedUnreachable: true };\n}\n\nfunction warnFallback(url: string): void {\n note(\n `That's fine — you can start your dev server later. When it's up, run:\\n\\n showrunner set-target -c demo.yaml --url ${url}\\n\\nto re-probe and update the config.`,\n 'Heads up',\n );\n}\n\nfunction formatProposal(p: DevServerProposal, cwd: string): string {\n return [\n `command: ${p.command} ${p.args.join(' ')}`,\n `cwd: ${cwd}`,\n `url: ${p.url}`,\n `confidence: ${p.confidence}`,\n `rationale: ${p.rationale}`,\n ].join('\\n');\n}\n","import { request as undiciRequest } from 'undici';\n\nexport interface ProbeResult {\n url: string;\n reachable: boolean;\n statusCode?: number;\n elapsedMs?: number;\n reason?: string;\n}\n\nconst DEFAULT_TIMEOUT_MS = 4000;\n\nexport async function probeUrl(url: string, timeoutMs = DEFAULT_TIMEOUT_MS): Promise<ProbeResult> {\n const start = Date.now();\n try {\n const res = await undiciRequest(url, {\n method: 'HEAD',\n bodyTimeout: timeoutMs,\n headersTimeout: timeoutMs,\n });\n const elapsedMs = Date.now() - start;\n // Treat 4xx as \"reachable\" (the server is up; auth/route is the user's\n // problem). 5xx is still reachable but warning-worthy.\n return {\n url,\n reachable: res.statusCode >= 200 && res.statusCode < 500,\n statusCode: res.statusCode,\n elapsedMs,\n };\n } catch (err) {\n return {\n url,\n reachable: false,\n reason: err instanceof Error ? err.message : String(err),\n elapsedMs: Date.now() - start,\n };\n }\n}\n","import { probeUrl } from './targetProbe.js';\n\n// Common dev-server ports across popular stacks.\n// 3000 Next / CRA / Express\n// 3001 Next alt / Storybook secondary\n// 4321 Astro default\n// 5173 Vite default\n// 5174 Vite alt (when 5173 is taken)\n// 8000 Django / Python / Hugo / Docusaurus\n// 8080 Vue CLI / generic Java\nexport const COMMON_DEV_PORTS = [3000, 3001, 4321, 5173, 5174, 8000, 8080] as const;\n\nexport interface ScannedTarget {\n url: string;\n port: number;\n statusCode: number;\n elapsedMs: number;\n}\n\n/**\n * Probe a set of ports on `host` in parallel and return the ones that responded.\n * Times out fast (default 800ms per port) so worst-case duration is bounded.\n */\nexport async function scanLocalPorts(\n host = 'localhost',\n ports: readonly number[] = COMMON_DEV_PORTS,\n timeoutMs = 800,\n): Promise<ScannedTarget[]> {\n const probes = ports.map(async (port) => {\n const url = `http://${host}:${port}`;\n const result = await probeUrl(url, timeoutMs);\n if (!result.reachable) return null;\n return {\n url,\n port,\n statusCode: result.statusCode ?? 0,\n elapsedMs: result.elapsedMs ?? 0,\n };\n });\n const all = await Promise.all(probes);\n return all\n .filter((x): x is ScannedTarget => x !== null)\n .sort((a, b) => a.port - b.port);\n}\n","import { z } from 'zod';\nimport { AgentBridgeLLMProvider } from '../providers/llm/agentBridge.js';\nimport { collectProjectSnapshot, renderSnapshot } from './projectSnapshot.js';\n\nexport const DevServerProposalSchema = z.object({\n command: z.string().min(1).describe('Executable name, e.g. \"npm\" or \"pnpm\".'),\n args: z.array(z.string()).describe('CLI arguments, e.g. [\"run\", \"dev\"].'),\n url: z.string().url().describe('URL the dev server will listen on once started.'),\n confidence: z.enum(['high', 'medium', 'low']),\n rationale: z.string().min(1).describe('One short sentence on why this is the right command.'),\n});\n\nexport type DevServerProposal = z.infer<typeof DevServerProposalSchema>;\n\nexport interface DiscoverOptions {\n /** Override the claude binary on PATH (default: \"claude\"). */\n command?: string;\n args?: string[];\n /** Hard cap on the LLM call (default 90s). */\n timeoutMs?: number;\n}\n\nconst SYSTEM_PROMPT = [\n 'You are helping the Showrunner CLI identify how to start a project\\'s development server.',\n 'You will be given a project snapshot (package.json, README head, common framework config files, .env.example).',\n '',\n 'Your job: identify the command + arguments to run the dev server, and the URL it will listen on.',\n '',\n 'Rules:',\n '- Use the scripts in package.json as your primary signal. Prefer \"dev\" > \"start\" > \"serve\" when present.',\n '- For Vite default port = 5173; Next/CRA = 3000; Astro = 4321; Vue CLI = 8080; Django = 8000.',\n '- If the project explicitly sets a port (via env, config, or CLI flags), use that, NOT the framework default.',\n '- If the snapshot is too sparse to tell, set confidence to \"low\" and use your best guess for both command and URL.',\n '- \"confidence\" reflects how sure you are. \"high\" = explicit script + config-confirmed port; \"medium\" = explicit script, default port; \"low\" = guessing.',\n '- \"rationale\" is one short sentence, plain English. No marketing speak.',\n '',\n 'Return only the structured output. No prose outside the JSON.',\n].join('\\n');\n\nexport async function discoverDevServer(\n projectDir: string,\n opts: DiscoverOptions = {},\n): Promise<DevServerProposal> {\n const snapshot = await collectProjectSnapshot(projectDir);\n const rendered = renderSnapshot(snapshot);\n\n const provider = new AgentBridgeLLMProvider({\n mode: 'spawn',\n command: opts.command ?? 'claude',\n args: opts.args ?? ['-p', '--output-format', 'json'],\n timeoutMs: opts.timeoutMs ?? 90_000,\n });\n\n const userPrompt = [\n `Project directory: ${projectDir}`,\n '',\n 'Project snapshot follows:',\n '',\n rendered,\n '',\n 'Identify the dev-server command + args + URL.',\n ].join('\\n');\n\n return await provider.generateStructured({\n systemPrompt: SYSTEM_PROMPT,\n userPrompt,\n schema: DevServerProposalSchema,\n schemaName: 'DevServerProposal',\n });\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\n\nconst FILE_CAP_BYTES = 2048;\nconst README_LINE_CAP = 100;\n\nconst CONFIG_FILE_PATTERNS: RegExp[] = [\n /^vite\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^next\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^astro\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^nuxt\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^svelte\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^vue\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^webpack\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^remix\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^gatsby-config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^rsbuild\\.config\\.(?:js|mjs|cjs|ts|mts|cts)$/,\n /^manage\\.py$/,\n /^pyproject\\.toml$/,\n /^Cargo\\.toml$/,\n];\n\nexport interface ProjectSnapshot {\n projectDir: string;\n sections: SnapshotSection[];\n}\n\nexport interface SnapshotSection {\n label: string;\n path: string;\n body: string;\n}\n\nexport async function collectProjectSnapshot(projectDir: string): Promise<ProjectSnapshot> {\n const sections: SnapshotSection[] = [];\n\n // package.json — full file (truncate to cap, but rarely necessary).\n const pkg = await readFileSafe(join(projectDir, 'package.json'));\n if (pkg) sections.push({ label: 'package.json', path: 'package.json', body: pkg });\n\n // README — head only.\n for (const candidate of ['README.md', 'readme.md', 'README.MD']) {\n const r = await readFileSafe(join(projectDir, candidate), { lineCap: README_LINE_CAP });\n if (r) {\n sections.push({ label: 'README (head)', path: candidate, body: r });\n break;\n }\n }\n\n // .env.example — useful for spotting PORT / HOST / NEXT_PUBLIC_BASE_URL hints.\n const envEx = await readFileSafe(join(projectDir, '.env.example'));\n if (envEx) sections.push({ label: '.env.example', path: '.env.example', body: envEx });\n else {\n const envSample = await readFileSafe(join(projectDir, '.env.sample'));\n if (envSample) sections.push({ label: '.env.sample', path: '.env.sample', body: envSample });\n }\n\n // Common framework config files at project root.\n let topEntries: string[];\n try {\n topEntries = await readdir(projectDir);\n } catch {\n topEntries = [];\n }\n for (const entry of topEntries) {\n if (CONFIG_FILE_PATTERNS.some((re) => re.test(entry))) {\n const body = await readFileSafe(join(projectDir, entry));\n if (body) sections.push({ label: entry, path: entry, body });\n }\n }\n\n return { projectDir, sections };\n}\n\nexport function renderSnapshot(snap: ProjectSnapshot): string {\n if (snap.sections.length === 0) {\n return `(empty or non-readable project at ${snap.projectDir})`;\n }\n const out: string[] = [];\n for (const s of snap.sections) {\n out.push(`### ${s.label} — ${s.path}`);\n out.push('```');\n out.push(s.body.trim());\n out.push('```');\n out.push('');\n }\n return out.join('\\n');\n}\n\nasync function readFileSafe(\n path: string,\n options: { byteCap?: number; lineCap?: number } = {},\n): Promise<string | null> {\n try {\n const s = await stat(path);\n if (!s.isFile()) return null;\n } catch {\n return null;\n }\n let text: string;\n try {\n text = await readFile(path, 'utf8');\n } catch {\n return null;\n }\n if (options.lineCap !== undefined) {\n const lines = text.split('\\n');\n if (lines.length > options.lineCap) {\n text = lines.slice(0, options.lineCap).join('\\n') + `\\n…[truncated at ${options.lineCap} lines]`;\n }\n }\n const byteCap = options.byteCap ?? FILE_CAP_BYTES;\n if (Buffer.byteLength(text, 'utf8') > byteCap) {\n text = text.slice(0, byteCap) + `\\n…[truncated at ${byteCap} bytes]`;\n }\n return text;\n}\n\n/** Convenience for callers that just want a relative path label. */\nexport function shortPath(projectDir: string, abs: string): string {\n return relative(projectDir, abs);\n}\n","import { spawn } from 'node:child_process';\nimport { probeUrl } from './targetProbe.js';\n\nexport interface SpawnResult {\n ok: boolean;\n pid?: number;\n command: string;\n args: string[];\n url: string;\n /** Reason set when ok=false. */\n reason?: string;\n}\n\nexport interface SpawnOptions {\n command: string;\n args: string[];\n url: string;\n cwd: string;\n /** How long to wait for the URL to respond (default 60s). */\n waitTimeoutMs?: number;\n /** Probe interval (default 750ms). */\n pollIntervalMs?: number;\n}\n\n/**\n * Spawn the proposed dev-server command detached + unref'd so it survives\n * after the wizard process exits. Then poll the proposed URL until it\n * responds or the wait timeout elapses.\n *\n * On success: returns the child's pid so the user can kill it later.\n * On timeout/error: returns ok=false with a reason; the child is left running\n * (we don't know enough to safely clean it up — that's the user's call).\n */\nexport async function spawnAndWait(opts: SpawnOptions): Promise<SpawnResult> {\n const waitTimeoutMs = opts.waitTimeoutMs ?? 60_000;\n const pollIntervalMs = opts.pollIntervalMs ?? 750;\n\n // On Windows, npm/pnpm shims need a shell — Linux/macOS doesn't.\n const useShell = process.platform === 'win32';\n\n let child;\n try {\n child = spawn(opts.command, opts.args, {\n cwd: opts.cwd,\n detached: true,\n stdio: 'ignore',\n shell: useShell,\n });\n child.unref();\n } catch (err) {\n return {\n ok: false,\n command: opts.command,\n args: opts.args,\n url: opts.url,\n reason: `failed to spawn: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const pid = child.pid;\n const start = Date.now();\n let lastReason = '';\n\n while (Date.now() - start < waitTimeoutMs) {\n // If the child has already exited, the probe is going to keep failing — bail.\n if (child.exitCode !== null) {\n return {\n ok: false,\n pid,\n command: opts.command,\n args: opts.args,\n url: opts.url,\n reason: `child process exited with code ${child.exitCode} before the URL came up`,\n };\n }\n const probe = await probeUrl(opts.url, pollIntervalMs);\n if (probe.reachable) {\n return {\n ok: true,\n pid,\n command: opts.command,\n args: opts.args,\n url: opts.url,\n };\n }\n lastReason = probe.reason ?? `HTTP ${probe.statusCode ?? '?'}`;\n await sleep(pollIntervalMs);\n }\n\n return {\n ok: false,\n pid,\n command: opts.command,\n args: opts.args,\n url: opts.url,\n reason: `timed out after ${waitTimeoutMs}ms waiting for ${opts.url} (last: ${lastReason}). Child still running as pid ${pid}.`,\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { spawn } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { logger } from '../util/logger.js';\n\ninterface InstallBrowserOpts {\n browser?: string;\n}\n\nconst DEFAULT_BROWSER = 'chromium';\n\nexport async function installBrowserCommand(opts: InstallBrowserOpts): Promise<void> {\n const browser = opts.browser ?? DEFAULT_BROWSER;\n const cli = await resolvePlaywrightCoreCli();\n\n logger.info(`installing Playwright ${browser} (via bundled playwright-core, no project required)`);\n // playwright-core's cli.js skips the \"install your project's dependencies first\" warning\n // that plain `npx playwright install` shows when invoked outside a project.\n const child = spawn(process.execPath, [cli, 'install', browser], {\n stdio: 'inherit',\n env: process.env,\n });\n const code: number = await new Promise((resolve, reject) => {\n child.on('error', reject);\n child.on('close', (c) => resolve(c ?? 0));\n });\n if (code !== 0) {\n logger.error(`playwright install exited with code ${code}`);\n process.exit(code);\n }\n logger.info(`${browser} installed. Try \\`showrunner doctor -c demo.yaml\\` next.`);\n}\n\nasync function resolvePlaywrightCoreCli(): Promise<string> {\n // Walk up from this module to the showrunner package root, then locate\n // playwright-core inside its node_modules. This works both when showrunner\n // is installed globally and when invoked via tsx during development.\n const here = fileURLToPath(import.meta.url);\n let dir = dirname(here);\n const root = dir.split(/[\\\\/]/)[0] + '/';\n while (dir && dir !== root) {\n const candidate = join(dir, 'node_modules', 'playwright-core', 'cli.js');\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next ancestor\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n 'Could not locate playwright-core CLI inside Showrunner\\'s node_modules. ' +\n 'This is a packaging bug — please file an issue.',\n );\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport yaml from 'js-yaml';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { probeUrl } from '../setup/targetProbe.js';\nimport { logger } from '../util/logger.js';\n\ninterface SetTargetOpts {\n config: string;\n url: string;\n force?: boolean;\n}\n\nexport async function setTargetCommand(opts: SetTargetOpts): Promise<void> {\n // Validate URL syntax before touching disk.\n try {\n new URL(opts.url);\n } catch {\n logger.error(`Invalid URL: ${opts.url}`);\n process.exit(2);\n }\n\n // Load the config (also validates the YAML is well-formed).\n try {\n await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n // Probe unless --force.\n if (!opts.force) {\n logger.info(`probing ${opts.url} ...`);\n const probe = await probeUrl(opts.url);\n if (!probe.reachable) {\n logger.error(\n `target ${opts.url} not reachable${\n probe.reason ? ` (${probe.reason})` : ''\n }. Start your dev server first, or pass --force to set the URL anyway.`,\n );\n process.exit(1);\n }\n logger.info(`reachable (HTTP ${probe.statusCode}, ${probe.elapsedMs}ms).`);\n }\n\n // Rewrite recording.target_url in place. We read the file fresh and modify\n // the parsed YAML rather than re-serialising loadConfig's normalised form,\n // so the user's comments and ordering survive (mostly — js-yaml drops\n // comments either way; this is best-effort).\n const absPath = isAbsolute(opts.config) ? opts.config : resolve(process.cwd(), opts.config);\n const rawText = await readFile(absPath, 'utf8');\n const doc = yaml.load(rawText) as Record<string, unknown>;\n\n if (!doc || typeof doc !== 'object' || !doc['recording'] || typeof doc['recording'] !== 'object') {\n logger.error(\n `config has no \\`recording\\` block — has it been edited by hand into an invalid shape?`,\n );\n process.exit(2);\n }\n (doc['recording'] as Record<string, unknown>)['target_url'] = opts.url;\n\n const newText = yaml.dump(doc, {\n lineWidth: 100,\n noRefs: true,\n sortKeys: false,\n });\n await writeFile(absPath, newText, 'utf8');\n\n logger.info(`updated recording.target_url → ${opts.url}`);\n logger.info(`(comments in demo.yaml may have been stripped — re-add them if needed.)`);\n}\n","import { stat } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { logger } from '../util/logger.js';\nimport type { ShowrunnerConfig } from '../config/schema.js';\nimport { formatMissingEnvVars, inspectProviderEnv } from '../config/providerEnv.js';\n\ninterface ValidateOpts {\n config: string;\n strict?: boolean;\n}\n\nexport async function validateCommand(opts: ValidateOpts): Promise<void> {\n // Load .env so api_key_env vars resolve the same way `run` would see them.\n try {\n process.loadEnvFile?.();\n } catch {\n // No .env present — fine.\n }\n\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const warnings: string[] = [];\n warnings.push(...(await checkReferencedPaths(loaded.config, loaded.configDir)));\n warnings.push(...formatMissingEnvVars(inspectProviderEnv(loaded.config)));\n\n if (warnings.length > 0) {\n for (const w of warnings) logger.warn(w);\n logger.info(\n `Config is structurally valid but ${warnings.length} issue(s) found.`,\n );\n if (opts.strict) {\n process.exit(1);\n }\n } else {\n logger.info('Config is valid.');\n }\n}\n\nasync function checkReferencedPaths(config: ShowrunnerConfig, configDir: string): Promise<string[]> {\n const warnings: string[] = [];\n const check = async (relPath: string | undefined, label: string): Promise<void> => {\n if (!relPath) return;\n const abs = isAbsolute(relPath) ? relPath : resolve(configDir, relPath);\n try {\n await stat(abs);\n } catch {\n warnings.push(`${label} not found: ${abs}`);\n }\n };\n\n await check(config.project.product_model, 'project.product_model');\n for (const s of config.comprehension.sources) {\n await check(s.path, `comprehension.sources[${s.type}].path`);\n }\n\n if (config.recording.auth?.type === 'session') {\n await check(config.recording.auth.cookies_file, 'recording.auth.cookies_file');\n if (config.recording.auth.local_storage_file) {\n await check(config.recording.auth.local_storage_file, 'recording.auth.local_storage_file');\n }\n }\n if (config.recording.auth?.type === 'setup_script') {\n await check(config.recording.auth.path, 'recording.auth.path');\n }\n\n await check(config.recording.state.seed_script, 'recording.state.seed_script');\n await check(config.recording.state.reset_script, 'recording.state.reset_script');\n await check(config.recording.state.teardown_script, 'recording.state.teardown_script');\n\n await check(config.output.branding.title_card?.font, 'output.branding.title_card.font');\n await check(config.output.branding.title_card?.logo, 'output.branding.title_card.logo');\n await check(config.output.background_music?.path, 'output.background_music.path');\n\n return warnings;\n}\n","import { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { renderVoScript } from '../manifest/voScript.js';\nimport { logger } from '../util/logger.js';\n\ninterface PrintVoOpts {\n config: string;\n}\n\nexport async function printVoCommand(opts: PrintVoOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const manifestPath = resolve(loaded.configDir, './scripts/manifest.json');\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const text = renderVoScript(manifest, { projectName: loaded.config.project.name });\n process.stdout.write(text);\n}\n","import { rm, stat } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport { readAndMergeVoScript, VoScriptMergeError } from '../manifest/voScript.js';\nimport { logger } from '../util/logger.js';\n\ninterface ApproveVoOpts {\n config: string;\n}\n\nexport async function approveVoCommand(opts: ApproveVoOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const manifestPath = resolve(loaded.configDir, './scripts/manifest.json');\n const voScriptPath = resolve(loaded.configDir, './scripts/vo_script.txt');\n const lockPath = resolve(loaded.configDir, '.showrunner-lock');\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n if (!(await pathExists(voScriptPath))) {\n logger.error(`VO script not found: ${voScriptPath}. Run \\`showrunner run\\` first.`);\n process.exit(1);\n }\n\n let merged;\n try {\n merged = await readAndMergeVoScript(voScriptPath, manifest);\n } catch (err) {\n if (err instanceof VoScriptMergeError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n await writeManifest(manifestPath, merged);\n if (await pathExists(lockPath)) {\n await rm(lockPath);\n }\n\n logger.info('VO edits merged into manifest. Resume with `showrunner run --config <path>`.');\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { chromium, firefox, webkit } from 'playwright-core';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readManifest, ManifestError } from '../manifest/io.js';\nimport { buildAuthPlan, AuthError } from '../recording/auth.js';\nimport { executeAction } from '../recording/actions.js';\nimport { ensureCursorInstalled, installCursorOverlay } from '../recording/cursorOverlay.js';\nimport {\n runLifecycleScript,\n LifecycleScriptError,\n} from '../recording/lifecycle.js';\nimport { generateRunId } from '../util/runId.js';\nimport { logger } from '../util/logger.js';\nimport type { Segment } from '../manifest/schema.js';\n\ninterface RerunOpts {\n config: string;\n segment: string;\n}\n\nconst RERUN_BUFFER_MS = 500;\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport async function rerunSegmentCommand(opts: RerunOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const { config, configDir } = loaded;\n const manifestPath = resolve(configDir, './scripts/manifest.json');\n const videoDir = resolve(configDir, config.recording.output_dir);\n\n let manifest;\n try {\n manifest = await readManifest(manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const segment: Segment | undefined = manifest.segments.find((s) => s.id === opts.segment);\n if (!segment) {\n logger.error(\n `Segment \"${opts.segment}\" not found in manifest. Known: ${manifest.segments.map((s) => s.id).join(', ')}`,\n );\n process.exit(1);\n }\n\n const runId = generateRunId();\n const baseEnv = { SHOWRUNNER_RUN_ID: runId, SHOWRUNNER_SEGMENT_ID: segment.id };\n\n if (config.recording.state.reset_script) {\n try {\n await runLifecycleScript({\n scriptPath: config.recording.state.reset_script,\n configDir,\n env: baseEnv,\n label: 'reset',\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n logger.error(`reset script failed: ${err.message}`);\n process.exit(1);\n }\n throw err;\n }\n }\n\n await mkdir(videoDir, { recursive: true });\n\n let authPlan;\n try {\n authPlan = await buildAuthPlan(config.recording.auth, configDir);\n } catch (err) {\n if (err instanceof AuthError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n const browser = await browserMap[config.recording.browser].launch({\n headless: config.recording.headless,\n });\n try {\n let storageState = authPlan.storageState;\n if (storageState === undefined && authPlan.postLaunch) {\n const authCtx = await browser.newContext({\n viewport: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n });\n try {\n const authPage = await authCtx.newPage();\n await authPage.goto(config.recording.target_url);\n await authPlan.postLaunch(authPage);\n storageState = await authCtx.storageState();\n } finally {\n await authCtx.close();\n }\n }\n\n const ctx = await browser.newContext({\n viewport: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n recordVideo: {\n dir: videoDir,\n size: { width: config.recording.viewport.width, height: config.recording.viewport.height },\n },\n storageState,\n });\n if (config.recording.cursor_highlight) {\n await installCursorOverlay(ctx);\n }\n await ctx.tracing.start({ screenshots: true, snapshots: true, sources: true });\n\n const page = await ctx.newPage();\n await page.goto(config.recording.target_url);\n if (config.recording.cursor_highlight) {\n await ensureCursorInstalled(page);\n }\n await page.waitForTimeout(RERUN_BUFFER_MS);\n\n await ctx.tracing.startChunk({ title: segment.id });\n let failure: string | undefined;\n const warnings: string[] = [];\n for (const action of segment.actions) {\n const outcome = await executeAction(page, action, {\n cursorEnabled: config.recording.cursor_highlight,\n });\n if (outcome.status === 'skipped') {\n warnings.push(`${action.type}: ${outcome.reason}`);\n logger.warn(`${action.type} skipped`, { reason: outcome.reason });\n } else if (outcome.status === 'segment_failed') {\n failure = outcome.reason;\n logger.error(`segment ${segment.id} failed`, { reason: outcome.reason });\n break;\n }\n }\n await page.waitForTimeout(config.recording.segment_buffer_ms);\n const traceDir = resolve(configDir, config.recording.trace_dir);\n await mkdir(traceDir, { recursive: true });\n await ctx.tracing.stopChunk({ path: join(traceDir, `${segment.id}.zip`) });\n\n const videoHandle = page.video();\n await ctx.close();\n\n if (!videoHandle) {\n logger.error('No video captured — recordVideo may have been ignored');\n process.exit(1);\n }\n const original = await videoHandle.path();\n const dest = join(videoDir, `${segment.id}.webm`);\n await rename(original, dest);\n\n const metadataPath = join(videoDir, `${segment.id}.rerun.json`);\n await writeFile(\n metadataPath,\n JSON.stringify(\n {\n segment_id: segment.id,\n run_id: runId,\n recorded_at: new Date().toISOString(),\n rerun_buffer_ms: RERUN_BUFFER_MS,\n status: failure ? 'failed' : 'ok',\n failure_reason: failure,\n warnings,\n },\n null,\n 2,\n ) + '\\n',\n 'utf8',\n );\n\n logger.info(`Segment ${segment.id} re-recorded → ${dest}`, { metadata: metadataPath });\n if (failure) {\n process.exit(1);\n }\n } finally {\n await browser.close();\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { launchHeadedSession } from '../recording/headed.js';\nimport { logger } from '../util/logger.js';\n\nexport interface CaptureAuthOpts {\n config: string;\n outputCookies?: string;\n outputStorage?: string;\n}\n\nexport async function captureAuthCommand(opts: CaptureAuthOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const cookiesRel = opts.outputCookies ?? './auth/session.json';\n const cookiesPath = isAbsolute(cookiesRel) ? cookiesRel : resolve(loaded.configDir, cookiesRel);\n await mkdir(dirname(cookiesPath), { recursive: true });\n\n logger.info('Launching headed browser for auth capture', {\n target: loaded.config.recording.target_url,\n output: cookiesPath,\n });\n\n const session = await launchHeadedSession({\n recording: loaded.config.recording,\n configDir: loaded.configDir,\n recordVideo: false,\n withCursor: false,\n applyAuth: false,\n });\n\n try {\n await session.page.goto(loaded.config.recording.target_url);\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n process.stdout.write(\n '\\nLog in to the target app in the browser window, then return here.\\n' +\n 'Press Enter to capture the session state (or Ctrl+C to abort): ',\n );\n await rl.question('');\n rl.close();\n\n await session.context.storageState({ path: cookiesPath });\n logger.info('Captured storage state', { path: cookiesPath });\n\n process.stdout.write(\n `\\nDone. To use this session, set the following in your demo.yaml:\\n\\n` +\n ` recording:\\n` +\n ` auth:\\n` +\n ` type: session\\n` +\n ` cookies_file: ${cookiesRel}\\n\\n` +\n `Then re-run \\`showrunner run --config <demo.yaml>\\`.\\n`,\n );\n } finally {\n await session.close();\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type BrowserContextOptions,\n type Page,\n} from 'playwright-core';\nimport type { RecordingConfig } from '../config/schema.js';\nimport { buildAuthPlan } from './auth.js';\nimport {\n ensureCursorInstalled,\n installCursorOverlay,\n verifyCursorMounted,\n} from './cursorOverlay.js';\nimport { logger } from '../util/logger.js';\n\nconst browserMap = { chromium, firefox, webkit } as const;\n\nexport interface HeadedSessionOptions {\n recording: RecordingConfig;\n configDir: string;\n /** When true, record video to recording.output_dir. Defaults to false. */\n recordVideo?: boolean;\n /** When true, install the showrunner cursor overlay. Defaults to false. */\n withCursor?: boolean;\n /**\n * When true, run any pre-configured `auth` plan before returning the page.\n * Defaults to false — most interactive commands (capture-auth, record-actions)\n * want a fresh, unauthenticated browser so the operator can drive it.\n */\n applyAuth?: boolean;\n}\n\nexport interface HeadedSession {\n browser: Browser;\n context: BrowserContext;\n page: Page;\n close(): Promise<void>;\n}\n\nexport async function launchHeadedSession(opts: HeadedSessionOptions): Promise<HeadedSession> {\n const { recording, configDir } = opts;\n const browser = await browserMap[recording.browser].launch({ headless: false });\n\n const contextOptions: BrowserContextOptions = {\n viewport: { width: recording.viewport.width, height: recording.viewport.height },\n };\n\n if (opts.recordVideo) {\n const videoDir = resolve(configDir, recording.output_dir);\n await mkdir(videoDir, { recursive: true });\n contextOptions.recordVideo = {\n dir: videoDir,\n size: { width: recording.viewport.width, height: recording.viewport.height },\n };\n }\n\n if (opts.applyAuth) {\n const authPlan = await buildAuthPlan(recording.auth, configDir);\n if (authPlan.storageState !== undefined) {\n contextOptions.storageState = authPlan.storageState;\n } else if (authPlan.postLaunch) {\n const authContext = 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 contextOptions.storageState = await authContext.storageState();\n } finally {\n await authContext.close();\n }\n }\n }\n\n const context = await browser.newContext(contextOptions);\n\n if (opts.withCursor) {\n await installCursorOverlay(context);\n }\n\n const page = await context.newPage();\n\n if (opts.withCursor) {\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\n return {\n browser,\n context,\n page,\n async close() {\n await context.close();\n await browser.close();\n },\n };\n}\n\nexport async function ensureCursorForHeaded(page: Page): Promise<void> {\n await ensureCursorInstalled(page);\n const mounted = await verifyCursorMounted(page);\n logger.debug(`cursor overlay mount check: ${mounted ? 'OK' : 'NOT FOUND'}`);\n}\n","import { readdir, stat } from 'node:fs/promises';\nimport { isAbsolute, join, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { readSlicePlan } from '../mux/slice.js';\nimport { runCommand, LifecycleScriptError } from '../recording/lifecycle.js';\nimport { logger } from '../util/logger.js';\n\nexport interface TraceOpts {\n config: string;\n segment?: string;\n all?: boolean;\n}\n\nexport async function traceCommand(opts: TraceOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const traceDir = resolve(loaded.configDir, loaded.config.recording.trace_dir);\n const videoDir = resolve(loaded.configDir, loaded.config.recording.output_dir);\n const slicePlanPath = join(videoDir, 'slice_plan.json');\n\n if (opts.all) {\n let plan;\n try {\n plan = await readSlicePlan(slicePlanPath);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n logger.error(`Could not read slice_plan.json at ${slicePlanPath}: ${cause}`);\n process.exit(1);\n }\n for (const seg of plan.segments) {\n const tracePath = seg.trace_path && isAbsolute(seg.trace_path)\n ? seg.trace_path\n : seg.trace_path\n ? resolve(loaded.configDir, seg.trace_path)\n : join(traceDir, `${seg.id}.zip`);\n logger.info(`Opening trace for ${seg.id}`, { path: tracePath });\n await openTrace(tracePath);\n }\n return;\n }\n\n if (opts.segment) {\n const tracePath = join(traceDir, `${opts.segment}.zip`);\n if (!(await fileExists(tracePath))) {\n logger.error(`No trace found at ${tracePath}`);\n process.exit(1);\n }\n await openTrace(tracePath);\n return;\n }\n\n const available = await listTraces(traceDir);\n if (available.length === 0) {\n logger.error(`No .zip traces in ${traceDir}. Run \\`showrunner run\\` first.`);\n process.exit(1);\n }\n process.stdout.write(`Available traces in ${traceDir}:\\n`);\n for (const name of available) process.stdout.write(` ${name}\\n`);\n process.stdout.write(\n `\\nRe-run with --segment <id> to open one, or --all to open every trace.\\n`,\n );\n}\n\nasync function openTrace(tracePath: string): Promise<void> {\n try {\n await runCommand({\n cmd: 'npx',\n args: ['playwright', 'show-trace', tracePath],\n label: 'trace',\n inherit: true,\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n // exit code from show-trace can be non-zero on window close; not fatal\n logger.debug(`trace viewer exited`, { code: err.exitCode });\n } else {\n throw err;\n }\n }\n}\n\nasync function listTraces(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir);\n return entries.filter((e) => e.endsWith('.zip')).sort();\n } catch {\n return [];\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 } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { runCommand, LifecycleScriptError } from '../recording/lifecycle.js';\nimport { logger } from '../util/logger.js';\n\nexport interface PreviewOpts {\n config: string;\n}\n\nexport async function previewCommand(opts: PreviewOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const previewSpec = resolve(loaded.configDir, './scripts/playwright_demo.spec.ts');\n if (!(await fileExists(previewSpec))) {\n logger.error(\n `No preview spec at ${previewSpec}. Run \\`showrunner run --stages script\\` first to generate it.`,\n );\n process.exit(1);\n }\n\n logger.info('Opening Playwright UI Mode for preview', { spec: previewSpec });\n\n try {\n await runCommand({\n cmd: 'npx',\n args: ['playwright', 'test', '--ui', previewSpec],\n cwd: loaded.configDir,\n label: 'preview',\n inherit: true,\n });\n } catch (err) {\n if (err instanceof LifecycleScriptError) {\n logger.debug(`preview UI exited`, { code: err.exitCode });\n } else {\n throw err;\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, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport {\n generateProductModelFromDocs,\n generateProductModelFromInteractive,\n ProductModelGenerationError,\n} from '../productModel/generate.js';\nimport { runInteractiveQA } from '../productModel/interactive.js';\nimport type { DocSource } from '../productModel/prompts.js';\nimport { resolveDefaultLLMProvider } from '../providers/llm/resolveFromContext.js';\nimport { logger } from '../util/logger.js';\n\nexport interface UnderstandOpts {\n config?: string;\n interactive?: boolean;\n output?: string;\n}\n\nexport async function understandCommand(opts: UnderstandOpts): Promise<void> {\n let configDir = process.cwd();\n let outputRel = opts.output ?? './product_model.json';\n let sources: { path: string; type: string }[] = [];\n let llmConfig: import('../config/schema.js').LLMConfig | undefined;\n\n if (opts.config) {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n configDir = loaded.configDir;\n // Precedence: explicit --output > config.project.product_model > default.\n if (!opts.output && loaded.config.project.product_model) {\n outputRel = loaded.config.project.product_model;\n }\n sources = loaded.config.comprehension.sources.map((s) => ({ path: s.path, type: s.type }));\n llmConfig = loaded.config.llm;\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n }\n\n const outputPath = isAbsolute(outputRel) ? outputRel : resolve(configDir, outputRel);\n await mkdir(dirname(outputPath), { recursive: true });\n\n let productModel;\n const provider = resolveDefaultLLMProvider({ configDir, llm: llmConfig });\n try {\n if (opts.interactive) {\n const answers = await runInteractiveQA();\n logger.info('Generating product_model from interactive answers');\n productModel = await generateProductModelFromInteractive({ answers, provider });\n } else {\n if (sources.length === 0) {\n logger.error(\n 'No `comprehension.sources` configured in demo.yaml. Add at least one source ' +\n '(prd, readme, codebase, etc.) or re-run with --interactive.',\n );\n process.exit(2);\n }\n const docs: DocSource[] = [];\n for (const src of sources) {\n const abs = isAbsolute(src.path) ? src.path : resolve(configDir, src.path);\n try {\n const content = await readFile(abs, 'utf8');\n docs.push({ path: src.path, type: src.type, content });\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n logger.warn(`Skipping source ${abs}: ${cause}`);\n }\n }\n if (docs.length === 0) {\n logger.error('No comprehension sources could be read.');\n process.exit(2);\n }\n logger.info('Generating product_model from documents', {\n sources: docs.map((d) => d.path),\n });\n productModel = await generateProductModelFromDocs({ sources: docs, provider });\n }\n } catch (err) {\n if (err instanceof ProductModelGenerationError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n await writeFile(outputPath, JSON.stringify(productModel, null, 2) + '\\n', 'utf8');\n logger.info('Wrote product_model.json', { path: outputPath });\n}\n","export const PRODUCT_MODEL_SYSTEM_PROMPT = `You build product_model.json for Showrunner, an automated product demo recorder.\n\nA product model is a tight, structured description of a web app: what it is, who uses it, and the 2–4 most important flows worth demoing. Showrunner later uses this to write a 60–90 second demo script.\n\nRules:\n- product_name: short, exact product name as branded.\n- tagline: one sentence, 8–15 words, plain language.\n- primary_user: one short phrase describing who the product is for.\n- core_flows: 2–4 flows. Each flow has an id (kebab-case), a name, a steps array (3–6 imperative steps from the user's POV), and an optional entry_url.\n- key_features: 3–6 short bullets, no marketing fluff.\n- demo_recommendation.suggested_flows: ids drawn from core_flows, in the order they should appear in the demo.\n- demo_recommendation.suggested_duration_seconds: realistic total runtime including intro and outro. Typical: 60–90.\n- confidence: 'high' if the source materials clearly describe the product; 'medium' if you had to infer; 'low' if you mostly guessed.\n- source: 'documents' when synthesized from supplied text; 'interactive' when from Q&A answers.\n- generated_at: ISO-8601 timestamp.\n\nOutput exactly the structured JSON requested. No prose, no commentary.`;\n\nexport interface DocSource {\n path: string;\n type: string;\n content: string;\n}\n\nexport function renderProductModelDocPrompt(sources: DocSource[]): string {\n const blocks = sources\n .map((s) => {\n const trimmed = s.content.length > 12000 ? s.content.slice(0, 12000) + '\\n…[truncated]' : s.content;\n return `=== ${s.type.toUpperCase()} ${s.path} ===\\n${trimmed}\\n=== END ${s.path} ===`;\n })\n .join('\\n\\n');\n\n return `You have the following source documents describing a product. Synthesize them into a product_model.json. Set source to 'documents'.\\n\\n${blocks}`;\n}\n\nexport interface InteractiveAnswers {\n productName: string;\n primaryUser: string;\n tagline: string;\n topFeatures: string[];\n topFlows: { name: string; steps: string[] }[];\n suggestedDurationSeconds: number;\n}\n\nexport function renderProductModelInteractivePrompt(a: InteractiveAnswers): string {\n return `An operator answered the following questions about their product. Build a product_model.json from their answers. Set source to 'interactive'. If an answer is sparse, make reasonable inferences but keep confidence honest ('medium' or 'low').\n\nproduct_name: ${a.productName}\nprimary_user: ${a.primaryUser}\ntagline: ${a.tagline}\ntop_features:\n${a.topFeatures.map((f) => ` - ${f}`).join('\\n')}\ntop_flows:\n${a.topFlows\n .map(\n (f, i) => ` ${i + 1}. ${f.name}\\n steps:\\n${f.steps.map((s) => ` - ${s}`).join('\\n')}`,\n )\n .join('\\n')}\nsuggested_duration_seconds: ${a.suggestedDurationSeconds}`;\n}\n","import { productModelSchema, type ProductModel } from './schema.js';\nimport { logger } from '../util/logger.js';\nimport {\n PRODUCT_MODEL_SYSTEM_PROMPT,\n renderProductModelDocPrompt,\n renderProductModelInteractivePrompt,\n type DocSource,\n type InteractiveAnswers,\n} from './prompts.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\nimport { generateWithRetry } from '../providers/llm/withRetry.js';\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nexport class ProductModelGenerationError extends Error {\n override readonly name = 'ProductModelGenerationError';\n}\n\nexport interface GenerateFromDocsOptions {\n sources: DocSource[];\n provider: LLMProvider;\n}\n\nexport interface GenerateFromInteractiveOptions {\n answers: InteractiveAnswers;\n provider: LLMProvider;\n}\n\nexport async function generateProductModelFromDocs(\n opts: GenerateFromDocsOptions,\n): Promise<ProductModel> {\n if (opts.sources.length === 0) {\n throw new ProductModelGenerationError(\n 'No source documents provided. Add entries under `comprehension.sources` in demo.yaml.',\n );\n }\n const userPrompt = renderProductModelDocPrompt(opts.sources);\n return callProvider(opts.provider, userPrompt, 'documents');\n}\n\nexport async function generateProductModelFromInteractive(\n opts: GenerateFromInteractiveOptions,\n): Promise<ProductModel> {\n const userPrompt = renderProductModelInteractivePrompt(opts.answers);\n return callProvider(opts.provider, userPrompt, 'interactive');\n}\n\nasync function callProvider(\n provider: LLMProvider,\n userPrompt: string,\n sourceTag: 'documents' | 'interactive',\n): Promise<ProductModel> {\n logger.debug('Generating product_model via LLM provider', { source: sourceTag });\n try {\n return await generateWithRetry(provider, {\n systemPrompt: PRODUCT_MODEL_SYSTEM_PROMPT,\n userPrompt,\n schema: productModelSchema,\n schemaName: 'product_model',\n maxTokens: DEFAULT_MAX_TOKENS,\n retryRenderer: (errorText, prevUserPrompt) =>\n `${prevUserPrompt}\\n\\nYour previous output failed validation with this error:\\n${errorText}\\n\\nRegenerate the product_model strictly matching the schema.`,\n });\n } catch (err) {\n throw new ProductModelGenerationError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { createInterface, type Interface as ReadlineInterface } from 'node:readline';\nimport type { InteractiveAnswers } from './prompts.js';\n\n/**\n * Buffered line reader on top of readline.Interface. Two reasons to queue\n * rather than use `rl.question()` / `rl.once('line')` directly:\n *\n * 1. `readline/promises` `rl.question()` has a documented edge case where\n * the second-or-third call silently exits when stdin is piped (non-TTY).\n * 2. With piped stdin, all lines arrive in a burst; if we only register a\n * one-shot 'line' listener per ask(), every line after the first fires\n * with no listener and is lost. Queueing preserves them for later asks.\n */\nclass LineReader {\n private queue: string[] = [];\n private waiter: ((line: string) => void) | null = null;\n private rejecter: ((err: Error) => void) | null = null;\n private closed = false;\n\n constructor(rl: ReadlineInterface) {\n rl.on('line', (line: string) => {\n if (this.waiter) {\n const cb = this.waiter;\n this.waiter = null;\n this.rejecter = null;\n cb(line);\n } else {\n this.queue.push(line);\n }\n });\n rl.on('close', () => {\n this.closed = true;\n if (this.rejecter) {\n const rej = this.rejecter;\n this.waiter = null;\n this.rejecter = null;\n rej(new Error('stdin closed before answer was provided'));\n }\n });\n }\n\n read(): Promise<string> {\n if (this.queue.length > 0) {\n return Promise.resolve(this.queue.shift()!);\n }\n if (this.closed) {\n return Promise.reject(new Error('stdin closed before answer was provided'));\n }\n return new Promise<string>((resolve, reject) => {\n this.waiter = resolve;\n this.rejecter = reject;\n });\n }\n}\n\nasync function ask(reader: LineReader, prompt: string): Promise<string> {\n process.stdout.write(prompt);\n return reader.read();\n}\n\nexport async function runInteractiveQA(): Promise<InteractiveAnswers> {\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false });\n const reader = new LineReader(rl);\n\n try {\n process.stdout.write(\n '\\nLet\\'s build a product_model interactively. Answer each prompt with a short line.\\n\\n',\n );\n const productName = (await ask(reader, '1. Product name: ')).trim();\n if (!productName) throw new Error('product name is required');\n\n const tagline = (await ask(reader, '2. One-sentence tagline: ')).trim();\n const primaryUser = (await ask(reader, '3. Who is the primary user? ')).trim();\n\n const featuresLine = (\n await ask(reader, '4. Top 3-6 features, comma-separated:\\n ')\n ).trim();\n const topFeatures = featuresLine\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const flowCountStr = (\n await ask(reader, '5. How many flows would you like to demo (2-4)? ')\n ).trim();\n const flowCount = clamp(parseInt(flowCountStr, 10) || 2, 2, 4);\n const topFlows: { name: string; steps: string[] }[] = [];\n for (let i = 0; i < flowCount; i++) {\n const name = (await ask(reader, ` Flow ${i + 1} name: `)).trim();\n const stepsLine = (\n await ask(reader, ` Flow ${i + 1} steps, '|' separated:\\n `)\n ).trim();\n const steps = stepsLine\n .split('|')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n topFlows.push({ name, steps });\n }\n\n const durationStr = (\n await ask(reader, '6. Target demo duration in seconds (60-120, default 75): ')\n ).trim();\n const suggestedDurationSeconds = clamp(parseInt(durationStr, 10) || 75, 30, 180);\n\n return {\n productName,\n primaryUser,\n tagline,\n topFeatures,\n topFlows,\n suggestedDurationSeconds,\n };\n } finally {\n rl.close();\n }\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n));\n}\n","import { mkdir, readdir, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, resolve, relative } from 'node:path';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { scanFile, type InstrumentCandidate } from '../instrument/scan.js';\nimport { suggestTestIds, InstrumentSuggestionError } from '../instrument/suggest.js';\nimport { buildDiff } from '../instrument/diff.js';\nimport { resolveDefaultLLMProvider } from '../providers/llm/resolveFromContext.js';\nimport { logger } from '../util/logger.js';\n\nexport interface InstrumentOpts {\n config: string;\n output: string;\n glob?: string;\n}\n\nexport async function instrumentCommand(opts: InstrumentOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const codebaseSources = loaded.config.comprehension.sources.filter((s) => s.type === 'codebase');\n if (codebaseSources.length === 0 && !opts.glob) {\n logger.error(\n 'No `comprehension.sources` with type=codebase found in demo.yaml, and no --glob provided.',\n );\n process.exit(2);\n }\n\n const filesToScan = new Set<string>();\n const IGNORED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'out']);\n\n async function walk(root: string, accept: (rel: string) => boolean): Promise<void> {\n const entries = await readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const abs = join(root, entry.name);\n if (entry.isDirectory()) {\n if (IGNORED_DIRS.has(entry.name)) continue;\n await walk(abs, accept);\n } else if (entry.isFile() && accept(relative(root, abs))) {\n filesToScan.add(abs);\n }\n }\n }\n\n const isJsxFile = (p: string): boolean => /\\.(tsx|jsx)$/.test(p);\n\n if (opts.glob) {\n // Lightweight glob: treat the pattern as \"match if path contains the pattern\n // stripped of leading **/ or trailing /**\", with extension filter via isJsxFile.\n // For accurate glob matching, users can be explicit with file extensions.\n const root = loaded.configDir;\n await walk(root, isJsxFile);\n } else {\n for (const src of codebaseSources) {\n const root = isAbsolute(src.path) ? src.path : resolve(loaded.configDir, src.path);\n await walk(root, isJsxFile);\n }\n }\n\n if (filesToScan.size === 0) {\n logger.error('No JSX/TSX files matched. Check comprehension.sources or --glob.');\n process.exit(2);\n }\n\n logger.info('Scanning files for instrumentation candidates', { files: filesToScan.size });\n\n const candidates: InstrumentCandidate[] = [];\n for (const file of filesToScan) {\n const found = await scanFile(file);\n candidates.push(...found);\n }\n\n if (candidates.length === 0) {\n logger.info('No unstable elements found — every targetable element already has data-testid or aria-label.');\n process.exit(0);\n }\n logger.info('Found instrumentation candidates', { count: candidates.length });\n\n let suggestions;\n try {\n const provider = resolveDefaultLLMProvider({\n configDir: loaded.configDir,\n llm: loaded.config.llm,\n });\n suggestions = await suggestTestIds({ candidates, provider });\n } catch (err) {\n if (err instanceof InstrumentSuggestionError) {\n logger.error(err.message);\n process.exit(1);\n }\n throw err;\n }\n\n if (suggestions.length === 0) {\n logger.info('Anthropic returned no suggestions.');\n process.exit(0);\n }\n\n const { patch, skipped } = await buildDiff(suggestions, { basePath: loaded.configDir });\n for (const s of skipped) {\n logger.warn(`Skipped suggestion at ${s.file}:${s.line} — ${s.reason}`);\n }\n\n const outputPath = isAbsolute(opts.output) ? opts.output : resolve(loaded.configDir, opts.output);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, patch, 'utf8');\n logger.info('Wrote instrumentation patch', { path: outputPath, suggestions: suggestions.length });\n process.stdout.write(`\\nApply with: cd ${loaded.configDir} && git apply ${opts.output}\\n\\n`);\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse } from '@babel/parser';\nimport _traverse from '@babel/traverse';\nimport type { NodePath } from '@babel/traverse';\nimport type {\n JSXAttribute,\n JSXOpeningElement,\n JSXIdentifier,\n} from '@babel/types';\n\n// @babel/traverse ships CJS default in an ESM-incompatible way; unwrap it.\nconst traverse = (_traverse as unknown as { default: typeof _traverse }).default ?? _traverse;\n\nconst TARGET_TAGS = new Set([\n 'button',\n 'a',\n 'input',\n 'textarea',\n 'select',\n 'form',\n 'Button',\n 'Link',\n 'Input',\n 'TextField',\n 'Form',\n]);\n\nexport interface InstrumentCandidate {\n file: string;\n line: number;\n column: number;\n tag: string;\n snippet: string;\n hasRole: boolean;\n hasTestId: boolean;\n hasAriaLabel: boolean;\n}\n\nexport async function scanFile(filePath: string): Promise<InstrumentCandidate[]> {\n const source = await readFile(filePath, 'utf8');\n let ast;\n try {\n ast = parse(source, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n errorRecovery: true,\n });\n } catch {\n return [];\n }\n\n const lines = source.split(/\\r?\\n/);\n const candidates: InstrumentCandidate[] = [];\n\n traverse(ast, {\n JSXOpeningElement(path: NodePath<JSXOpeningElement>) {\n const tag = jsxTagName(path.node);\n if (!tag) return;\n const hasRole = pickAttr(path.node, 'role') !== null;\n const hasTestId =\n pickAttr(path.node, 'data-testid') !== null || pickAttr(path.node, 'data-test-id') !== null;\n const hasAriaLabel = pickAttr(path.node, 'aria-label') !== null;\n\n const isTargetTag = TARGET_TAGS.has(tag);\n const isTargetByRole = hasRole;\n if (!isTargetTag && !isTargetByRole) return;\n\n if (hasTestId || hasAriaLabel) return; // already labeled\n\n const loc = path.node.loc;\n if (!loc) return;\n const lineIdx = loc.start.line - 1;\n const snippet = lines[lineIdx] ?? '';\n\n candidates.push({\n file: filePath,\n line: loc.start.line,\n column: loc.start.column,\n tag,\n snippet,\n hasRole,\n hasTestId,\n hasAriaLabel,\n });\n },\n });\n\n return candidates;\n}\n\nfunction jsxTagName(node: JSXOpeningElement): string | null {\n const name = node.name;\n if (name.type === 'JSXIdentifier') {\n return (name as JSXIdentifier).name;\n }\n return null;\n}\n\nfunction pickAttr(node: JSXOpeningElement, attr: string): JSXAttribute | null {\n for (const a of node.attributes) {\n if (a.type !== 'JSXAttribute') continue;\n if (a.name.type !== 'JSXIdentifier') continue;\n if (a.name.name === attr) return a;\n }\n return null;\n}\n","import { z } from 'zod';\nimport type { InstrumentCandidate } from './scan.js';\nimport { logger } from '../util/logger.js';\nimport type { LLMProvider } from '../providers/llm/types.js';\n\nconst DEFAULT_MAX_TOKENS = 8000;\n\nconst suggestionSchema = z.object({\n suggestions: z.array(\n z.object({\n file: z.string(),\n line: z.number().int().positive(),\n original: z.string(),\n replacement: z.string(),\n reasoning: z.string().default(''),\n }),\n ),\n});\n\nexport type Suggestion = z.infer<typeof suggestionSchema>['suggestions'][number];\n\nexport class InstrumentSuggestionError extends Error {\n override readonly name = 'InstrumentSuggestionError';\n}\n\nexport interface SuggestOptions {\n candidates: InstrumentCandidate[];\n provider: LLMProvider;\n}\n\nconst SYSTEM_PROMPT = `You add data-testid attributes to JSX elements so they can be reliably targeted by automated demo tools.\n\nRules:\n- For each candidate, propose a stable kebab-case data-testid based on visible text, surrounding context, or the element's role. Examples: \"login-submit\", \"new-article-button\", \"todo-item-toggle\".\n- Prefer short, semantic ids over verbose ones.\n- Output a single-line replacement: take the original line and insert data-testid=\"...\" just before the closing > of the opening tag. Preserve all existing whitespace and other attributes.\n- Skip elements where you can't infer a meaningful name (e.g. truly generic wrappers). In that case omit them from the output rather than guessing.\n- Never duplicate an existing data-testid on the page; if two candidates would collide, suffix the second with an index (\"-2\").\n- Reasoning: one short line explaining the chosen name.\n\nReturn JSON matching the requested schema.`;\n\nexport async function suggestTestIds(opts: SuggestOptions): Promise<Suggestion[]> {\n if (opts.candidates.length === 0) return [];\n\n const candidateBlock = opts.candidates\n .map(\n (c, i) =>\n `[${i + 1}] file=${c.file} line=${c.line} tag=${c.tag}\\n ${c.snippet.trim()}`,\n )\n .join('\\n');\n\n const userPrompt = `Suggest data-testid attributes for the following JSX elements:\\n\\n${candidateBlock}\\n\\nFor each, return {file, line, original (exact source line), replacement (source line with data-testid inserted), reasoning}.`;\n\n logger.debug('Calling LLM provider for instrument suggestions', {\n candidates: opts.candidates.length,\n });\n\n try {\n const result = await opts.provider.generateStructured({\n systemPrompt: SYSTEM_PROMPT,\n userPrompt,\n schema: suggestionSchema,\n schemaName: 'instrument_suggestions',\n maxTokens: DEFAULT_MAX_TOKENS,\n });\n return result.suggestions;\n } catch (err) {\n throw new InstrumentSuggestionError(\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative } from 'node:path';\nimport type { Suggestion } from './suggest.js';\n\nexport interface DiffOptions {\n /** When set, paths in the diff are written relative to this dir. */\n basePath?: string;\n}\n\n/**\n * Build a unified diff from per-file single-line replacements. Each suggestion\n * is treated independently; lines that don't match the suggestion's `original`\n * exactly are skipped with a warning header but don't block the rest.\n */\nexport async function buildDiff(\n suggestions: Suggestion[],\n opts: DiffOptions = {},\n): Promise<{ patch: string; skipped: { file: string; line: number; reason: string }[] }> {\n const byFile = new Map<string, Suggestion[]>();\n for (const s of suggestions) {\n const arr = byFile.get(s.file) ?? [];\n arr.push(s);\n byFile.set(s.file, arr);\n }\n\n const skipped: { file: string; line: number; reason: string }[] = [];\n const fileDiffs: string[] = [];\n\n for (const [file, perFile] of byFile) {\n let source: string;\n try {\n source = await readFile(file, 'utf8');\n } catch (err) {\n for (const s of perFile) {\n skipped.push({\n file,\n line: s.line,\n reason: `read failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n continue;\n }\n const lines = source.split('\\n');\n const sorted = [...perFile].sort((a, b) => a.line - b.line);\n\n const hunks: string[] = [];\n for (const s of sorted) {\n const idx = s.line - 1;\n const actual = lines[idx];\n if (actual === undefined) {\n skipped.push({ file, line: s.line, reason: 'line out of range' });\n continue;\n }\n if (actual.trim() !== s.original.trim()) {\n skipped.push({\n file,\n line: s.line,\n reason: `source line drifted from suggestion (expected \"${s.original.trim()}\", saw \"${actual.trim()}\")`,\n });\n continue;\n }\n hunks.push(\n `@@ -${s.line},1 +${s.line},1 @@\\n-${actual}\\n+${s.replacement}`,\n );\n }\n\n if (hunks.length === 0) continue;\n const displayPath = opts.basePath ? relative(opts.basePath, file).replace(/\\\\/g, '/') : file;\n fileDiffs.push(`--- a/${displayPath}\\n+++ b/${displayPath}\\n${hunks.join('\\n')}`);\n }\n\n return { patch: fileDiffs.join('\\n') + (fileDiffs.length > 0 ? '\\n' : ''), skipped };\n}\n","import { createInterface } from 'node:readline/promises';\nimport { resolve } from 'node:path';\nimport { stat } from 'node:fs/promises';\nimport { loadConfig, ConfigError } from '../config/loader.js';\nimport { launchHeadedSession } from '../recording/headed.js';\nimport {\n attachNavigationCapture,\n coalesceEvents,\n installCaptureBinding,\n type RecordedEvent,\n} from '../recording/captureEvents.js';\nimport { readManifest, writeManifest, ManifestError } from '../manifest/io.js';\nimport type { Action, Manifest } from '../manifest/schema.js';\nimport { logger } from '../util/logger.js';\n\nexport interface RecordActionsOpts {\n config: string;\n segment?: string;\n output?: string;\n}\n\nexport async function recordActionsCommand(opts: RecordActionsOpts): Promise<void> {\n let loaded;\n try {\n loaded = await loadConfig(opts.config);\n } catch (err) {\n if (err instanceof ConfigError) {\n logger.error(err.message);\n process.exit(2);\n }\n throw err;\n }\n\n const envFile = resolve(loaded.configDir, '.env');\n try {\n process.loadEnvFile(envFile);\n } catch {\n // optional\n }\n\n const manifestPath = opts.output\n ? resolve(loaded.configDir, opts.output)\n : resolve(loaded.configDir, './scripts/manifest.json');\n\n logger.info('Launching headed browser for action capture', {\n target: loaded.config.recording.target_url,\n });\n\n const events: RecordedEvent[] = [];\n const interleavedNavigations: Action[] = [];\n const sessionEnd = new AbortController();\n\n const session = await launchHeadedSession({\n recording: loaded.config.recording,\n configDir: loaded.configDir,\n recordVideo: false,\n withCursor: false,\n applyAuth: true,\n });\n\n try {\n await installCaptureBinding(session.context, (evt) => events.push(evt));\n attachNavigationCapture(session.page, (action) => interleavedNavigations.push(action));\n\n await session.page.goto(loaded.config.recording.target_url);\n\n process.stdout.write(\n '\\nDrive the demo in the browser window. Click, type, navigate.\\n' +\n 'When you\\'re done, return here and press Enter to write the manifest (or Ctrl+C to abort).\\n',\n );\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const closed = new Promise<void>((resolveClose) => {\n sessionEnd.signal.addEventListener('abort', () => resolveClose());\n });\n const userPrompt = rl.question('Press Enter to save: ');\n await Promise.race([userPrompt, closed]);\n rl.close();\n } finally {\n await session.close();\n }\n\n const coalesced = coalesceEvents(events);\n const actions = mergeWithNavigations(coalesced, interleavedNavigations);\n logger.info('Coalesced action stream', {\n raw_events: events.length,\n navigations: interleavedNavigations.length,\n actions: actions.length,\n });\n\n if (actions.length === 0) {\n logger.warn('No actions captured — manifest not modified.');\n return;\n }\n\n const updatedManifest = await mergeIntoManifest({\n manifestPath,\n segmentId: opts.segment,\n actions,\n projectName: loaded.config.project.name,\n });\n\n await writeManifest(manifestPath, updatedManifest);\n logger.info('Wrote manifest', { path: manifestPath, segments: updatedManifest.segments.length });\n}\n\n/**\n * Insert navigation events into the action stream by timestamp. Navigations\n * arrive on their own channel from Playwright; the click/input events come from\n * the in-page binding. Cheap interleave: append navigations to the end. (For\n * v1 this is fine — the typical pattern is \"fill form → submit → navigate\".)\n */\nfunction mergeWithNavigations(coalesced: Action[], navigations: Action[]): Action[] {\n return [...coalesced, ...navigations];\n}\n\ninterface MergeOptions {\n manifestPath: string;\n segmentId?: string;\n actions: Action[];\n projectName: string;\n}\n\nasync function mergeIntoManifest(opts: MergeOptions): Promise<Manifest> {\n const exists = await fileExists(opts.manifestPath);\n if (!exists) {\n // Build a one-segment skeleton.\n const segmentId = opts.segmentId ?? 'recorded';\n const duration = Math.max(8, opts.actions.length * 2);\n return {\n total_duration_seconds: duration,\n generated_from: 'record-actions',\n segments: [\n {\n id: segmentId,\n label: 'Recorded',\n start: 0,\n end: duration,\n vo_line: `Recorded walkthrough of ${opts.projectName}.`,\n actions: opts.actions,\n transition: 'cut',\n },\n ],\n };\n }\n\n let existing;\n try {\n existing = await readManifest(opts.manifestPath);\n } catch (err) {\n if (err instanceof ManifestError) {\n throw new Error(`record-actions: existing manifest invalid — ${err.message}`);\n }\n throw err;\n }\n\n if (!opts.segmentId) {\n // Append a new \"recorded\" segment at the end.\n const lastEnd = existing.segments[existing.segments.length - 1]!.end;\n const newStart = lastEnd;\n const newEnd = newStart + Math.max(8, opts.actions.length * 2);\n existing.segments.push({\n id: `recorded-${existing.segments.length}`,\n label: 'Recorded',\n start: newStart,\n end: newEnd,\n vo_line: 'Recorded walkthrough.',\n actions: opts.actions,\n transition: 'cut',\n });\n existing.total_duration_seconds = newEnd;\n return existing;\n }\n\n const target = existing.segments.find((s) => s.id === opts.segmentId);\n if (!target) {\n throw new Error(\n `record-actions: segment \"${opts.segmentId}\" not found in ${opts.manifestPath}. ` +\n `Available: ${existing.segments.map((s) => s.id).join(', ')}`,\n );\n }\n target.actions = opts.actions;\n return existing;\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 type { BrowserContext, Page } from 'playwright-core';\nimport type { Action } from '../manifest/schema.js';\nimport { logger } from '../util/logger.js';\nimport { SELECTOR_FOR_FN_SOURCE } from './selectorHeuristic.js';\n\nexport interface RecordedEvent {\n kind: 'click' | 'input' | 'keydown' | 'submit' | 'change' | 'scroll';\n selector: string;\n /** For input/change: the field's current value. For keydown: the key. For scroll: 'up'|'down'. */\n payload?: string;\n /** Wall-clock timestamp captured in the page. */\n ts: number;\n /** True if the field is a contenteditable (treat differently from inputs). */\n contenteditable?: boolean;\n /** For scroll events: accumulated deltaY since the last emit. */\n deltaY?: number;\n}\n\n/**\n * Install a small in-page script that listens for user interactions and posts\n * each one back to Node via the `__srRecordEvent` binding. Selector preference:\n * 1. [data-testid=\"X\"]\n * 2. [name=\"X\"] (form fields)\n * 3. [placeholder=\"X\"]\n * 4. [aria-label=\"X\"]\n * 5. #id (if id is stable-looking)\n * 6. text=<visible text> for buttons/links\n * 7. minimal CSS path\n */\nexport async function installCaptureBinding(\n context: BrowserContext,\n onEvent: (evt: RecordedEvent) => void,\n): Promise<void> {\n await context.exposeBinding('__srRecordEvent', (_source, evt: unknown) => {\n if (!isRecordedEvent(evt)) return;\n onEvent(evt);\n });\n\n await context.addInitScript(IN_PAGE_SCRIPT);\n}\n\nfunction isRecordedEvent(value: unknown): value is RecordedEvent {\n if (!value || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.kind === 'string' &&\n typeof v.selector === 'string' &&\n typeof v.ts === 'number'\n );\n}\n\nconst IN_PAGE_SCRIPT = `\n(() => {\n if (window.__srRecordingInstalled) return;\n window.__srRecordingInstalled = true;\n\n ${SELECTOR_FOR_FN_SOURCE}\n\n function send(kind, el, payload, extra) {\n const sel = selectorFor(el);\n if (!sel) return;\n const evt = Object.assign({\n kind: kind,\n selector: sel,\n payload: payload,\n ts: Date.now(),\n contenteditable: el && el.isContentEditable === true,\n }, extra || {});\n if (window.__srRecordEvent) {\n try { window.__srRecordEvent(evt); } catch {}\n }\n }\n\n document.addEventListener('click', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('click', el, null);\n }, true);\n\n document.addEventListener('input', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n const value = (el.value !== undefined && el.value !== null) ? String(el.value) : (el.textContent || '');\n send('input', el, value);\n }, true);\n\n document.addEventListener('change', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n if (el.tagName !== 'SELECT') return;\n send('change', el, String(el.value));\n }, true);\n\n document.addEventListener('keydown', (e) => {\n if (e.key !== 'Enter' && e.key !== 'Escape' && e.key !== 'Tab') return;\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('keydown', el, e.key);\n }, true);\n\n document.addEventListener('submit', (e) => {\n const el = e.target;\n if (!el || el.nodeType !== 1) return;\n send('submit', el, null);\n }, true);\n\n // Scroll capture — debounce 250ms, coalesce within window, emit direction + accumulated deltaY.\n let scrollLastY = window.scrollY;\n let scrollAccum = 0;\n let scrollTimer = null;\n let scrollTarget = null;\n function flushScroll() {\n scrollTimer = null;\n if (scrollAccum === 0) return;\n const direction = scrollAccum > 0 ? 'down' : 'up';\n const deltaY = Math.abs(scrollAccum);\n scrollAccum = 0;\n const el = scrollTarget || document.scrollingElement || document.body;\n send('scroll', el, direction, { deltaY: deltaY });\n }\n document.addEventListener('scroll', (e) => {\n const target = (e.target === document ? (document.scrollingElement || document.body) : e.target);\n if (!target || target.nodeType !== 1) return;\n const currentY = target === document.scrollingElement || target === document.body\n ? window.scrollY\n : (target.scrollTop || 0);\n const delta = currentY - scrollLastY;\n scrollLastY = currentY;\n if (delta === 0) return;\n // Direction change → flush the previous burst immediately.\n if (scrollAccum !== 0 && Math.sign(delta) !== Math.sign(scrollAccum)) {\n if (scrollTimer !== null) { clearTimeout(scrollTimer); scrollTimer = null; }\n flushScroll();\n }\n scrollAccum += delta;\n scrollTarget = target;\n if (scrollTimer === null) {\n scrollTimer = setTimeout(flushScroll, 250);\n }\n }, true);\n})();\n`;\n\n/**\n * Stream of RecordedEvents → coalesced Action[] suitable for a manifest segment.\n * Rules:\n * - Contiguous `input` events on the same selector collapse into one `type`\n * action carrying the final value.\n * - `keydown:Enter` after an input on the same selector becomes a `press: Enter`.\n * - Standalone `click` events become `click` actions, unless the next event is\n * an input on the same selector (then the click is just focus — drop it).\n * - `submit` is dropped (Enter or button-click already triggered it).\n * - `change` on a `<select>` becomes `fill` with the value.\n */\nexport function coalesceEvents(events: RecordedEvent[]): Action[] {\n const out: Action[] = [];\n let pendingInputSelector: string | undefined;\n\n for (let i = 0; i < events.length; i++) {\n const evt = events[i]!;\n const next = events[i + 1];\n\n if (evt.kind === 'click') {\n // If the next event is an input on the same selector, this click was\n // just focusing the field — drop it.\n if (next && next.kind === 'input' && next.selector === evt.selector) {\n continue;\n }\n out.push({ type: 'click', selector: evt.selector });\n pendingInputSelector = undefined;\n continue;\n }\n\n if (evt.kind === 'input') {\n // Find the last value across the run of consecutive inputs on this selector.\n let lastValue = evt.payload ?? '';\n let j = i;\n while (j + 1 < events.length) {\n const peek = events[j + 1]!;\n if (peek.kind === 'input' && peek.selector === evt.selector) {\n lastValue = peek.payload ?? '';\n j++;\n continue;\n }\n break;\n }\n i = j;\n out.push({ type: 'type', selector: evt.selector, value: lastValue });\n pendingInputSelector = evt.selector;\n continue;\n }\n\n if (evt.kind === 'keydown' && evt.payload === 'Enter') {\n // Press Enter on the field, attached to current selector if known.\n out.push({ type: 'press', key: 'Enter', selector: evt.selector });\n pendingInputSelector = undefined;\n continue;\n }\n if (evt.kind === 'keydown' && evt.payload === 'Escape') {\n out.push({ type: 'press', key: 'Escape', selector: evt.selector });\n continue;\n }\n if (evt.kind === 'keydown' && evt.payload === 'Tab') {\n out.push({ type: 'press', key: 'Tab', selector: evt.selector });\n continue;\n }\n\n if (evt.kind === 'change') {\n out.push({ type: 'fill', selector: evt.selector, value: evt.payload ?? '' });\n continue;\n }\n\n if (evt.kind === 'scroll') {\n // Coalesce consecutive scroll bursts on the same selector + direction\n // into a single scroll action. A direction change ends the run.\n const direction = evt.payload === 'up' ? 'up' : 'down';\n let j = i;\n while (j + 1 < events.length) {\n const peek = events[j + 1]!;\n if (\n peek.kind === 'scroll' &&\n peek.selector === evt.selector &&\n (peek.payload === 'up' ? 'up' : 'down') === direction\n ) {\n j++;\n continue;\n }\n break;\n }\n i = j;\n out.push({ type: 'scroll', selector: evt.selector, direction });\n continue;\n }\n // submit: dropped intentionally\n }\n\n void pendingInputSelector;\n return out;\n}\n\n/**\n * Watch navigations on the page and emit wait_for_url actions when the URL changes.\n * Returns a function that drains current navigation events into the action array.\n */\nexport function attachNavigationCapture(\n page: Page,\n pushEvent: (action: Action) => void,\n): void {\n let lastUrl = page.url();\n page.on('framenavigated', (frame) => {\n if (frame !== page.mainFrame()) return;\n const url = frame.url();\n if (url === lastUrl) return;\n lastUrl = url;\n if (url === 'about:blank') return;\n pushEvent({ type: 'wait_for_url', pattern: url });\n logger.debug(`captured navigation`, { url });\n });\n}\n"],"mappings":"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","names":["resolve","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","text","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","password","mkdir","dirname","join","state","join","mkdir","dirname","browserMap","chromium","firefox","webkit","resolve","join","mkdir","text","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","text","writeFile","writeFile","text","resolve","fileExists","join","mkdir","dirname","rename","isAbsolute","resolve","dirname","mkdir","writeFile","spawn","stat","isAbsolute","resolve","dirname","join","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","dirname","isAbsolute","spawn","stat","join","runCommand","resolve","mkdir","writeFile","access","dirname","isAbsolute","join","resolve","spawn","access","stat","chromium","resolve","undiciRequest","z","readFile","readdir","stat","join","text","z","spawn","spawn","sleep","isAbsolute","resolve","join","mkdir","dirname","writeFile","access","spawn","access","dirname","join","spawn","resolve","dirname","join","access","readFile","writeFile","isAbsolute","resolve","yaml","isAbsolute","resolve","readFile","yaml","writeFile","stat","isAbsolute","resolve","isAbsolute","resolve","stat","resolve","resolve","text","rm","stat","resolve","resolve","pathExists","rm","stat","mkdir","rename","writeFile","join","resolve","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","mkdir","join","rename","writeFile","mkdir","dirname","isAbsolute","resolve","mkdir","resolve","chromium","firefox","webkit","browserMap","chromium","firefox","webkit","resolve","mkdir","text","resolve","isAbsolute","mkdir","dirname","readdir","stat","isAbsolute","join","resolve","resolve","join","isAbsolute","fileExists","readdir","stat","stat","resolve","resolve","fileExists","stat","mkdir","readFile","writeFile","dirname","isAbsolute","resolve","DEFAULT_MAX_TOKENS","createInterface","resolve","ask","resolve","isAbsolute","mkdir","dirname","readFile","writeFile","mkdir","readdir","writeFile","dirname","isAbsolute","join","resolve","relative","readFile","z","DEFAULT_MAX_TOKENS","z","SYSTEM_PROMPT","readFile","relative","resolve","readdir","join","relative","isAbsolute","mkdir","dirname","writeFile","createInterface","resolve","stat","resolve","createInterface","fileExists","stat","runCommand","access","resolve","chromium","stat"]}