/** * `event` — persist one ordinary material outcome without sending it. * * Moved out of cli.ts's switch by the per-verb module split (#462); * only the case wrapper, the injected `ctx` lookups and the imports * changed from the original bodies. */ import type { CommandContext } from "./context.ts"; import { findProject, loadConfig } from "../config.ts"; import { dbPath, openStore } from "../store.ts"; export async function eventCommand(ctx: CommandContext): Promise { if (ctx.argv[1] !== "record") { process.stderr.write("omp-conductor: event needs the record subcommand\n"); process.exit(2); } const category = ctx.flag("category"); const summary = ctx.flag("summary")?.replace(/\s+/g, " ").trim(); const evidence = ctx.flag("evidence")?.replace(/\s+/g, " ").trim(); if ( category === undefined || !/^[a-z0-9][a-z0-9-]{0,31}$/.test(category) || summary === undefined || summary.length === 0 || summary.length > 240 || summary.startsWith("--") || evidence === undefined || evidence.length === 0 || evidence.length > 500 || evidence.startsWith("--") ) { process.stderr.write( "omp-conductor: event record needs --category with a lowercase slug, --summary (1-240 chars), and --evidence (1-500 chars)\n", ); process.exit(2); } const rawOccurredAt = ctx.flag("occurred-at"); const recordedAt = Date.now(); const occurredAt = rawOccurredAt === undefined ? recordedAt : Date.parse(rawOccurredAt); if (!Number.isFinite(occurredAt)) { process.stderr.write("omp-conductor: event record --occurred-at needs an ISO timestamp\n"); process.exit(2); } const project = findProject(loadConfig(), ctx.projectFlag); const store = openStore(dbPath()); try { const event = store.recordMaterialEvent({ project: project.name, category, summary, evidence, occurredAt, recordedAt, }); process.stdout.write( `event ${event.id} recorded for ${project.name} (${event.category}, ${new Date(event.occurredAt).toISOString()}) — nothing sent\n`, ); } finally { store.close(); } }