Cloud: a window on a paused machine's workspace resumes it and shows its progress (#33483)

Merged
TE
4d ago
+94-4

Fixes #33483.

On launch, paused machines are refused, and the connecting view watches the local daemon and hides itself. That leaves a blank pane with no Resume.
Expected: the pane says the machine is paused and offers Resume (or resumes it on its own).

What changed

  • WindowController.showWorkspace: when the requested workspace is on a Cloud machine whose record is paused (a relaunch connects only live machines, so nothing mirrors that workspace), the window now calls showPausedMachine (new, WindowController+PausedMachine.swift). It resumes the machine once through the existing attach path (CloudMachineSession.attach(origin: .user), the same Resume Machine path opening a terminal or chat uses), and shows the existing CloudMachineProgressView for that machine: booting stages while it resumes, Resume while paused, the reason and Retry if the resume fails. Once the machine runs, the existing isWaiting keeps the view up while its daemon loads, and the workspace replaces it when it is mirrored.
  • A window kept off screen until its workspace is mirrored (WindowManager.awaitingContent) is presented with that view (present is now internal), and makeController's present condition and WindowInvariants count the view as content.
  • Behaviour change to note: a window whose requested workspace is on a paused machine now waits on that machine (and resumes it) instead of falling back to another of its workspaces; the request is no longer silently replaced.
  • plans/cmux-next/arch-exceptions/paused-machine-window-33483.json: app_lines +18; this is window wiring over App-only types.

Tests

PausedMachineWindowTests (new): a window restored on a paused machine's workspace shows the machine's progress view and resumes it exactly once across observer re-runs, keeping its request; a window on a live machine resumes nothing. Before the fix the window's content is the connecting view, so the first test fails at its #require.

Risk: low-medium. It touches only the path where the requested workspace is on a paused Cloud machine; live machines and this Mac return before it. Follow-ups (Dismiss falls back to the connecting view; the bring-to-front flag of an off-screen window is dropped) are filed separately.

Agent session: agent session

🤖 Generated with Claude Code


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


Summary by cubic

Fixes a window restored on a paused Cloud machine's workspace showing a blank pane with no Resume after a relaunch. The window now resumes the machine once and shows its progress view until the workspace is mirrored.

  • A window on a paused machine's workspace now calls showPausedMachine, which resumes the machine through the same attach path used by terminal and chat, and shows the existing CloudMachineProgressView with Resume, Retry, or the paused reason.
  • A window kept off screen until its workspace is mirrored now presents that view instead of staying hidden.
  • Behavior change: a window whose requested workspace is on a paused machine now waits on (and resumes) that machine instead of silently falling back to another workspace.
  • Adds PausedMachineWindowTests covering resume-once semantics and confirming live machines are unaffected.