export const dynamic = "force-dynamic"; import type { Metadata } from "next"; import Link from "next/link"; import { eq } from "drizzle-orm"; import { notFound } from "next/navigation"; import { RotateCw } from "lucide-react"; import { getDb } from "@/lib/db/client"; import { runs } from "@/lib/db/schema"; import { getScript } from "@/lib/config/load"; import { readLogTail } from "@/lib/runner/log-file"; import { RunTerminal } from "@/components/runs/run-terminal"; import { buttonVariants } from "@/components/ui/button"; import { Card, CardAction, CardContent, CardHeader, CardTitle, } from "@/components/ui/card"; interface RunDetailPageProps { params: Promise<{ runId: string }>; } function formatVariableValue(value: unknown): string { if (value === undefined || value === null || value === "") return "—"; if (Array.isArray(value)) return value.length ? value.join(", ") : "—"; if (typeof value === "boolean") return value ? "true" : "false"; return String(value); } export async function generateMetadata({ params, }: RunDetailPageProps): Promise { const { runId } = await params; const run = getDb() .select({ scriptName: runs.scriptName }) .from(runs) .where(eq(runs.id, runId)) .get(); return { title: run ? `${run.scriptName} run` : "Run not found" }; } export default async function RunDetailPage({ params }: RunDetailPageProps) { const { runId } = await params; const db = getDb(); const run = db.select().from(runs).where(eq(runs.id, runId)).get(); if (!run) notFound(); const { text: initialLog, size: initialLogBytes } = readLogTail( run.logFilePath, ); const script = getScript(run.scriptId); const variableEntries = script ? script.variables.map((variable) => ({ key: variable.name, label: variable.label ?? variable.name, value: run.variables[variable.name], })) : Object.entries(run.variables).map(([key, value]) => ({ key, label: key, value, })); return (
{run.scriptName} {script && ( Re-run )}
Triggered by
{run.triggeredBy}
Started
{run.startedAt ? new Date(run.startedAt).toLocaleString() : "-"}
Run ID
{run.id}
Command
              {run.resolvedCommand}
            
{variableEntries.length > 0 && (
Variables
{variableEntries.map(({ key, label, value }) => (
{label}
{formatVariableValue(value)}
))}
)}
); }