diff --git a/src/renderer/src/components/orca-cloud/CloudMoveToComputerDialog.tsx b/src/renderer/src/components/orca-cloud/CloudMoveToComputerDialog.tsx index 48dd1abb2cb..71640370a4b 100644 --- a/src/renderer/src/components/orca-cloud/CloudMoveToComputerDialog.tsx +++ b/src/renderer/src/components/orca-cloud/CloudMoveToComputerDialog.tsx @@ -10,7 +10,8 @@ import { } from '@/components/ui/dialog' import { useNow } from '@/hooks/use-now' import { useTranslate, type Translate } from '@/i18n/use-translate' -import { reapplyOrcaCloudTransfer, runOrcaCloudTransferToLocal } from '@/lib/orca-cloud-transfer-flow' +import { runOrcaCloudTransferToLocal } from '@/lib/orca-cloud-transfer-flow' +import { reapplyOrcaCloudTransfer } from '@/lib/orca-cloud-transfer-reapply' import { activateAndRevealWorktree } from '@/lib/workspace/activation/worktree-activation' import { closeMoveToThisComputer, diff --git a/src/renderer/src/lib/orca-cloud-session-events.ts b/src/renderer/src/lib/orca-cloud-session-events.ts index 6d76dcc3237..1df37e48993 100644 --- a/src/renderer/src/lib/orca-cloud-session-events.ts +++ b/src/renderer/src/lib/orca-cloud-session-events.ts @@ -1,5 +1,5 @@ // Window side of Orca Cloud's session lifecycle: cap warnings, rollovers and idle sleep from main. -import { offerPendingCloudTransfers } from '@/lib/orca-cloud-transfer-flow' +import { offerPendingCloudTransfers } from '@/lib/orca-cloud-transfer-reapply' import { armInterruptedTurnsForHostRestart, continueInterruptedTurns, diff --git a/src/renderer/src/lib/orca-cloud-transfer-flow.ts b/src/renderer/src/lib/orca-cloud-transfer-flow.ts index 33abb1374a5..843b85cdbe9 100644 --- a/src/renderer/src/lib/orca-cloud-transfer-flow.ts +++ b/src/renderer/src/lib/orca-cloud-transfer-flow.ts @@ -3,6 +3,7 @@ // branch), apply the uncommitted work and chats, then open it. The cloud workspace is left as is. // Progress, success and failure render in CloudMoveToComputerDialog (orca-cloud-move-store). import { toast } from 'sonner' +import { claimMoveRun, releaseMoveRun } from '@/lib/orca-cloud/orca-cloud-move-run' import { translate } from '@/i18n/i18n' import { useAppStore } from '@/store' import { activateAndRevealWorktree } from '@/lib/workspace/activation/worktree-activation' @@ -28,24 +29,7 @@ const STEP_OF_PHASE: Partial { const api = window.api?.orcaCloudWorkspace // One move at a time: a second click (or a retry racing the first) must not start another pack. - if (!api?.prepareTransferToLocal || inFlightRun !== null) { + if (!api?.prepareTransferToLocal) { + return + } + const run = claimMoveRun() + if (run === null) { return } - const run = ++runCounter - inFlightRun = run const archiveAfter = options.archiveAfter ?? false const startedAt = Date.now() let step: CloudMoveStep = 'packing' @@ -94,9 +80,7 @@ export async function runOrcaCloudTransferToLocal( // Stop waiting: release the guard so Try again works; this run's late results are ignored // except a late success, which still lands as a notice (the workspace really is here). timedOut = true - if (inFlightRun === run) { - inFlightRun = null - } + releaseMoveRun(run) setCloudMoveState({ stage: 'failed', workspaceId, @@ -231,11 +215,7 @@ export async function runOrcaCloudTransferToLocal( } } finally { clearTimeout(timeout) - if (inFlightRun === run) { - inFlightRun = null - } + releaseMoveRun(run) dispose() } } - -export { offerPendingCloudTransfers, reapplyOrcaCloudTransfer } from './orca-cloud-transfer-reapply' diff --git a/src/renderer/src/lib/orca-cloud-transfer-reapply.ts b/src/renderer/src/lib/orca-cloud-transfer-reapply.ts index 6ae0f923000..36f33157f0f 100644 --- a/src/renderer/src/lib/orca-cloud-transfer-reapply.ts +++ b/src/renderer/src/lib/orca-cloud-transfer-reapply.ts @@ -4,7 +4,7 @@ import { toast } from 'sonner' import { translate } from '@/i18n/i18n' import { noteCloudWorkspaceMoved, setCloudMoveState } from '@/lib/orca-cloud/orca-cloud-move-store' import type { CloudTransferPrepared } from '../../../shared/hosted-sandbox/cloud-transfer-api' -import { claimMoveRun, releaseMoveRun } from './orca-cloud-transfer-flow' +import { claimMoveRun, releaseMoveRun } from '@/lib/orca-cloud/orca-cloud-move-run' /** * "Apply changes again": re-applies the saved changes and chats onto the SAME local worktree after diff --git a/src/renderer/src/lib/orca-cloud/orca-cloud-move-run.ts b/src/renderer/src/lib/orca-cloud/orca-cloud-move-run.ts new file mode 100644 index 00000000000..ebe0b35d2ec --- /dev/null +++ b/src/renderer/src/lib/orca-cloud/orca-cloud-move-run.ts @@ -0,0 +1,18 @@ +// One "Move to this computer" (or "Apply changes again") at a time: a second click or a retry +// racing the first must not start another pack or apply. A timed-out run releases it. +let inFlightRun: number | null = null +let runCounter = 0 + +export function claimMoveRun(): number | null { + if (inFlightRun !== null) { + return null + } + inFlightRun = ++runCounter + return inFlightRun +} + +export function releaseMoveRun(run: number): void { + if (inFlightRun === run) { + inFlightRun = null + } +}