import { findPlaybook, loadPlaybooks } from "./playbooks.js"; import { listRunIds, loadRun } from "./state.js"; import type { PlaybookRunState } from "./types.js"; export interface CompletedRunSummary { run: PlaybookRunState; playbookName: string; completedAt: string; finalOutcome: string; } export function finalOutcome(run: PlaybookRunState): string { const last = run.history.at(-1); return last?.outcome ?? "complete"; } export async function listCompletedRuns(cwd: string): Promise { const ids = await listRunIds(cwd); const runs = (await Promise.all(ids.map((id) => loadRun(cwd, id)))).filter((run): run is PlaybookRunState => Boolean(run)); return runs.filter((run) => run.status === "completed").sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)); } export async function summarizeCompletedRun(cwd: string, run: PlaybookRunState): Promise { const playbook = await findPlaybook(cwd, run.playbookId); return createCompletedRunSummary(run, playbook?.definition.name ?? run.playbookId); } export async function summarizeCompletedRuns(cwd: string, runs: PlaybookRunState[]): Promise { if (runs.length === 0) return []; const playbooks = await loadPlaybooks(cwd); const namesById = new Map(); for (const playbook of playbooks) { if (!namesById.has(playbook.definition.id)) namesById.set(playbook.definition.id, playbook.definition.name); } return runs.map((run) => createCompletedRunSummary(run, namesById.get(run.playbookId) ?? run.playbookId)); } export async function listCompletedRunSummaries(cwd: string): Promise { const runs = await listCompletedRuns(cwd); return summarizeCompletedRuns(cwd, runs); } function createCompletedRunSummary(run: PlaybookRunState, playbookName: string): CompletedRunSummary { return { run, playbookName, completedAt: run.updatedAt, finalOutcome: finalOutcome(run), }; } export function formatCompletedRunLine(summary: CompletedRunSummary): string { return `${summary.run.runId} — ${summary.playbookName} — ${summary.completedAt} — ${summary.finalOutcome}`; } export function renderCompletedRunDetail(summary: CompletedRunSummary): string[] { const history = summary.run.history.map((entry) => ` ${entry.at} ${entry.step} → ${entry.outcome} (${entry.to})`); return [ `Completed: ${summary.playbookName}`, `Run: ${summary.run.runId}`, `Finished: ${summary.completedAt}`, `Final outcome: ${summary.finalOutcome}`, ...(history.length > 0 ? ["History:", ...history] : []), ]; }