fix: let a move be retried after its conflicts are resolved

- Move stays enabled while the dialog lists conflicts; confirming re-reads
  them, so a draft discarded in the fork meanwhile no longer blocks it.
- A dialog left open while another tab moved the session closes instead of
  moving from the old workspace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Guilhem Lemouel
2026-10-26 09:28:17 -07:00
co-authored by Claude Opus 5.5
parent 29b085f733
commit 8b5b386609
2 changed files with 24 additions and 13 deletions
@@ -42,7 +42,6 @@
type="info"
alwaysPortal
{loading}
confirmDisabled={conflicts.length > 0}
{onConfirmed}
{onCanceled}
>
@@ -79,7 +78,8 @@
</div>
{#if conflicts.length > 0}
<p class="text-xs text-red-600 dark:text-red-400">
You already have drafts of the highlighted items in {targetName}. Discard them there first.
You already have drafts of the highlighted items in {targetName}. Discard them there, then
move again.
</p>
{:else if error}
<p class="text-xs text-red-600 dark:text-red-400">{error}</p>
@@ -492,6 +492,12 @@
async function confirmMove() {
const req = moveRequest
if (!session || !req || moving) return
// Another tab moved the session while this dialog was open.
if (actingWorkspaceId !== req.parent) {
moveRequest = undefined
sendUserToast('This session moved to another workspace meanwhile. Pick the fork again.', true)
return
}
moving = true
const releaseAutoResume = runtime?.manager.holdAutoResume()
// Bracketed like a turn, so another tab on this session cannot send while its drafts
@@ -500,18 +506,23 @@
if (chatId) localRunStarted(session.id, chatId)
try {
// A turn that ran while the dialog was open (a job's auto-resume, another tab) may have
// added drafts the list does not show. Now that no turn can start, it is re-read.
// added drafts the list does not show, and the conflicts listed may have been discarded
// since. Now that no turn can start, both are re-read.
const listed = await listMoveItems(req.parent, req.target)
if (typeof listed === 'string' || itemKeys(listed.items) !== itemKeys(req.items)) {
moveRequest =
typeof listed === 'string'
? { ...req, open: true, error: listed }
: {
...req,
...listed,
open: true,
error: "This session's drafts changed. Check the list and confirm again."
}
if (typeof listed === 'string') {
moveRequest = { ...req, open: true, error: listed }
return
}
const changed = itemKeys(listed.items) !== itemKeys(req.items)
if (changed || listed.conflicts.length > 0) {
moveRequest = {
...req,
...listed,
open: true,
error: changed
? "This session's drafts changed. Check the list and confirm again."
: undefined
}
return
}
const res = await moveSessionToFork(session.id, req.parent, req.target, {