import Link from "next/link"; import { notFound } from "next/navigation"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { listFleetAgents } from "@/lib/agents"; import { findTask, listTaskEvents } from "@/lib/tasks"; import { formatDateTime } from "@/lib/utils"; import type { FleetAgent, TaskEvent, TaskRecord } from "@/lib/types"; export const dynamic = "force-dynamic"; function familyVariant(family: TaskRecord["family"]) { if (family === "zeroclaw") { return "success"; } if (family === "direct") { return "warning"; } return "default"; } function dispatchVariant(state: TaskRecord["dispatch_state"]) { return state === "failed" ? "warning" : state === "completed" ? "success" : "secondary"; } function collectDependencyRows(task: TaskRecord) { const rows = [ { label: "Template", value: task.template_key }, { label: "Repository", value: task.repo_slug }, { label: "Base Branch", value: task.base_branch }, { label: "Preferred Agent", value: task.preferred_agent }, { label: "Model Hint", value: task.model_hint }, { label: "Reasoning Effort", value: task.reasoning_effort }, ]; return rows.filter((row) => row.value); } function collectRequirementRows(task: TaskRecord) { const rows = [ { label: "Assignee", value: task.assignee || "Unassigned" }, { label: "Family", value: task.family || "manual" }, { label: "Target Host", value: task.target_host || "n/a" }, { label: "Target Channel", value: task.target_channel || "n/a" }, { label: "Dispatch Method", value: task.dispatch_method }, { label: "Dispatch State", value: task.dispatch_state }, { label: "Priority", value: task.priority }, { label: "Status", value: task.status }, ]; return rows; } function findAssignedAgent(task: TaskRecord, agents: FleetAgent[]) { return agents.find( (agent) => agent.assignmentKey === task.assignee || agent.slug === task.assignee || agent.aliases.includes(task.assignee), ); } function renderEventTone(event: TaskEvent["event_type"]) { if (event === "dispatch_failed") { return "border-amber-400/20 bg-amber-500/5"; } if (event === "dispatch_succeeded" || event === "acknowledged") { return "border-emerald-400/20 bg-emerald-500/5"; } return "border-white/10 bg-slate-950/40"; } export default async function TaskDetailPage({ params, }: { params: Promise<{ id: string }>; }) { const { id } = await params; const numericId = Number(id); if (!Number.isInteger(numericId) || numericId <= 0) { notFound(); } const [task, events, agents] = await Promise.all([ findTask(numericId), listTaskEvents(numericId, 100), listFleetAgents(), ]); if (!task) { notFound(); } const requirementRows = collectRequirementRows(task); const dependencyRows = collectDependencyRows(task); const assignedAgent = findAssignedAgent(task, agents); return (
Latest Result
{task.result_summary || "No result has been posted yet."}
Completion
Execution Detail
{task.result_detail || task.last_error || "No detailed execution transcript has been recorded yet."}
Latest Failure
{task.last_error}
{event.summary}
{event.event_type.replace(/_/g, " ")} {event.state ? ` • ${event.state}` : ""}
{formatDateTime(event.created_at)}
{event.detail}
) : null}No explicit dependencies or repository context were captured for this task.
)}Tags
{assignedAgent.name}
{assignedAgent.role}
No configured fleet agent matched this task assignee.
)}