// The sweep-report kind: a cited report that is not yet a video. // // It has no decisions, no build and no rich read, which is exactly why it is // here on day one: it is the cheapest possible proof that adding a kind costs a // registry entry and nothing else. import { readdir, readFile, stat } from "node:fs/promises"; import path from "node:path"; const stat0 = (p) => stat(p).then((s) => s, () => null); const SWEEP_RE = /(^|[-_])sweep([-_]report)?\.md$|^sweep-report\.md$/i; export async function sweepSignature(dir) { const st = await stat0(dir); return String(Math.round(st?.mtimeMs ?? 0)); } export async function summariseSweep(ctx) { const { dir, name } = ctx; const names = await readdir(dir).catch(() => []); const reportName = names.find((n) => SWEEP_RE.test(n)); const file = reportName ? path.join(dir, reportName) : null; const [text, st] = await Promise.all([ file ? readFile(file, "utf8").catch(() => null) : null, file ? stat0(file) : null, ]); // A citation in these reports is a markdown link carrying a `?v=` moment. // Counting them is the one number worth putting on the card: it is how much // work a manifest would be. const citations = text ? (text.match(/\]\([^)]*[?&]v=/g) ?? []).length : 0; const title = text?.match(/^#\s+(.+)$/m)?.[1]?.trim() ?? name; const facts = []; if (citations) facts.push(`${citations} citation${citations === 1 ? "" : "s"}`); facts.push("no manifest"); return { title, subtitle: "a report, not yet a video", state: "draft", newestMtimeMs: st?.mtimeMs ?? 0, facts, flags: [], posterRel: null, haystack: [ctx.id, title, reportName].filter(Boolean).join(" ").toLowerCase(), reportName, }; }