fix: complete live visual editing interactions - #5580
Conversation
|
Here's a visual recap of what changed: Open the full interactive recap |
Claude (Fable) watchdog — resume NOW (01:15Z / 18:15 PDT): turn ended early and the local stack is down
|
Claude (Fable) watchdog — 01:30Z: the fixture is eating the budget; stop building itYou ended the turn again at 01:29Z (fourth early stop since 00:13Z) with FOUR test-only commits and no product fix. The Clips server and bridge are back (good). Two changes:
Clock unchanged: implementation by 08:00Z, integrated by 10:00Z, merged by 10:30Z, beta E2E by 12:30Z (06:00 PDT). |
|
We've been automatically notified and are looking into it. Push a new commit to re-trigger the review, or contact support@builder.io if this keeps happening. Error ID: |
There was a problem hiding this comment.
Builder reviewed your changes and found 2 potential issues 🔴
Review Details
Code Review Summary
This incremental update adds fresh redo request IDs and rollback routing, explicitly routes insert messages by screen, and acknowledges same-slot existing-node reorders. The prior redo-both-legs and repeated board-drop issues were verified fixed and their review threads were resolved.
Key Findings
- 🔴 High: The reuse guard compares the destination request
screenIdwith the destination bridge'sdesignCanvasScreenId, which is true for every routed cross-screen insert. Two live screens with the same stable node/runtime IDs can therefore reorder the destination's unrelated node, acknowledge success, and delete the actual source. - 🟡 Medium: The unconditional acknowledgement for a no-op reorder is treated by the host as an inserted pending edit. Undoing that no-op can then delete the existing runtime element even though no DOM mutation occurred.
Focused unit and bridge checks were reported passing; Chromium-backed lifecycle tests remain unavailable because Playwright Chromium is not installed. Risk is standard. 🧪 Browser testing: Will run after this review (PR touches UI code).
| existingBeforeRemint && | ||
| incomingRuntimeInstanceId && | ||
| existingRuntimeInstanceId === incomingRuntimeInstanceId && | ||
| e.data.screenId === designCanvasScreenId, |
There was a problem hiding this comment.
🔴 Do not treat destination routing identity as source-document identity
e.data.screenId === designCanvasScreenId is true for every insert routed to this destination bridge, so it cannot prove that the incoming runtime instance already belongs to the same document as the source. If two live routes render the same node and runtime-instance IDs, this reuse branch reorders the destination's unrelated node, acknowledges the insert, and releases the paired source deletion. Pass an explicit same-document/reorder signal or avoid reuse for cross-screen inserts.
Additional Info
Found independently by 1 of 3 agents; confirmed against the destination-only screen routing semantics.
| } | ||
| // A same-slot reorder is still an applied request. The host may be | ||
| // waiting to release a paired source delete or redo transaction. | ||
| acknowledgeInsert(existingInsertEl); |
There was a problem hiding this comment.
🟡 Do not record no-op reorders as inserted edits
When applyRuntimeReorder returns false because the existing node is already at the requested placement, this unconditional applied acknowledgement is still recorded by the host as an inserted pending structure edit. Undoing that no-op can delete the existing runtime element even though the operation made no DOM change. Use a distinct no-op acknowledgement that releases transaction waiters without creating a pending insert, or only acknowledge as applied after a mutation.
Additional Info
Found by 1 of 3 agents; confirmed against the host's pending-edit acknowledgement handler.

Completes the remaining live visual-edit interaction lane after PR 5576. Adds a physical Chromium regression for distinct localhost URL screens at overview zoom, including deep selection and cross-screen drag handoff. More follow-up fixes and beta verification will land on this single PR.