/** * Build (or rebuild) `compare.html` for a harness run directory. * * Usage: * # explicit run dir * pnpm tsx eval/pbl-v2-planner/build-compare.ts eval/pbl-v2-planner/results// * # latest run under results/ (auto-pick) * pnpm tsx eval/pbl-v2-planner/build-compare.ts * * Then open the printed compare.html path in a browser. */ import { readdirSync, statSync, existsSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { buildCompareHtml } from './compare-html'; function here(): string { return typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url)); } /** Find the most recently modified run dir (the leaf containing projects/). */ function latestRunDir(): string | undefined { const resultsRoot = join(here(), 'results'); if (!existsSync(resultsRoot)) return undefined; let best: { dir: string; mtime: number } | undefined; for (const model of readdirSync(resultsRoot)) { const modelDir = join(resultsRoot, model); if (!statSync(modelDir).isDirectory()) continue; for (const ts of readdirSync(modelDir)) { const dir = join(modelDir, ts); if (!statSync(dir).isDirectory()) continue; if (!existsSync(join(dir, 'projects'))) continue; const mtime = statSync(dir).mtimeMs; if (!best || mtime > best.mtime) best = { dir, mtime }; } } return best?.dir; } function main(): void { const arg = process.argv[2]; const runDir = arg || latestRunDir(); if (!runDir) { console.error('No run dir given and none found under results/. Run the harness first.'); process.exit(1); } if (!existsSync(join(runDir, 'projects'))) { console.error(`"${runDir}" has no projects/ subdir — not a harness run dir.`); process.exit(1); } const out = buildCompareHtml(runDir); console.log(`Wrote ${out}`); console.log(`Open it: file://${out}`); } main();