import type {
Execution,
ExecutionEnvelope,
} from "@executor/react";
import {
useExecution,
useExecutions,
} from "@executor/react";
import {
Alert,
Badge,
Button,
Card,
DocumentPanel,
EmptyState,
LoadableBlock,
useExecutorPluginNavigation,
useExecutorPluginRouteParams,
} from "@executor/react/plugins";
const formatTimestamp = (value: number | null): string => {
if (value === null) {
return "—";
}
return new Intl.DateTimeFormat(undefined, {
dateStyle: "medium",
timeStyle: "short",
}).format(value);
};
const formatDuration = (execution: Execution): string | null => {
if (execution.startedAt === null || execution.completedAt === null) {
return null;
}
const durationMs = Math.max(0, execution.completedAt - execution.startedAt);
if (durationMs < 1_000) {
return `${durationMs} ms`;
}
if (durationMs < 60_000) {
return `${(durationMs / 1_000).toFixed(1)} s`;
}
return `${(durationMs / 60_000).toFixed(1)} min`;
};
const summarizeCode = (code: string): string =>
code
.trim()
.replace(/\s+/g, " ")
.slice(0, 220);
const formatJsonDocument = (value: string | null): string | null => {
if (value === null) {
return null;
}
try {
return JSON.stringify(JSON.parse(value), null, 2);
} catch {
return value;
}
};
const statusVariant = (
status: Execution["status"],
): "default" | "muted" | "outline" | "destructive" => {
switch (status) {
case "completed":
return "default";
case "failed":
return "destructive";
case "running":
case "waiting_for_interaction":
return "outline";
default:
return "muted";
}
};
const MetadataItem = (props: {
label: string;
value: string;
}) => (
Every execution recorded for this workspace, newest first.
{pendingInteraction.kind} • {pendingInteraction.purpose}