import { listRuns } from "@autoscholar/core"; import type { RunStatus } from "@autoscholar/schemas"; import Link from "next/link"; import { StatusBadge } from "@/components/StatusBadge"; import { ago, fmtUsd, modeLabel } from "@/lib/format"; import { db } from "@/lib/server/db"; export const dynamic = "force-dynamic"; const GROUPS: Record = { active: [ "queued", "provisioning", "running", "quality_check", "revising", "retrying", "publishing", "cancelling", ], blocked: ["quality_failed", "awaiting_approval", "ready_to_publish"], done: ["published", "failed", "cancelled"], }; export default async function RunsPage({ searchParams }: { searchParams: Promise<{ filter?: string }> }) { const { filter } = await searchParams; const statuses = filter && GROUPS[filter] ? (GROUPS[filter] as RunStatus[]) : undefined; const runs = await listRuns(db(), { status: statuses, limit: 200 }); return (

Orchestration

Runs

{runs.length === 0 && ( )} {runs.map((r) => ( ))}
Title Mode Status Stage Attempt Cost Auto-publish Updated
No runs match.
{r.title}

{r.id}

{modeLabel(r.researchMode)} {r.currentStage ?? "—"} {r.currentAttemptNo}/{r.maxAttempts} {fmtUsd(r.totalCostUsd)} / {fmtUsd(r.maxBudgetUsd)} {r.autoPublish ? "yes" : "no"} {ago(r.updatedAt)}
); }