Skip to content

agent pane: a paused Cloud machine's chat says paused and offers Resume - #26874

Merged
teamleaderleo merged 8 commits into
feat-cmux-nextfrom
hc/cloud-chat-paused-banner
Oct 28, 2026
Merged

teamleaderleo merged 8 commits into
feat-cmux-nextfrom
hc/cloud-chat-paused-banner

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

A chat whose Cloud machine is paused now says the machine is paused and offers Resume. Before, the banner over the chat said the machine was offline, with nothing to do about it. While the machine starts, the banner shows a spinner and "Starting" in place of a second Resume.

Leo, 2026-10-28: "whatever's convenient for cloud, like that can be productionized, operationalized, we ought to just put out there". The Cloud state-of-affairs issue (cmuxterm-hq#4755), quoting Leo: "we want to get a lot of good stuff wrt the pausing and resuming and how it integrates with acpmux + the gui chat". This PR fixes one item on its gap list: a paused machine's chat reads "offline", and the pane has no Resume. The chat-menu half (Pause and Resume rows) is cmux#26872.

What changed (webviews only)

  • peerCloudMachine.ts (new):
    • It matches an offline peer chat to the account's Cloud machine by name, in any case, the way the app matches a peer to a machine.
    • It says whether the machine is paused or starting; a Resume this page asked for counts as starting.
    • usePeerCloudMachine reads the account's machine list once when the chat's machine goes down.
  • PeerCopyBanner.tsx: a machine the account lists as paused reads " is paused", with Resume. One that is starting reads "Starting …" with the shared Spinner, never a pulsing dot. Anything else reads offline, as before.
  • App.tsx passes the hook's state and resume to the banner.
  • Resume goes through the existing cloudMachine.resume bridge method. That method takes one click, and the app runs it only on a paused machine from the account's list. After Resume, the list is read again, so a refused Resume leaves the machine paused with Resume back.
  • Timer: the list is read every 3 s, only while the machine starts. It stops when the machine leaves the starting stages, when the chat's machine answers again, or when the banner unmounts (effect cleanup, clearInterval). There is no other timer or observer.
  • Strings: peerCopy.paused.title, peerCopy.paused.resume and peerCopy.starting.title, in all 21 locales.

Design choice (gallery agent-pane.peer-copy-paused, experiment paused-machine-resume, 3 arms):

  • actions (ships): Resume in an actions row under the banner's text.
  • inline: Resume as a link at the end of the first line.
  • button: a small filled button at the trailing edge of the first line.

I picked actions because it matches the watch and open-elsewhere banners in the same pane, which put their choices in that row with the same button. The other two arms make this banner look different from its neighbours: a filled accent button is louder than anything else in the pane, and an inline link is easy to miss in a two-line banner.

Gating: none. This fixes the existing offline banner, which every user already sees on a peer chat whose machine stops answering. Only a machine the account lists as paused or starting changes what it says. Without Cloud machines, nothing changes.

Captures: the before/after captures are the gallery variants before, paused, starting and paused-no-time in agent-pane.peer-copy-paused (the gallery advisory run on this PR).

Risk: low. Webview only, no new bridge method, and at most one list read, plus the 3 s reads while a machine starts.

Tests (test/agent-pane-peer-copy-paused.test.tsx, cmux-ci Linux, together with the peer-copy, gallery-entry, coverage and strings suites; bun run check passes):

  • a paused machine's chat says it is paused, and Resume starts it once;
  • a starting machine is read again until it leaves the starting stages, and no read outlives the banner;
  • a machine the account does not list, or one that is ready, reads offline as before;
  • each arm of paused-machine-resume puts Resume where it says.

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 chat whose Cloud machine is paused now says the machine is paused and offers Resume, instead of reading "offline" with nothing to do about it. While the machine starts, the banner shows a spinner and "Starting".

Details

  • The offline chat's peer is matched to the account's Cloud machine by name, only when no other of the account's machines shares the name and the peer is not an ssh peer; the machine list is read once when the chat goes down and every 3 seconds only while it starts, capped at 60 reads.
  • A Resume belongs to the machine it was asked for; another peer never reads as starting because of it.
  • Resume runs the existing cloudMachine.resume bridge, which consumes one click; a refused Resume leaves the machine paused, with Resume back.
  • paused-machine-resume compares three Resume placements; the actions row (matching the watch banner) ships, and inline and button arms stay in the gallery.
  • Webview-only with copy in all 21 locales; without a Cloud machine match, the banner reads offline exactly as before.

Written for commit 10ecc55. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 3 commits October 28, 2026 04:53
The banner over a peer chat drawn from the Mac's copy read 'offline' for a
paused Cloud machine, with nothing to do about it (cmuxterm-hq#4755). It now
reads the account's machine of the chat's peer name (cloudMachine.list):
a paused one says it is paused with Resume (cloudMachine.resume, one click),
and one starting shows a spinner. The list is read again every 3 s only
while the machine starts; the reads stop when it no longer starts, when the
chat is back, or when the banner goes.

Resume's place is the paused-machine-resume experiment (actions row ships;
inline link and filled button compared in the gallery).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 10ecc55: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr26874 -f ref=hc/cloud-chat-paused-banner -f platform=macos -f backend_mode=local

Unclear: web / react-apps-check failed: no known signature; failed step: Check webview test shards. This PR merged before its CI finished: fix forward on main.

CI failed on 10ecc55049 (run 40720305980 attempt 1): 2 code, 1 unknown.

Job Verdict Why
web / react-apps-base-check (1) code a web test failed
web / react-apps-base-check (2) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs thread-minimap-left-rail-stays.test.ts webkit: an open card follows its rail on every painted inspector and resize frame at 1084px: failed (job)
  • seen on other PRs transcript-jump-latest.test.tsx scrolled up, a static button above the composer jumps to the latest message while a reply streams: failed (job)
  • seen on other PRs gallery-agent-pane-entries.test.ts agent-pane.header-tools#pull-request-status shows the product: failed (job)
  • seen on other PRs thread-minimap-long-chat.test.tsx a clicked tick keeps focus while the chat scrolls it out of the rail's window: failed (job)
  • seen on other PRs transcript-find-follow.test.tsx a Find jump stays on its match when the transcript measures again before the scroll event: failed (job)
  • seen on other PRs transcript-scroll-restore.test.tsx a scrolled-up chat reports where it rests and reopens there, not at the latest message: failed (job)
  • seen on other PRs transcript-scroll-restore.test.tsx a place whose row is gone opens at the latest message: failed (job)
  • seen on other PRs transcript-scroll-restore.test.tsx switching chats opens the new chat at latest instead of the old chat's scroll offset: failed (job)
Matched log lines
web / react-apps-base-check (1): (fail) webkit: an open card follows its rail on every painted inspector and resize frame at 1084px [3769.94ms]
web / react-apps-base-check (2): (fail) agent-pane.header-tools#pull-request-status shows the product [917.83ms]

Not re-run automatically: web / react-apps-base-check (1), web / react-apps-base-check (2), web / react-apps-check are not machine failures.

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.

red: web / Web status; base red: the same failure on the base d8a5b1a; does not block
red: web / react-apps-base-check (1); no finished base run on d8a5b1a to compare; do not merge until green; see lane-rules
red: web / react-apps-base-check (2); no finished base run on d8a5b1a to compare; do not merge until green; see lane-rules
red: web / react-apps-check; base red: the same failure on the base d8a5b1a; does not block

Gallery before/after for 10ecc55: 16 states rendered, 0 images differ, 1356 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 40720305776 -R manaflow-ai/cmux -n gallery-advisory-26874-10ecc550490de3532d717689eedc793f6140dba8 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.add-project-panel/environment Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/environment Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/sources Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/sources Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/directory Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/directory Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/keyboard Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/keyboard Apple System Colors unchanged 0% own styles.css
agent-pane.changes-file-menu/closed Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-file-menu/closed Apple System Colors unchanged 0% own styles.css
agent-pane.changes-file-menu/open Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-file-menu/open Apple System Colors unchanged 0% own styles.css
agent-pane.changes-file-menu/keyboard Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-file-menu/keyboard Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/toolbar Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/toolbar Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/commit-form Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/commit-form Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/include-new Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/include-new Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/keyboard Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/keyboard Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/busy Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/busy Apple System Colors unchanged 0% own styles.css
agent-pane.changes-git-actions/push-refused Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-git-actions/push-refused Apple System Colors unchanged 0% own styles.css
agent-pane.changes-options-menu/closed Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-options-menu/closed Apple System Colors unchanged 0% own styles.css
agent-pane.changes-options-menu/open Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-options-menu/open Apple System Colors unchanged 0% own styles.css
agent-pane.changes-options-menu/keyboard Apple System Colors Light unchanged 0% own styles.css
agent-pane.changes-options-menu/keyboard Apple System Colors unchanged 0% own styles.css

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 28, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-wr6xds created for this PR by the cmux coordinator.

teamleaderleo and others added 3 commits October 28, 2026 06:49
…arts are bounded

Another peer never reads as starting because of a Resume still running for another machine. A
machine stuck starting is read at most 60 times (3 minutes). The read when the machine goes down
is its own effect, so leaving the starting stages asks for no extra read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…tart test reads each tick

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…unt's shares, never an ssh peer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
@blacksmith-sh

blacksmith-sh Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Found 20 test failures on Blacksmith runners:

Failures

Test View Logs
src/pages/settings/layout.test.ts/layout.test View Logs
src/pages/settings/layout.test.ts/layout.test View Logs
test/agent-pane-jump-latest-motion.test.ts/agent-pane-jump-latest-motion.test View Logs
test/agent-pane-jump-latest-motion.test.ts/agent-pane-jump-latest-motion.test View Logs
test/agent-pane-queue-scroll-bottom.test.ts/agent-pane-queue-scroll-bottom.test View Logs
test/agent-pane-queue-scroll-bottom.test.ts/agent-pane-queue-scroll-bottom.test View Logs
test/agent-pane-stream-jitter.test.ts/agent-pane-stream-jitter.test View Logs
test/agent-pane-stream-jitter.test.ts/agent-pane-stream-jitter.test View Logs
test/row-focus.test.ts/row-focus.test View Logs
test/row-focus.test.ts/row-focus.test View Logs

...and 10 more test failures. View all on Blacksmith

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

@cursor

cursor Bot commented Oct 28, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, next-review): SHIP at ec91c67

No blocking findings.

  • Non-blocking: webviews/test/agent-pane-peer-copy-paused.test.tsx:94 defines Host inside mount(), so changing peers remounts the hook and resets its state. The pending-resume test therefore doesn’t exercise switching peers with retained state. Use a stable component and rerender its props.

Static review only; unchanged Cloud helpers were unavailable, and tests were not run.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra): SHIP at 10ecc55

Gallery health reds (empty-state#search, narrow#model-menu, model-picker#many-harnesses, streaming-text#jump-during-stream, and the budget lines for composer-row, composer, diff-panel, image-viewer) fail the same way on base (run 40716206829); none is in agent-pane.peer-copy-paused.

@teamleaderleo
teamleaderleo merged commit cce378b into feat-cmux-next Oct 28, 2026
160 of 164 checks passed
@teamleaderleo
teamleaderleo deleted the hc/cloud-chat-paused-banner branch October 28, 2026 16:09
@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40723201469 at cce378b failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 33e2e65. This pull request is one of 4 merged since: #26736, #26880, #26891, #26874.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 10ecc550 Deployed Oct 28, 2026 by teamleaderleo via wait for same-key tree publisher #72205
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant