Agentic UI: Allow cancelling an in-flight push or pull - #4510
Conversation
📊 Performance Test ResultsComparing abdec3a vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
| enabled, | ||
| label: enabled | ||
| ? __( 'Cancel pull' ) | ||
| : __( 'Pull can not be cancelled while importing changes to your local site' ), |
katinthehatsite
left a comment
There was a problem hiding this comment.
Generally, the changes look good to me 👍
I noticed one thing:
- start and cancel push
- observe the the header says
Push cancelled - wait for a couple of minutes
- observe that the header now says
Pushed 2 mins agoeven though the push was cancelled
I am wondering if the Pushed 2 mins ago should appear in this case at all, what do you think?
At the moment it is preserving whatever message it was before the push/cancel. Cancel does not update it? Was that the behavior you saw? I pushed some fixes, can you take another look please? |
So what seems to happen is that if you push, it shows the pushed x amount of time ago, then you try to push again and cancel, it will show |
| */ | ||
| const SYNC_ABORT_CONTROLLERS = new Map< string, AbortController >(); | ||
|
|
||
| // Agentic push/pull resolve with this instead of rejecting when the user cancels. |
There was a problem hiding this comment.
I think the type below is pretty self-explanatory
| remoteSiteId: number; | ||
| }; | ||
|
|
||
| // Stopping is best-effort: the push/pull mutation itself rejects with a |
There was a problem hiding this comment.
I think this can also be removed as it is already visible from the code
| remoteSiteId, | ||
| } ); | ||
| } | ||
| // See `pullSiteFromLive` — same registry, so `cancelSyncOperation` covers both UIs. |
There was a problem hiding this comment.
the template literal on the next line already shows this, I think
| { sitePath: site.path, remoteSiteId, options, signal: release.signal } | ||
| ); | ||
| } catch ( error ) { | ||
| // See the pull route — a cancel is reported, not raised as a 500. |
There was a problem hiding this comment.
The comment restates the code pattern so I would drop it as well
katinthehatsite
left a comment
There was a problem hiding this comment.
I think the functionality works as expected 👍 I left some minor suggestions regarding cleaning up the comments.
…ncel # Conflicts: # apps/ui/src/components/site-dropdown/main-view.tsx
…te (#4522) ## Related issues - Fixes STU-2243 - Stacked on #4510 — review that one first; this PR targets its branch and will retarget to `trunk` once it lands. ## How AI was used in this PR Written with Claude Code, after tracing how the classic renderer handles the same flow. ## Proposed Changes A push now stays in progress until the live site has actually been updated. Previously it announced "Push complete" as soon as the archive finished uploading, while WordPress.com was still taking its safety backup and importing — so the app looked done, the live site wasn't, and a second push failed with "another import is already in progress". The push also stops reading as idle. Instead of showing "Preparing the live site…" for its whole duration, it names the phase it's in and how far along it is: creating the backup, uploading, backing up the remote site, applying changes, almost there — the same wording the classic UI uses. Failures now say what went wrong, distinguishing a failed database import from a timeout on a too-large site. Cancelling is unaffected: a push is still stoppable until the remote import starts, and refused after. ## Testing Instructions 1. Connect a site to WordPress.com and push it from the site dropdown. Use a site large enough that the remote backup takes a moment. 2. The dropdown should step through the phases with percentages, and **not** toast "Push complete" when the upload finishes. 3. Confirm the live site reflects the change by the time the toast appears. 4. Start a second push immediately after the first completes — it should not fail with "another import is already in progress". 5. Cancel a push during "Creating backup…"/upload — still works; once it reaches "Backing up remote site…" the X is dimmed. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors?

Related issues
How AI was used in this PR
Written with Claude Code, then verified end to end against real pushes and pulls
Proposed Changes
You can now stop an in-flight sync from the site dropdown, with the same boundary Classic uses: a push can be cancelled until the remote import is initiated, a pull until the CLI starts writing your local site. Past that point the button is disabled and the panel says why, because stopping there would leave a half-imported site. Cancelling reports "Push/Pull cancelled" rather than an error, and is logged as such.
Testing Instructions
[Sync] Pull cancelled by userwith no error.studioCLI process survives a cancel (ps aux | grep "main.mjs pull").Pre-merge Checklist