import { useId, useState } from "react"; import { useMutation } from "@tanstack/react-query"; import type { IssueRecoveryAction } from "@paperclipai/shared"; import { isNativeWorkspaceExportRepairCause } from "@paperclipai/shared"; import { issuesApi } from "../api/issues"; import { Button } from "./ui/button"; import { Label } from "./ui/label"; import { Textarea } from "./ui/textarea"; /** Copyback repair preserves the accepted result and never wakes the provider. */ export function WorkspaceExportRecovery({ issueId, action, canManage, onQueued }: { issueId: string; action: IssueRecoveryAction | null; canManage: boolean; onQueued: () => void; }) { const noteId = useId(); const [repairNote, setRepairNote] = useState(""); const [queuedActionVersion, setQueuedActionVersion] = useState(null); const retry = useMutation({ mutationFn: () => issuesApi.retryWorkspaceExport(issueId, { actionId: action!.id, runId: action!.evidence.runId as string, repairNote: repairNote.trim(), }), onSuccess: () => { setQueuedActionVersion(String(action!.updatedAt)); onQueued(); }, }); if (!action || !isNativeWorkspaceExportRepairCause(action.cause) || action.ownerType !== "board" || !["active", "escalated"].includes(action.status) || typeof action.evidence.runId !== "string") return null; const queued = queuedActionVersion === String(action.updatedAt) || action.wakePolicy?.kind === "resume_native_run"; return

Workspace export needs repair

{queued ?

Export is queued for the saved result. The agent will not repeat its work.

: <>

{"Automatic workspace export retries stopped. Inspect the export failure, restore provider or destination availability, and preserve the saved files in the retained sandbox. Retry export here when the cause is resolved."}

{canManage ? <>