fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(preview): stabilize background browser automation - #8981

Open
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture
Open

fix(preview): stabilize background browser automation#8981
maria-rcks wants to merge 9 commits into
pingdotgg:mainfrom
maria-rcks:t3code/fix-browser-automation-capture

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-5.6-sol on behalf of Maria

Background preview webviews now stay inside the compositor viewport while leased, snapshot copy has a 2500ms deadline with replacement recovery outside the debugger semaphore, and broker and overlay budgets reserve response headroom. Recording uses the supported setDisplayMediaRequestHandler and getDisplayMedia path from #8957 with no capturePage warmup, while debugger commands and notifications including screencast-frame acknowledgements drain before guest or window teardown. Verified on Linux x86_64 with 151 desktop, 47 web, and 26 server tests, all four affected typechecks, lint, and git diff --check. The required packaged mac arm64 Electron 43.4.1 and 44.1.0 matrix remains blocked on this host; exact host evidence is Electron 43.4.1 as ELF x86-64 on Linux 6.18.46 x86_64, exiting because libnspr4.so is unavailable, so no mac artifact is attached and maintainer mac validation remains required before merge.


Note

High Risk
Touches app quit, window close, update install, CDP lifecycle, and IPC contract changes for snapshots and recording—core desktop preview paths where races or regressions would be user-visible.

Overview
Hardens desktop preview automation around ordered teardown, bounded captures, and sanitized failures so quit, window close, and webview removal do not race in-flight debugger work or leak secrets into logs.

Shutdown and lifecycle now run preparePreviewTeardown / prepareForWindowTeardown before destroying windows or completing app quit; typed teardown errors block quit, reset quitting, and log structured annotations without raw cause payloads. Update install and main-window close follow the same path.

Preview manager gains phased CDP sessions with in-flight command draining, timeouts for snapshot capture and teardown drains, prepareWebviewRemoval, capture-surface recovery events (subscribeCaptureRecoveries), and IPC prepareWebviewRemoval plus preload onCaptureRecovery. Recording switches from getMediaSourceId / capturePage warmup to a single display-media arm per host session (setDisplayMediaRequestHandler), with arm conflicts surfaced as PreviewRecordingArmConflictError.

Automation snapshot over IPC returns a Success / Failure result with filtered native capture messages instead of throwing; the MCP broker subtracts response headroom from the caller timeout when routing to the desktop host.

Reviewed by Cursor Bugbot for commit 7a896db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize preview background automation with bounded captures and orderly teardown

  • Recording now uses getDisplayMedia with an arm-and-claim model instead of getUserMedia with precomputed source dimensions; startRecording returns void and may fail with PreviewRecordingArmConflictError.
  • Automation snapshots gain bounded capture/drain timeouts, phase-aware control sessions that reject commands during teardown, and automatic capture-surface recovery on failure.
  • Window close, app quit, and update install now wait for prepareForWindowTeardown to drain captures and detach debugger sessions before proceeding; failures block close and log sanitized annotations.
  • Renderer keeps retired capture webviews visible during recovery, tracks compositing readiness via data-preview-compositing, and coordinates retirement through new prepareWebviewRemoval and onCaptureRecovery bridge APIs.
  • Behavioral Change: automation.snapshot IPC returns a Success/Failure result union instead of rejecting; DesktopPreviewRecordingSource removed; startScreencast returns void; new channels PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL and PREVIEW_CAPTURE_RECOVERY_CHANNEL added.

Macroscope summarized 7a896db.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are the same convention issue at two ends of the same path: raw underlying error text is being promoted from cause into caller-visible message/detail payloads instead of normalized, bounded structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/app/DesktopLifecycle.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two runtime-behavior findings in the changed web UI code, both about readiness/capture paths that only work under conditions the desktop app does not guarantee (background-throttled window; agent-driven automation with no user activation).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/browser/browserRecording.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR substantially redesigns preview automation across desktop, renderer, preload, contracts, and server layers, including recording, snapshot recovery, webview replacement, and shutdown behavior. Because existing user paths and IPC contracts change with significant asynchronous lifecycle complexity, human validation is needed.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three findings, all inline: typed Effect error channels are being erased at Promise/Record boundaries instead of being handled inside Effect with the tagged union. The rest of the service work (new PreviewManager interface members declared inline on the Context.Service, namespace imports, Schema.TaggedErrorClass failures with structural attributes and exported Schema.is predicates) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/desktop/src/window/DesktopWindow.ts Outdated
Comment threadapps/desktop/src/ipc/methods/preview.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/desktop/src/app/DesktopLifecycle.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e0a39f. Configure here.

Comment threadapps/desktop/src/window/DesktopWindow.ts
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/desktop/src/preview/Manager.ts
Comment threadapps/desktop/src/preview/Manager.ts Outdated
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx Outdated
Comment threadapps/web/src/browser/ElectronBrowserHost.tsx
Comment threadapps/web/src/browser/HostedBrowserWebview.tsx
Comment threadapps/web/src/components/preview/previewAutomationErrors.ts Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks