fix(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc
, '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(web): roll back timed-out preview resizes - #4341

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback
Closed

fix(web): roll back timed-out preview resizes#4341
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-3712-preview-resize-rollback

Conversation

@nateEc

@nateEcnateEc commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Capture the active preview viewport before applying an automation resize.
  • Restore the previous server snapshot and rendered viewport when the requested viewport times out.
  • Preserve the original timeout if the best-effort rollback also fails.

Why

A timed-out preview_resize request updated the declared viewport before rendering completed, leaving preview_status and the live webview internally inconsistent.

Closes#3712

UI Changes

No visual redesign. Failed automation resizes now return to the prior viewport instead of leaving partial state. The isolated web app pass authenticated and created a real thread successfully; the Browser surface is Electron-only and is intentionally unavailable in the web-only runner.

Checklist

  • Focused transaction tests pass
  • Web typecheck passes
  • Targeted lint and formatting pass
  • Isolated test-t3-app smoke pass completed

Note

Medium Risk
Changes preview automation resize semantics (rollback + serialization) in Electron-only paths; behavior is well-tested but affects automation status/viewport consistency on failure.

Overview
Preview automation resize no longer leaves a stale declared viewport when rendering times out. The handler now records the tab’s current viewport (or FILL_PREVIEW_VIEWPORT), runs the resize through a per-tab transaction queue, and on waitForRenderedViewport failure reapplies that prior setting to the server snapshot and waits briefly (up to 2s) for rollback to render—while still surfacing the original timeout if rollback fails.

New helpers in previewResizeTransaction.ts implement the rollback transaction and serialize concurrent resizes per environmentId:threadId:tabId key; unit tests cover success, rollback on timeout, and queue behavior.

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

Note

Roll back timed-out preview viewport resizes to their previous setting

  • Introduces resizePreviewViewportTransaction in previewResizeTransaction.ts which applies a viewport setting, waits for it to render, and on timeout attempts a best-effort rollback to the previous setting (capped at 2000ms), preserving the original error if rollback also fails.
  • Adds createPreviewResizeTransactionQueue to serialize resize operations per preview tab (keyed by environment, thread, and tab ID), preventing concurrent conflicting resizes on the same tab.
  • Updates PreviewAutomationHost to wrap resize handling in the transaction queue and pass rollback context (previous setting defaulting to FILL_PREVIEW_VIEWPORT).
  • Behavioral Change: resize operations that previously fired-and-forgot on timeout now attempt rollback; concurrent resizes on the same tab are now serialized rather than running in parallel.

Macroscope summarized 584eaa3.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e273cda8-fe7e-40c8-a52c-267e60a20e6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/web/src/components/preview/PreviewAutomationHosts.tsx Outdated
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new transaction queue and automatic rollback behavior for preview resize timeouts. While well-tested, this adds meaningful runtime behavioral changes to preview automation infrastructure that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

nateEc added 2 commits July 24, 2026 14:28
- Apply preview viewport changes as a transaction with the previous setting captured first.
- Restore the prior server snapshot and rendered viewport after a resize timeout.
- Cover successful resize, timeout rollback, and rollback failure behavior.
- Serialize resize and rollback work per preview tab.
- Read the rollback viewport only after the transaction acquires its tab lock.
- Preserve parallel resizing across different tabs and add focused concurrency coverage.
@nateEc
nateEcforce-pushed the codex/fix-3712-preview-resize-rollback branch from bf2cd3e to 584eaa3CompareJuly 24, 2026 06:35

@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 584eaa3. Configure here.

await input.waitForViewport(
input.previousSetting,
Math.min(input.timeoutMs, MAX_ROLLBACK_WAIT_MS),
);

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.

Stale rollback overwrites intervening resize

Medium Severity

The resizePreviewViewportTransaction's rollback, triggered by a viewport render timeout, uses a stale previousSetting. This can overwrite intervening manual user viewport changes, reverting the server and local snapshot to an outdated state.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 584eaa3. Configure here.

@nateEc

Copy link
Copy Markdown
ContributorAuthor

Closing this PR because it has been superseded by #4661. Current main serializes viewport mutations and only rolls back when the timed-out request still owns the latest setting and the preview server epoch is unchanged. That also addresses the unresolved stale-rollback review concern on this PR, with focused coverage in previewViewportRollback.test.ts.

@nateEcnateEc closed this Aug 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preview_resize times out and leaves viewport state internally inconsistent

1 participant

@nateEc