#!/usr/bin/env node // E2E fake for scripts/diarize.mjs (the speaker-diarization wrapper). Mimics the // args controller/diarizeOne.ts builds: // diarize.mjs --output diarization.json --video-id --seg --emb // --threshold --threads --python

// Output contract: write a DiarizationRecord (common/lib/diarization.ts) to // EXACTLY the --output path. Run from cwd == the video dir. // // Two modes by video dir (cwd), mirroring how fake-parakeet-stitch keys off the // dir name: // * default: write a plausible two-speaker record and exit 0. // * vidC, or any dir containing "diarizefail": exit non-zero WITHOUT writing // anything. This is the case that must not fail the surrounding // transcription, and must leave the video ineligible for the Clean-audio // sweep — audio is unrecoverable, so "the diarizer broke" has to read as // "keep the audio", never as "done". // // vidC is the designated failing id because it is already in the shared // one-transcribe-channel-with-audio fixture's archive; a spec can exercise the // failure path without renaming dirs into ids the batch would never pick up. import { writeFile } from "node:fs/promises"; import path from "node:path"; import { installFixtureWatchdog } from "./_watchdog.mjs"; // Never outlive the run that spawned us — see _watchdog.mjs. installFixtureWatchdog(); const argv = process.argv.slice(2); function arg(flag) { const i = argv.indexOf(flag); return i < 0 ? undefined : argv[i + 1]; } const out = arg("--output") ?? arg("-o"); const videoId = arg("--video-id") ?? path.basename(process.cwd()); const seg = arg("--seg"); const emb = arg("--emb"); const threshold = Number(arg("--threshold") ?? "0.5"); const audio = argv[argv.length - 1]; if (!out) { process.stderr.write("[fake-diarize] missing --output\n"); process.exit(2); } const cwd = process.cwd(); if ( cwd.toLowerCase().includes("diarizefail") || path.basename(cwd) === "vidC" ) { process.stderr.write(`[fake-diarize] synthetic engine failure for ${videoId}\n`); process.exit(3); } const turns = [ { start: 0, end: 4.5, speaker: 0 }, { start: 4.5, end: 7.25, speaker: 1 }, { start: 7.25, end: 10, speaker: 0 }, ]; await writeFile( out, JSON.stringify({ videoId, generatedAt: new Date().toISOString(), audioSeconds: 10, durationMs: 1, speakers: new Set(turns.map((t) => t.speaker)).size, turns, engine: { engine: "fake-diarize", ...(seg ? { segmentationModel: path.basename(seg) } : {}), ...(emb ? { embeddingModel: path.basename(emb) } : {}), version: "e2e", threshold, }, }) + "\n", ); process.stderr.write( `[fake-diarize] ${turns.length} turns for ${videoId} (${audio}) -> ${out}\n`, );