Skip to content

fix(cloud): isolate sidebar row hover targets - #18693

Merged
austinywang merged 7 commits into
mainfrom
task-18689-cloud-hover-target
Oct 10, 2026
Merged

austinywang merged 7 commits into
mainfrom
task-18689-cloud-hover-target

Conversation

@austinywang

@austinywang austinywang commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Hovering New Cloud Machine in the Cloud Machines sidebar could highlight the OpenCode row instead of the view under the pointer.

Fix

Cloud tree hover now asks AppKit which view owns the window-space pointer before assigning a row. The shared cmuxHitTest(windowPoint:) path supplies the superview-space coordinate required by both unflipped AppKit and flipped SwiftUI content hosts. Hover refresh also keeps NSWindow.mouseLocationOutsideOfEventStream in its native window coordinate space, so a moved window cannot remap the pointer to another row. Menu-pinned and native-drag hover ownership still take precedence, while selection and row action rendering remain unchanged.

Validation

  • python3 scripts/verify-local.py --affected origin/main --swift-changed — passed the affected localization-defaults, app-source wiring, test-wiring, and feature-flag checks.
  • python3 scripts/verify-local.py --only swift-syntax --swift Sources/Cloud/CloudTreeNSOutlineView.swift cmuxTests/CloudTreeHeaderActionsTests.swift — passed.
  • ./scripts/sync-test-wiring --check and git diff --check — passed.
  • Focused hosted run 37873929934 on a8012ed2efd29ad134def4d3c3037deb5046b291 passed all 11 CloudTreeHeaderActionsTests tests, including flipped and unflipped overlapping-sibling ownership and the moved-window refresh regression.
  • Red-before evidence: focused run 37865127155 on 3aae873669b2d6f0f57f409bec3e6c9aaa344647 failed the flipped-host cases before the hit-test coordinate repair; the same selector is green above on the repaired head.
  • The moved-window regression also failed all three refresh assertions at cba9556f8a579752842f0cffc17de785ca6386be in run 37871570864. Both red runs and the final green run use scripts/run-e2e.sh cmuxTests/CloudTreeHeaderActionsTests --ref <sha> --no-video.
  • Exact-head tagged non-launching fleet build ce5741e90058c9ecca9f78dc passed on cmux10s-Mac-mini.local with tag issue-18689-cloud-hover-docs, local backend mode, and artifact digest sha256:8a4c316d04225a07bdae6f1eabf54aa186538726a31b97acec74abab1ef401a7; workspace cleanup completed. HQ publication returned HTTP 502, so no HQ download link is available.
  • Final-head macOS compile admission passed. The first attempt of the broader changed-suite lane in run 37873859085 crashed during Xcode test enumeration (IDELaunchServicesLauncher, childPID > 0) before tests ran; rerun attempt 2 passed.
  • No interactive app launch or UI capture was performed: this PR has no dev-build label, and the workflow's optional dogfood proof is therefore skipped.

Changelog

Fixed: Cloud sidebar hover stays with the row that owns the pointer.

Issues

Fixes #18689
Related: #16385

Issue lifecycle

Impact map

  • Source of truth: CloudTreeNSOutlineView owns one hover target and the AppKit window-space hit-test boundary; CloudTreeCellView and CloudTreeCreateActionView continue to render the existing shared row/action states.
  • Adjacent paths inspected: New Workspace, New Cloud Machine, My Devices/provider/account rows, row descendants, keyboard selection, menu pinning, and native drag lifting; no action routing or localized strings changed.
  • Cross-surface effects: only transient pointer ownership and refresh coordinate conversion changed. Pressed/disabled states, light/dark colors, localization, selection, accessibility, and create actions remain on their existing paths.
  • Regression coverage: CloudTreeHeaderActionsTests exercises sibling hit-target isolation in both host orientations plus refresh after a moved window origin; the exact hosted run executed all 11 cases.
  • Read-only correctness review of the repair found no concrete defects; the final follow-up adds only a regression-test doc comment.
  • Residual limit: the test uses native AppKit event injection rather than a full interactive dogfood tour; the exact-head tagged app build passed without launch.

Mergeability

  • Base SHA: ce6be93cf232b381befbfcac8ff107f14fd40a02
  • Head SHA: a8012ed2efd29ad134def4d3c3037deb5046b291
  • Conflict-only gate: pass (merge-gate.sh --conflict-only)

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0ba43cfa-dee8-4298-969e-5a92de5c400f
📥 Commits

Reviewing files that changed from the base of the PR and between 0d53ad8 and a8012ed.

📒 Files selected for processing (1)
  • cmuxTests/CloudTreeHeaderActionsTests.swift

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

Cloud outline hover updates now require the pointer’s resolved hit target to belong to the outline. Hover refresh uses window coordinates. Tests cover overlapping sibling views and pointer movement in flipped and unflipped hosts.

Changes

Cloud sidebar hover

Layer / File(s) Summary
Outline hit-target ownership
Sources/Cloud/CloudTreeNSOutlineView.swift
Hover updates check whether hit testing resolves the pointer to the outline or one of its descendants. Hover refresh uses the window’s pointer location directly.
Hover regression coverage
cmuxTests/CloudTreeHeaderActionsTests.swift
Tests cover overlapping sibling hit targets in flipped and unflipped hosts and window-coordinate pointer locations. The test helper can deliver mouse-move events at explicit window points.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: lucasr1b

Merge Risk: ⚪ Minimal · up to a8012

The focused hover tests and reported validation passed. The available evidence supports merging without a specific outstanding behavior risk.

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Linked Issues check Passed Issue #18689 requires a shared hover-target fix and focused regression coverage. CloudTreeNSOutlineView.updateHover now uses AppKit hit testing and does not assign an outline row when an overlapping…
Out of Scope Changes check Passed The changes stay within issue #18689. Source changes update Cloud sidebar hover ownership and coordinate refresh. Test changes cover the related hover regressions and preserve selection behavior. No u…
Docstring Coverage Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files.
Cmux Cloud Persistent Session And Early Input Passed PASS: The pull request changes only Cloud sidebar hover hit-testing, window-coordinate refresh, and related tests. The diff introduces no Cloud terminal creation, cmux-tui client, transport, PTY readi…
Cmux Swift Actor Isolation Passed PASS. The production diff changes only CloudTreeNSOutlineView, an AppKit UI type, by adding window hit-testing and adjusting pointer-coordinate handling. It adds no model structs, service protocols,…
Cmux Swift Blocking Runtime Passed The production diff only adds AppKit hit testing and preserves native window coordinates. It introduces no semaphores, blocking waits, sleeps, delayed dispatch, polling, main-queue synchronization, or…
Cmux Browser Automation Off-Main Passed The pull request changes only Cloud sidebar hover code and its tests. The authoritative diff does not modify Sources/TerminalController.swift, ControlCommandExecutionPolicy.swift, or worker browse…
Cmux Expensive Synchronous Load Passed PASS. The production diff only adds AppKit hit testing and changes window-coordinate handling in CloudTreeNSOutlineView; it adds no agent-history loader, file read, JSON/JSONL parsing, directory sca…
Cmux Cache Substitution Correctness Passed The diff changes transient Cloud sidebar hover ownership and window-coordinate pointer refresh only. It does not replace an authoritative persistence, history, undo, or snapshot read with a cached or …
Cmux No Hacky Sleeps Passed PASS: The pull request changes only Sources/Cloud/CloudTreeNSOutlineView.swift and cmuxTests/CloudTreeHeaderActionsTests.swift. The check applies only to production non-Swift TypeScript, JavaScrip…
Cmux Algorithmic Complexity Passed PASS: The production diff adds one AppKit hit test and an ancestor check per hover update. It does not add nested scans, repeated sorting/filtering, batch rescans, or in-memory joins over scalable use…
Cmux Swift Concurrency Passed PASS: The pull-request diff adds AppKit hit testing, coordinate conversion, synchronous hover logic, and synchronous XCTest coverage. It adds no Dispatch queues, Combine state, completion-handler APIs…
Cmux Swift @Concurrent Passed The pull request changes only synchronous hover hit-testing, coordinate conversion, and synchronous test helpers. It introduces no async, nonisolated async, or @concurrent declaration or call-si…
Cmux Swift Package Boundaries Passed PASS: The only production change is in CloudTreeNSOutlineView, an AppKit UI class. It adds pointer ownership checks and window-coordinate hover refresh using NSView.cmuxHitTest; this is UI/AppKit …
Cmux Swiftpm Lockfiles Passed The pull request changes only Sources/Cloud/CloudTreeNSOutlineView.swift and cmuxTests/CloudTreeHeaderActionsTests.swift. It does not change a SwiftPM package, Package.resolved, an Xcode project…
Cmux Swift Logging Passed PASS. The Swift diff adds hit-testing and coordinate handling in CloudTreeNSOutlineView.swift plus regression tests. It adds no print, debugPrint, dump, NSLog, file/stdout diagnostics, `Logg…
Cmux User-Facing Error Privacy Passed PASS — The production diff changes Cloud sidebar hover hit-testing and window-coordinate handling only. It adds no user-facing error, alert, command output, API error body, or recovery copy. The added…
Cmux Full Internationalization Passed The production diff changes hover hit testing and window-coordinate handling only. It adds no user-facing Swift text, localization key, string catalog entry, web text, or metadata. Added prose is deve…
Cmux Swiftui State Layout Passed No prohibited SwiftUI state or layout pattern is introduced. The production diff changes CloudTreeNSOutlineView, an NSOutlineView AppKit bridge, and adds hit testing plus window-coordinate handlin…
Cmux Architecture Rethink Passed The diff is a small local correctness fix. CloudTreeNSOutlineView remains the single hover owner, and the new pointerHitTargetBelongsToOutline helper enforces the explicit hit-target invariant thr…
Cmux Swift Auxiliary Window Close Shortcuts Passed The PR does not add or materially change a standalone production window. CloudTreeNSOutlineView.swift only reads its existing containing NSWindow for hover calculations. The new `HoverLocationWind…
Cmux Source Artifacts Passed The PR changes only Sources/Cloud/CloudTreeNSOutlineView.swift and cmuxTests/CloudTreeHeaderActionsTests.swift. The diff contains hand-written Swift source and focused tests. No logs, screenshots,…
Cmux No Test Or Debug Seam In Production Source Passed The production diff only adds a private pointerHitTargetBelongsToOutline(at:) helper and changes hover coordinate handling. It adds no #if DEBUG or test-build guard, no test/debug-named production…
Title check Passed The title clearly and concisely describes the main change: isolating Cloud sidebar row hover targets.
Description check Passed The description clearly explains the problem, fix, validation results, changelog entry, issue context, impact, and remaining verification limits. It does not use every template heading, such as an exp…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · 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.

@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 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 61fcba8. Configure here.

Comment thread Sources/Cloud/CloudTreeNSOutlineView.swift
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Dogfood tours of a8012ed2

cloud-machine-author-tour at a8012ed2, on its merge 014cfbf6 that CI built: failure (run)

cloud-machine-author-tour at a8012ed2

Key frames of cloud-machine-author-tour at a8012ed 04-10-right-sidebar-cloud 07-20-lab-compact 15-30-lab-aero

Tours are picked by the paths globs in dogfood/scenarios/*.json; a Dogfood-tours: a, b line in the description picks them instead (none turns this off). Look at every frame before merging: a green tour only means no step failed.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Passes: CI passes on a8012ed2ef.

CI passes on a8012ed2ef (run 37873859085 attempt 2).

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.

@austinywang
austinywang merged commit 592952f into main Oct 10, 2026
138 of 141 checks passed
@austinywang
austinywang deleted the task-18689-cloud-hover-target branch October 10, 2026 20:02
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for a8012ed2ef: every check was green at merge (15 verified; 19 skipped by policy). Full suite runs on main after merge.

rustybret pushed a commit to rustybret/bmux that referenced this pull request Oct 10, 2026
812c971 fix: make local-tmux detached recovery reliable (manaflow-ai#18654)
592952f fix(cloud): isolate sidebar row hover targets (manaflow-ai#18693)
aece34e fix: repair Cloud VM canary and Claude managed defaults (manaflow-ai#18982)
071dbed fix(ui): reduce workspace layout follow-up amplification (manaflow-ai#18879)
ca14fdd fix(cloud): fence WireGuard activation preparation lifecycle (manaflow-ai#18672)
cf5bbe8 Fix Codex agent status in remote SSH workspaces (manaflow-ai#18792)
f7095c9 ⌘⌥F finds open agent sessions by what was said in them (manaflow-ai#18962)
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.

Cloud sidebar hover can highlight OpenCode from New Cloud Machine

1 participant