Cloud page: follow the app's sign-in live, and name machines as the sidebar does

Merged
TE
6d ago
+442-9

Leo (2026-10-31): "let's work on improving this a LOT / cmux-platform, cmux when necessary / lots and lots of code".

What was broken

Dogfooding NEXT's Cloud while signed in with ten machines in the right sidebar:

  1. Stale sign-in. A Cloud page tab opened earlier (before the sign-in, or before the session was restored at launch) still showed the signed-out hero ("Your agents keep working when your Mac doesn't" and Sign In). A second Cloud page opened later listed the machines. The page's store read cmux.cloud.auth.status once, when it mounted; nothing told it the app's account changed, so only a sign-in through that page's own button refreshed it.
  2. Raw ids. On the classic link, the page listed vm-1304f870… for machines the sidebar and cmux cloud list-machines name kind-aqua-sandpiper. The page record took CloudMachine.displayName only; the sidebar's title falls back to the generated slug.

What changed

  • Host: CloudPageProvider serves a new page stream, cmux.cloud.auth.watch. Its first event is the current account ({signedIn, team}), then one per change, from an observation of CloudService (isSignedIn, auth.teamID) that re-arms per change and ends with the last watcher. No timer, no polling. PageFactory.cloudProvider passes the account; providers given none refuse the stream as an unknown op.
  • Page: CloudStore subscribes on start (closed on stop). On each event it re-reads auth; if it differs from what the page shows it drops the old account's state and loads the new one (or clears to signed out), the same path its own Sign In / Sign Out take. A host without the stream is ignored, so the page still works against an older app.
  • Names: CloudMachine.shownName (displayName, else slug) is the one rule; title is shownName ?? id, and the classic page record's name is shownName. No second rule on the page.

Risk

Low. The new stream is additive; an event for the account already shown reloads nothing (the page's own Sign In racing the event loads once, covered by a test). The name change only affects machines with no user name and a slug, which now show the slug instead of the id, as the sidebar already does.

Tests

  • webviews/src/pages/cloud/store.account.test.ts (new): signed-out page lists machines once the app signs in elsewhere (red before: no stream, auth stays signed out); sign-out elsewhere clears the machines and closes the watch; a same-account event reloads nothing; own Sign In plus the event loads once; the stream ends with the page; an older host without it still loads.
  • CloudClassicPageTests: theAccountStreamFollowsTheAppsSignIn, noAccountRefusesTheAccountStream, aRecordIsNamedAsTheSidebarNamesIt.
  • Receipts: webview bun test src/pages/cloud 116 pass / 0 fail on the fleet Linux pool (job cb16f05a95f042668350ac6a, at the head's webview tree); cmux-ci compile-check --app passed at 3c99551 (job a75ad58e650a7837e74a2085; Swift is unchanged since); Swift suites CloudClassicPageTests (12, incl. the 3 new) + CloudPaneTests (8) all pass at 3c99551 (fleet job ef5033411fdf4cab443574d4; the later commit touches only webviews).

No visual design change: the page renders its existing signed-in and signed-out states; it now reaches the right one. Design spec: leo-workspace design/cloud.md (unchanged).

Prior art: builds on #28405 (classic link page ops). No overlap with #28781 (cost), #28786 (signed-out actions sign in, then run), #28777 / #27973 (picker sign-in).

Agent session: agent session

šŸ¤– Generated with Claude Code


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


Summary by cubic

A Cloud page opened while signed out (or before a session was restored at launch) kept its Sign In hero after the app signed in elsewhere, and classic link records showed raw machine ids where the sidebar shows the generated name. The page now follows the app's account live and names machines the same way the sidebar does.

  • The host serves the cmux.cloud.auth.watch stream: its first event is the current account (signed-in state, user, team), then one per sign-in, sign-out, user or team switch anywhere in the app; no polling.
  • The page reads auth again on each event and loads or clears the machines through the same path as its own Sign In / Sign Out, so events for another signed-in user and for repeat states are handled. A read that fails drops the old account's machines and restarts, so the event is never lost; a restart mid-subscribe closes the stale stream and keeps its own. Hosts without the stream are ignored, so the page still works against older apps.
  • CloudMachine.shownName (display name, else generated slug) is now the single naming rule for page records, matching the sidebar.