| 1 | import { app } from "./bridge"; |
| 2 | import { t } from "./i18n"; |
| 3 | import type { RewindResultView } from "./types"; |
| 4 | |
| 5 | export async function commitRewindWithPreview( |
| 6 | sourceTabId: string, |
| 7 | turn: number, |
| 8 | scope: "conversation" | "code" | "both", |
| 9 | ): Promise<RewindResultView> { |
| 10 | const plan = await app.PreviewRewindForTab(sourceTabId, turn, scope); |
| 11 | const remoteLegacy = !plan?.ok && /remote host uses legacy rewind semantics/i.test(plan?.error || ""); |
| 12 | if (!remoteLegacy) { |
| 13 | const canCommit = scope === "conversation" |
| 14 | ? plan?.canConversation |
| 15 | : scope === "both" |
| 16 | ? plan?.canConversation && plan?.canFiles |
| 17 | : plan?.canFiles; |
| 18 | if (!plan?.ok || !canCommit) { |
| 19 | return { |
| 20 | ok: false, |
| 21 | error: plan?.error |
| 22 | || plan?.disabledReason |
| 23 | || (plan?.conflicts?.length ? plan.conflicts.join("; ") : "") |
| 24 | || "rewind unavailable", |
| 25 | conflicts: plan?.conflicts, |
| 26 | }; |
| 27 | } |
| 28 | if (scope !== "conversation" && (plan.coverage === "partial" || (plan.coverageGaps?.length ?? 0) > 0)) { |
| 29 | const gaps = (plan.coverageGaps || []).join("\n"); |
| 30 | if (!window.confirm(t("rewind.confirmPartialCoverage", { gaps: gaps || t("rewind.partialCoverageUnknown") }))) { |
| 31 | return { ok: false, error: "rewind cancelled" }; |
| 32 | } |
| 33 | } |
| 34 | } |
| 35 | return app.CommitRewindForTab(sourceTabId, remoteLegacy ? "" : (plan.planId || ""), turn, scope); |
| 36 | } |
| 37 | |
| 38 | export function undoCommittedRewind(sourceTabId: string, transactionId: string): Promise<RewindResultView> { |
| 39 | return app.UndoRewindForTab(sourceTabId, transactionId); |
| 40 | } |
| 41 |