Repository navigation
Let the Cloud toolbar name the machine-list failure it has - #15236
Conversation
With cached machines still on screen, the toolbar row renders one warning triangle and one "Machine list unavailable" line for all three failures and offers nothing to click. The notice and the empty state already route .unreachable to Retry, .sessionRejected to a fresh sign-in and .requiresPro to an upgrade, from the same MachineListStatusPresentation. This commit adds the failing coverage and the `perform` parameter the row needs to reach the handler. The body still hardcodes the triangle and the generic string, so the new tests are red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
MachinesListStatusToolbarRow now reads MachineListStatusPresentation the way the notice and the empty state already do, instead of hardcoding one warning triangle and one "Machine list unavailable" line. A rejected session shows the account glyph and a Sign In link; a lapsed plan shows the Pro glyph and an Upgrade link; an unreachable read keeps Retry. Both go through the same performListStatusAction the other two surfaces use. The presentation gains `staleTitle`, the one-line form for the toolbar, so the shorter copy still lives beside the full copy it has to agree with, and Action gains `shortTitle` because the toolbar has one line beside the status text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 15 seconds. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
… states, and make the tests discriminate
Review follow-up.
The row applied `.help(failure ?? "")` and `.cloudErrorCopyMenu(failure)`
unconditionally, so waiting and reconnecting got an empty tooltip and,
worse, an empty `.contextMenu {}`, which on macOS suppresses whatever menu
that region would otherwise inherit. Base applied neither to those
states. Both now hang off the failure branch. The action button also
takes `.fixedSize()`: in a narrow sidebar, truncating the status line is
survivable, losing the only affordance that fixes the failure is not.
Three test problems, all of which let a regression through:
- Nothing covered `failure = presentation.isFailure ? error : nil`, the
one genuinely new branch. Simplifying it to `let failure = error` kept
every test green while offline gained an orange dismissable chip. The
offline case now asserts no `CloudBannerDismissButton` for waiting or
reconnecting, and one for each failure.
- "The three failures do not read the same line" compared the three
rendered strings pairwise, but each row already carries a distinct glyph
and a distinct button, so three identical sentences would have passed.
Each row is now matched against its own `staleTitle`, the three stale
lines are checked to be distinct, and the panel's paragraph is checked
not to leak into the toolbar's single line. That subsumes the separate
stale-qualifier test, which is gone.
- Assertions used the English literals "last known" and "Offline", which
a copy edit or a non-`en` host would have reddened for no behavioral
reason. They read the presentation and the catalog now.
Also removed `.environment(\.accessibilityEnabled, true)` from the test
host and the comment claiming it switched SwiftUI's accessibility output
on. It does not: the key is a read-only signal for app code, and it is
deprecated. The window is what populates the tree, which the comment now
says.
## Changelog
Fixed: the Cloud sidebar toolbar no longer suppresses the header's context menu while waiting for the network or reconnecting.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ReviewReview subagent, correctness first. It cleared the view body (valid Fixed
Left
Disclosure: Fleet dogfood requested for the three failure states at minimum sidebar width, since a signed-out CI run cannot reach them. |
… through Run 36401958401 failed every test in this suite with nil elements and empty text. The previous commit removed `.environment(\.accessibilityEnabled, true)` on the claim that it did nothing and a window was the real requirement. The window is not sufficient: the same assertions passed in run 36397834894 with the modifier and no window, and fail with a window and no modifier. In-process there is no assistive client to switch SwiftUI's accessibility output on, so the hierarchy has to ask for it. The window is kept, since querying a detached hosting view is worth avoiding on its own, and the comment now records which of the two is load-bearing so it is not removed again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
CI receipt, and a correction to my review comment above. Correction. In the review I claimed
So the modifier is what publishes SwiftUI's accessibility tree in process; the window is not a substitute for it. Red/green for the behavior, from the same focused command:
The tip commit's test rewrite is in flight; I will post its result rather than claim it.
|
|
CI receipt for the accessibility-environment fix.
Same command both times:
|
|
Subagent review at a3c7589: nine findings, five fixed in a3c7589, four left with reasons (comment above). The one regression from that fix (dropped accessibility environment in the test harness) was restored in 25c3793 and is green in CI. Landing: resolving the main conflict, merging main after #15414, then auto-merge. |
Bugbot is paused — on-demand spend limit reachedBugbot 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. |
|
Merge receipt for |
762c3ed Recover a Cloud machine graph stuck on an equal-cursor conflict (manaflow-ai#15328) 524ebff ci: replay the fuzz regressions on sidebar, split and window changes (manaflow-ai#15412) 818d475 Let a user's Cloud open dial even right after a background link failure (manaflow-ai#15291) 97491a7 Let the Cloud toolbar name the machine-list failure it has (manaflow-ai#15236) 0abac32 PR media: adopt CI's build only, start when CI completes, run for every app PR (manaflow-ai#15418) 7f08715 ci(seed): keep the trusted seed on the Mac before the R2 upload (manaflow-ai#15411) 5663c13 Finish the destroy work where a Cloud machine is first found gone (manaflow-ai#15359) # Conflicts: # .github/workflows/ci.yml # .github/workflows/pr-media.yml # .github/workflows/seed-derived-data.yml # .github/workflows/test-e2e.yml
Main moved each Cloud row's tooltip and accessibility label into CloudTreeRowToolTip (#15326), so the Cloud Machines header's plan help and its "Cloud Machines, 1 of 50 machines" label move there too. MachinesCloudStatus keeps this branch's collapse-when-empty layout and takes main's performListStatusAction (#15236). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
When a machine-list read fails while cached machines stay on screen, the Cloud toolbar was the only one of the three status surfaces that did not say what went wrong.
MachinesListStatusToolbarRowmatched.failedwithout looking at the reason and drew one warning triangle plus "Machine list unavailable — showing last known", with nothing to click. So a user whose plan lapsed (HTTP 402) and a user whose session was rejected (HTTP 401) both read the same sentence, and neither was offered the thing that would fix it. The notice and the empty state have routed all three reasons correctly for a while:.unreachableto Retry,.sessionRejectedto a fresh sign-in,.requiresProto an upgrade. The file's own doc comment says all three surfaces read one presentation "so they never disagree"; the toolbar row was the one that did not read it.This is audit finding A5 from https://github.com/manaflow-ai/cmuxterm-hq/issues/853.
The row now reads
MachineListStatusPresentation:presentation.symbolName, so a rejected session gets the account badge and a lapsed plan gets the Pro sparkle instead of a generic trianglestaleTitle, the one-line form for a toolbar that still has cached rows under it. It sits next to the fulltitleit has to agree with, rather than being a separate literal in the viewpresentation.actionand runs through the sameperformListStatusActionthe notice and the empty state use, so the toolbar is no longer a dead endAction.shortTitleexists because the toolbar has one line beside the status text. "Sign Out & Sign In Again" becomes "Sign In" there; the notice and the empty state keep the full titlesOrange tint, the raw error on hover, the copy-error menu and the dismiss button stay bound to failures only, as before.
The two new stale strings use a comma rather than an em dash, which also keeps them parseable by
scripts/localize-changes.Testing
Added
cmuxTests/MachinesListStatusToolbarRowTests(5 tests). They mount the production row in anNSHostingViewwith accessibility enabled and read the accessibility tree, which is what the row actually exposes:.waitingForNetworkoffers no action and still reads "Offline".upgradeRed then green, same focused command both times:
f3278d4performparameter, body unchanged91f128bResults are pending as of this description; I will post the red and green outcomes as a comment.
Not run locally: this machine does not build cmux, so there is no local scoped verification for the Swift changes.
python3 scripts/localization_catalog.py checkdid run: 9 catalogs, 9 locales, 0 parity errors.Localization audit: two new keys (
machines.sessionRejected.stale,machines.requiresPro.stale) and two new short action titles (machines.sessionRejected.signInAgain.short,machines.requiresPro.upgrade.short), all four with entries for every one of the nine macOS locales, prepared through./scripts/localize-changesand imported by the catalog tool.machines.unavailable.retryneeded no short form, soshortTitlereturnstitlefor.retryrather than adding a duplicate key. No web strings changed.Changelog
Fixed: When the Cloud machine list fails to load and cached machines stay on screen, the toolbar now says whether the sign-in or the plan is the problem and offers the matching fix, instead of showing one generic "unavailable" message
Demo Video
Frames for the Cloud sidebar surfaces are being captured in CI for the audit; the three toolbar failure states are not reachable in a signed-out CI run, so this PR leans on the accessibility-tree assertions above rather than a screenshot.
Checklist
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
The Cloud toolbar now names the specific machine-list failure it hit and offers the fix for it instead of showing one generic "unavailable" message with nothing to click. A rejected session gets a Sign In link, a lapsed plan an Upgrade link, and an unreachable read keeps Retry, routed through the same handler the notice and empty state use.
staleTitleandshortTitletoMachineListStatusPresentationso the toolbar's one-line copy stays beside the full copy it has to agree with.Written for commit a87e1f9. Summary will update on new commits.