sync: port upstream background preview capture, PiP, source-control settings (#4204–#4975) - #192
Conversation
Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit 32af2f0)
…ng (pingdotgg#4665) (cherry picked from commit 80ead5f)
Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit 10bca3f)
(cherry picked from commit 5ba6ef7)
(cherry picked from commit 2919147)
…ingdotgg#4975) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 50871eb)
(cherry picked from commit 72b960f)
…rk behavior The fork's PreviewAutomationBroker returns early for `recordingStop` so a stop artifact never re-targets the caller's browsing tab. Upstream pingdotgg#4397 removed that carve-out and added a test asserting the opposite routing. Keep the fork behavior and its "does not replace the default tab" test, and drop the contradicting upstream case.
|
Important Review skippedToo many files! This PR contains 105 files, which is 5 over the limit of 100. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (105)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3463451520
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| recentlySeenUrls, | ||
| }; | ||
| if (current.serverEpoch !== null && event.serverEpoch !== current.serverEpoch) return current; | ||
| if (event.revision < current.serverRevision) return current; |
There was a problem hiding this comment.
Ignore events already represented by the latest list
When a preview.list response and its corresponding event race across the separate RPC streams, the list can be applied first with the same revision as the delayed event. Accepting equality here reapplies that event; notably, a delayed opened event then overwrites the active tab selected or preserved during reconciliation, even though the authoritative list already included the new tab. Treat revisions equal to current.serverRevision as already incorporated so only strictly newer events are applied.
Useful? React with 👍 / 👎.
| const reconcileSessions = (result: Atom.Type<typeof sessionsAtom>) => { | ||
| if (!AsyncResult.isSuccess(result)) return; | ||
| if (result.value.sessions.length > 0) { | ||
| recoveringUrl = null; | ||
| recoveryId += 1; | ||
| reconcilePreviewServerSessions(threadRef, result.value.sessions); | ||
| return; | ||
| } | ||
|
|
||
| const localSnapshot = readThreadPreviewState(threadRef).snapshot; | ||
| const recoverableUrl = | ||
| localSnapshot && localSnapshot.navStatus._tag !== "Idle" | ||
| ? localSnapshot.navStatus.url | ||
| : null; | ||
| if (!recoverableUrl) { | ||
| applyPreviewServerSnapshot(threadRef, null); | ||
| return; | ||
| } | ||
| if (recoveringUrl === recoverableUrl) return; | ||
|
|
||
| recoveringUrl = recoverableUrl; | ||
| const currentRecoveryId = ++recoveryId; | ||
| void runAtomCommand( | ||
| get.registry, | ||
| previewEnvironment.open, | ||
| { | ||
| environmentId: threadRef.environmentId, | ||
| input: { threadId: threadRef.threadId, url: recoverableUrl }, | ||
| }, | ||
| { reportDefect: false, reportFailure: false }, | ||
| ).then((openResult) => { | ||
| if (disposed || currentRecoveryId !== recoveryId) return; | ||
| recoveringUrl = null; | ||
| if (openResult._tag === "Failure") return; | ||
| applyPreviewServerSnapshot(threadRef, openResult.value); | ||
| get.refresh(sessionsAtom); | ||
| }); | ||
| reconcilePreviewServerSessions(threadRef, result.value); |
There was a problem hiding this comment.
Recreate the active preview after a server restart
When the backend restarts, the new in-memory preview manager returns an empty list with a new serverEpoch; unconditionally reconciling that result now clears every local session and unmounts the still-running Electron webview. The removed code reopened the active recoverable URL with a fresh server tab, so ordinary backend restarts now discard the user's preview instead of safely remapping it to the new epoch. Restore that recovery without reusing the old raw tab ID.
AGENTS.md reference: AGENTS.md:L20-L25
Useful? React with 👍 / 👎.
| const changeRequestTemplate = | ||
| settings.style.followChangeRequestTemplates && provider.kind === "github" | ||
| ? Option.getOrUndefined(yield* detectPrTemplate(cwd, baseRangeRef, gitCore.execute)) | ||
| : undefined; |
There was a problem hiding this comment.
Honor change-request templates for GitLab repositories
When the detected provider is GitLab, this condition always suppresses template detection even though GitLab change requests are supported and the new setting is presented as the provider-neutral “Follow change request templates.” Consequently, repositories using GitLab merge-request templates always receive the generic generated body while the setting appears enabled. Dispatch to provider-specific template detection, including GitLab's merge-request template locations, rather than restricting the feature to GitHub.
Useful? React with 👍 / 👎.
L3/7 of the 2026-07-30 upstream sync stack. Stacked on #191.
What lands
Fork deviations preserved
browserRecording.ts: upstream restructured single-recording → per-tabactiveRecordingsfor PiP (376 changed lines vs the fork's 79). Took upstream's file and re-applied the fork's two surviving deltas — a rejectablestartupSettled(so a real startup failure reaches pending stops instead of resolving them as success) and the narrowedisStartupWaitTimeoutthat distinguishes a genuine timeout from a propagated failure. These two are coupled. Upstream independently converged on the fork's removal of the "requires visible tab" guard.PreviewAutomationBroker: kept the fork'srecordingStopearly return andevaluatecarve-out. Upstream's contradicting "tracks the tab returned by a targeted recording stop" test is dropped in favour of the fork's "does not replace the default tab" test.build-desktop-artifact.ts: upstream unpacks only on Windows. Kept the bundled Copilot CLI unpacked on every platform —resolveBundledCopilotCliPathprobesapp.asar.unpacked/node_modules/@github/copilot-*for a spawnable binary, so packing it would break the fork's Copilot driver on macOS/Linux.CursorTextGeneration: kept the fork'sTextGenerationShapetyping while adopting upstream'spolicy/changeRequestTemplateplumbing.Verification
vp run typecheckandvp checkpass;browserRecording15/15 andbuild-desktop-artifact28/28 green.