import { useActionQuery } from "@agent-native/core/client/hooks"; import { IconAlertTriangle, IconClock, IconExternalLink, IconPlayerPause, IconPlayerPlay, } from "@tabler/icons-react"; import { Link } from "react-router"; import { automationScopeLabel, automationStatus, automationTarget, } from "../lib/automation-display"; import { automationRunScope, type DispatchAutomationItem, } from "../lib/automations"; import { ActionQueryError } from "./action-query-error"; import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; import { Skeleton } from "./ui/skeleton"; interface AutomationRun { id: string; runId: string | null; threadId: string | null; status: "running" | "success" | "error" | "interrupted"; startedAt: number; finishedAt: number | null; error: string | null; } export interface AutomationDetailsPanelProps { automation: DispatchAutomationItem; isToggling?: boolean; onToggle: () => void; } function formatTimestamp(value: number | string | null | undefined): string { if (value == null) return "Not recorded"; const date = new Date(value); return Number.isNaN(date.getTime()) ? "Unknown time" : date.toLocaleString(); } function formatDuration(run: AutomationRun): string | null { if (!run.finishedAt) return null; const seconds = Math.max( 0, Math.round((run.finishedAt - run.startedAt) / 1000), ); return `${seconds}s`; } function runDebugPath(run: AutomationRun): string | null { const params = new URLSearchParams(); if (run.runId) params.set("runId", run.runId); else if (run.threadId) params.set("threadId", run.threadId); else return null; return `/admin/thread-debug?${params.toString()}`; } function runStatusVariant( status: AutomationRun["status"], ): "default" | "destructive" | "outline" { if (status === "error") return "destructive"; if (status === "success") return "default"; return "outline"; } function DetailField({ label, value, mono = false, }: { label: string; value: string; mono?: boolean; }) { return (