diff --git a/apps/fabro-web/app/routes/run-stages.tsx b/apps/fabro-web/app/routes/run-stages.tsx
index d10756a24..7503f0c3a 100644
--- a/apps/fabro-web/app/routes/run-stages.tsx
+++ b/apps/fabro-web/app/routes/run-stages.tsx
@@ -1,8 +1,10 @@
import { useEffect, useMemo, useState } from "react";
import { useParams } from "react-router";
import {
+ ArrowDownTrayIcon,
ChevronDownIcon,
ChevronRightIcon,
+ ClipboardDocumentIcon,
CpuChipIcon,
} from "@heroicons/react/16/solid";
import { CircleStackIcon, ClockIcon } from "@heroicons/react/20/solid";
@@ -1234,6 +1236,66 @@ function EventsTabToggle({
);
}
+function EventExportActions({
+ events,
+ runId,
+ stageId,
+ className,
+}: {
+ events: EventEnvelope[];
+ runId: string;
+ stageId: string;
+ className?: string;
+}) {
+ const [copied, setCopied] = useState(false);
+ const disabled = events.length === 0;
+ const buttonClass =
+ "inline-flex size-6 items-center justify-center rounded text-fg-muted transition-colors hover:bg-overlay hover:text-fg-2 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-teal-500 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-fg-muted";
+ return (
+
+
+
+
+ );
+}
+
function EventsToolbar({
tab,
renderer,
@@ -1250,6 +1312,9 @@ function EventsToolbar({
filteredCount,
totalCount,
providerUsed,
+ events,
+ runId,
+ stageId,
}: {
tab: EventsTab;
renderer: StageRenderer;
@@ -1266,6 +1331,9 @@ function EventsToolbar({
filteredCount: number;
totalCount: number;
providerUsed: StageModelUsage | null;
+ events: EventEnvelope[];
+ runId: string;
+ stageId: string;
}) {
// Filters apply to: the agent transcript (filter event kinds) and the Debug
// tab (filter event categories). Specialized renderers (human, parallel,
@@ -1348,6 +1416,12 @@ function EventsToolbar({
{modelUsageLabel}
)}
+
{tab === "primary" && renderer === "command" && commandTurn && (
)}
@@ -1560,6 +1634,9 @@ export default function RunStages() {
filteredCount={effectiveTab === "primary" ? filteredTurns.length : filteredDebugEvents.length}
totalCount={effectiveTab === "primary" ? turns.length : debugEvents.length}
providerUsed={selectedStage.providerUsed}
+ events={stageEventsQuery.data ?? []}
+ runId={id ?? ""}
+ stageId={selectedStageId ?? ""}
/>
{effectiveTab === "debug" && (