Skip to content

fix(cmux-next): keep hidden WebViews out of scene captures - #17370

Merged
teamleaderleo merged 16 commits into
feat-cmux-nextfrom
fix/scene-compositing-v17
Oct 10, 2026
Merged

teamleaderleo merged 16 commits into
feat-cmux-nextfrom
fix/scene-compositing-v17

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

The v16 scene captures composited a parked Home WebView over the active Agent pane because the native base hid only selected pages. Composer and hint captures also froze a picker during its fade, and the sidebar scene restored width without selecting the tray look.

This follow-up to #17361 now hides every WKWebView while drawing the native base, snapshots only visible views with effective alpha, uses precomputed window coordinates in view order, waits for menu animations to finish, and selects the real tray look for sidebar-tiles. The render script fails closed if a manifest entry reports a hidden WebView composited.

Validation:

  • git diff --check
  • bash -n scripts/cmux-next/render-scenes.sh
  • exact-head fleet build and real seven-scene capture will be attached before merge

Follow-up to #17361.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Keeps hidden WebViews, parked tabs, and mid-animation menus out of scene captures so screenshots match what users see.

Merging base replaced this branch's hidden-WebView compositing: DebugWindowSnapshot now captures from the window server's image and paints only visible WebViews in the AppKit fallback. The scene validation kept here awaits menu animations before snapping, closes leftover menus, and render-scenes.sh exits when a visible WebView fails to snapshot.

Written for commit 3ac8774. Summary will update on new commits.

View guided diff Turn on auto-fix


Note

Medium Risk
Changes span debug capture timing, cmux-next job routing and merge gates, and post-publish manifest verification retries—any regression could block PRs or mis-attribute tree binaries, while capture fixes affect automation evidence only.

Overview
Scene capture reliability is tightened so automation screenshots match on-screen UI: captures wait for menu animations to finish, reset sidebar look per scene (sidebar-tiles uses tray; others use quiet), close stray menus before snapshotting, and render-scenes.sh fails if a scene reports failed/hidden WebView compositing.

cmux-next / cmux-tui CI adds a Swift canary job (Debug swift build of touched CmuxNext production targets) as the PR gate for small package-only Swift diffs, with full Release compile advisory on that class; changed-package cargo fmt --check for cmux-tui in cmux-tui-spec.yml; PRs that do not touch cmux-tui/ghostty-next can run daemon/scheme jobs on the newest published tree via CMUX_TUI_TREE_BASE_FALLBACK / tree_fetch_key; bot attempt 4 drops side-lane placement for overflow; gallery PR workflow adds narrow+normal widths, 4-way sharding, and merge of shard results.

Tooling / release: pre-commit formats staged webviews (vp) and cmux-tui Rust (rustfmt); published manifest verification retries remote binary digest reads with cache-bust URLs; nightly release notes step gets a 10-minute cap; docs add UI reference sources and tier/canary notes.

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

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 49938fa0-1811-4c3f-9f1a-e4f0173bd859

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
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Leaving open as an active scene-capture follow-up. It needs a fresh base update after the current capture lane settles.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Leaving this open: the live cx-pane-composer-2 lane owns the scene-capture follow-up, so this work is still active.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Batch queue: dropped from this batch, conflict.

  • Packages/macOS/CmuxNext/Sources/CmuxNextApp/Control/DebugAgentPane.swift: both sides changed it
  • Packages/macOS/CmuxNext/Sources/CmuxNextApp/Control/DebugWindowSnapshot.swift: both sides changed it

Next: merge feat-cmux-next, resolve, push.

@cursor

cursor Bot commented Oct 6, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

I pushed merge commit e1b27246a6cf while mistakenly sweeping beyond my assigned lane. Please review these two conflict resolutions:

  • DebugAgentPane.swift: combined the action list, retaining close_menus and the newer click and gesture_state entries.
  • DebugWindowSnapshot.swift: retained this branch’s webViewTargets collection and compositing flow, and retained the base’s accessible visibleWebViews(in:) helper, including its hidden/transparent ancestor filtering, for the existing snapshot tests.

I did not run scoped Swift tests for this resolution or merge the PR. The owner should validate the combined snapshot behavior before landing.

teamleaderleo and others added 11 commits October 9, 2026 19:28
* ci: format staged files in the trusted pre-commit hook

* ci: guard formatter scope for staged files

* ci: scope Rust formatter guard to its package

* ci: use direct rustfmt and skip merge formatting

* ci: pass the cmux-tui Rust edition to rustfmt
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch

PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: check rustfmt on the cmux-tui packages a PR touches

PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit

The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(cmux-tui): leave the relay circuit to its own repair

Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next

* ci: remove unit tests from Swift canary change
…e cmux-tui (#18698)

* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree

#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui

Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cmux-next): the newest-published search deepens only this commit's history

A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(cmux-next): map UI parity reference sources

* docs(cmux-next): add media preview reference source

* docs(cmux-next): define reference freshness checks
* test(nightly): the notes step cannot spend the publish budget before the upload (red)

Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(nightly): bound the publish notes step at 10 minutes

The notes take seconds since 0115b26. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…self (#17622)

* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself

Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cmux-next): the tree gate watches the base and may pin the tree

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree

When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cmux-tui): a transient wrong binary read must not fail publication

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cmux-tui): read a mismatched published binary again before failing

R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cmux-next): a pull request gate pins a tree its base never builds

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(cmux-next): a pull request gate pins a tree its base never builds

A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(cmux-next): retain base tree dispatch tests

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states

* test(gallery): cover workflow matrix changes

* fix(gallery): dedupe equal responsive widths

* ci: shard gallery matrix renders

* ci: retrigger sharded gallery validation
DebugWindowSnapshot.swift takes base's version: base now snapshots from
the window server's image (bee060d, cx-ddjj) and only paints visible
WebViews in the AppKit fallback, which supersedes this branch's hidden-WebView
compositing. render-scenes.sh drops the webviews_hidden_composited check
(base no longer reports it) and keeps the error/webviews_failed checks.
DebugAgentPane keeps both close_menus and base's inspector action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@blacksmith-sh

blacksmith-sh Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_every_reused_workspace_checkout_retries_once_from_a_fresh_repository (main.Cmu
xNextCheckoutRetryTests.test_every_reused_workspace_checkout_retries_once_from_a_fresh_
repository) (job='swift-canary')/
test_every_reused_workspace_checkout_retries_once_from_a_fresh_repository (main.Cmu
xNextCheckoutRetryTests.test_every_reused_workspace_checkout_retries_once_from_a_fresh_
repository) (job='swift-canary')
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@github-actions

Copy link
Copy Markdown
Contributor

Not verified: macOS jobs did not run: compile and app tests were skipped on 3ac87745b0; ci-status is green without them.

CI passes on 3ac87745b0 (run 38017507188 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 default effort and found 3 potential issues.

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 3ac8774. Configure here.

composer_text_length: (composer?.innerText || '').trim().length,
document_ready: document.readyState === 'complete'
document_ready: document.readyState === 'complete',
animations_pending: animationsPending

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Animation wait flag never reaches page

High Severity

readiness accepts waitForAnimations and the injected script reads that name, but callAsyncJavaScript is invoked with an empty arguments dictionary. The page then throws a ReferenceError, so every scene's post-action readiness check fails and capture aborts before a snapshot.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3ac8774. Configure here.

timeout-minutes: 20
env:
CMUX_NEXT_RUNNER: ${{ needs.macos-placement.outputs.runner || github.repository_owner != 'manaflow-ai' && 'macos-26' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'blacksmith-6vcpu-macos-26' || vars.CI_PR_POOL_OWNED == '1' && contains(fromJSON('["pull_request","push","workflow_dispatch"]'), github.event_name) && (github.run_attempt <= 2 || github.triggering_actor != 'github-actions[bot]') && vars.CI_SIDE_LANE_RUNNER || vars.MACOS_RUNNER_26 || 'blacksmith-6vcpu-macos-26') }}
SWIFT_CANARY_TARGETS: ${{ needs.path_route.outputs.swift_canary_targets }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Canary job skips overflow reroute

Medium Severity

swift-canary is now placed with the other Mac jobs, but its runs-on still prefers macos-placement's runner on every attempt. A bot attempt 4 therefore stays on a mini that already refused the job, and test_every_mac_job_reads_the_placement fails because the test JOBS list was not updated.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3ac8774. Configure here.

Comment thread scripts/gh-merge-green
esac
done <<<"$next_verdicts"
for next_check in \
"cmux-next Swift canary" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Advisory Release compile still blocks merge

Medium Severity

Package-only Swift PRs mark Release compile as continue-on-error so the canary can be the gate, but gh-merge-green still adds cmux-next Release compile (Xcode 26) to must whenever that job appears. A diagnostic Release failure still refuses the merge.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3ac8774. Configure here.

@teamleaderleo
teamleaderleo merged commit b925da8 into feat-cmux-next Oct 10, 2026
87 of 106 checks passed
@teamleaderleo
teamleaderleo deleted the fix/scene-compositing-v17 branch October 10, 2026 03:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants