Cloud: a paused machine never flashes Disconnected, and a send to its chat resumes it

Merged
TE
3d ago
+111-14

Leo, 2026-11-03: "The model sometimes sees a delay and you sometimes see it after sending but it evens out to not much at all just a tiny bit of extra time that you mostly perceive as "thinking" / But it's all still responsive on the ui side"

Cloud machines are about to pause on idle, and later between tool calls. When a pause ends a machine's app link, the app's record still says running. Today the sidebar header and the composer strip first read Disconnected with an attention dot, for up to 30 s, until the throttled list read catches up.

What changes (cmux NEXT Cloud, app link only; legacy links unchanged)

When an app link drops on a machine whose record doesn't read paused yet:

  • The app reads the machine list at once, forced past the 30 s throttle, once per ended link.
  • Until that read answers, the machine reads as on its way (spinner, .connecting, no attention colour).
  • Then it reads Paused (grey) if the list says paused. If the machine still runs, it reads Disconnected as before (#28409).
  • This applies to drops and revocations only. A provider failure still reads Failed to start.

Sends:

  • A send during the read waits for it, and never reconnects a machine a pause may have parked. An open chat's background reattach therefore never undoes a pause. The page's own send wake (#33281) is what resumes a paused machine on an explicit send.
  • AgentPaneMachineLink.awaitLink now runs the Reconnect once if a link that read as on its way turns out down. A send made during the read still reconnects a link that really dropped, as it did on base.
  • A connect clears the confirmation, so a link that came back is never masked.

Files

  • CloudMachineStage.swift: linkEndConfirming on the stage input. An ended link reads .booting while it is set.
  • CloudMachineSession.swift: showEnded starts one forced read, which clears the flag when it returns unless a connect happened since. A connect also clears it. No timer.
  • AgentPaneMachineLink.swift: at most one Reconnect per wait, run when the wait first sees .down.
  • Tests: forced read with the header connecting while it runs, then Paused (idle) and .stuck; a real drop still reads Disconnected; a connect clears the confirmation; a wait reconnects once when the link turns down.

Prior art acknowledged: #28403, #34266, #28051, #25668, #28409, #33281, #33890. None of their files overlap.

Risk: state handling on the link-ended path. Reviewed by a different model (router-review); three rounds of blocking findings fixed.

Agent session: agent session

šŸ¤– Generated with Claude Code