import { readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { parseFlags } from "../../skills/doc-wiki/scripts/_cli_args.js"; import { loadState, runKey } from "./bench_checkpoint.js"; import type { Arm, BenchState, RunRecord, TicketRecord, TicketsFile } from "./types.js"; const ARMS: readonly Arm[] = ["baseline", "wiki"]; const cell = (r: RunRecord | undefined): string => { if (r === undefined || r.status === "pending") return "⏳"; if (r.status === "passed") return r.detail === "tests-passed-on-retry" ? "✅ (retry)" : "✅"; if (r.status === "failed") return `❌ ${r.detail ?? ""}`.trim(); return r.status; }; export function renderResults(repo: string, tickets: readonly TicketRecord[], state: BenchState): string { const lines: string[] = [`## ${repo}`, ""]; let cost = 0; lines.push("| arm | passed/graded (rate) |", "|---|---|"); const gradedByArm: number[] = []; for (const arm of ARMS) { let passed = 0; let graded = 0; for (const t of tickets) { const r = state.runs[runKey(t.issue, arm)]; if (r?.cost_usd !== undefined) cost += r.cost_usd; if (r?.status === "passed" || r?.status === "failed") { graded += 1; if (r.status === "passed") passed += 1; } } gradedByArm.push(graded); const rate = graded === 0 ? 0 : Math.round((passed / graded) * 100); lines.push(`| ${arm} | ${passed}/${graded} (${rate}%) |`); } if (new Set(gradedByArm).size > 1) { lines.push("", "> Note: arms have unequal graded counts — rates are not directly comparable until grading completes."); } lines.push("", `Total session cost: $${cost.toFixed(2)}`, ""); lines.push("| ticket | merged | baseline | wiki |", "|---|---|---|---|"); for (const t of tickets) { const safeTitle = t.title.replace(/\|/g, "\\|"); lines.push( `| #${t.issue} ${safeTitle} | ${t.merged_at.slice(0, 10)} | ${cell(state.runs[runKey(t.issue, "baseline")])} | ${cell(state.runs[runKey(t.issue, "wiki")])} |`, ); } lines.push(""); return lines.join("\n"); } export async function main(argv: readonly string[]): Promise { const { help, values } = parseFlags(argv, { "--repo": "repo", "--out": "out" }); if (help || values.repo === undefined) { process.stderr.write("usage: benchmark report --repo [--out benchmark/RESULTS.md]\n"); return help ? 0 : 2; } const repo = String(values.repo); const ticketsFile = JSON.parse(readFileSync(join("benchmark", "tickets", `${repo}.json`), "utf8")) as TicketsFile; const active = ticketsFile.tickets.filter((t) => t.excluded === undefined); const state = loadState(join("benchmark", "runs", repo, "state.json"), repo); const md = `# Benchmark Results\n\n> Generated by \`npm run benchmark -- report\`. Methodology: [METHODOLOGY.md](METHODOLOGY.md).\n\n${renderResults(repo, active, state)}`; writeFileSync(String(values.out ?? join("benchmark", "RESULTS.md")), md); return 0; }