cx-v9k2f: lanes view on Agent Activity + sidebar attention count (Labs preview)

Merged
TE
23d ago
+2641-53

Bead: cx-v9k2f (part 2 of 2). Needs #20362 (acpmux decides lane) to show anything; without it every session decodes to no lane.

Problem

Leo, 2026-10-13: cmux NEXT coordination should make lanes that go idle or stuck obvious. About 25 lanes sat idle for hours unnoticed that day, some dead on out-of-credit errors.

Change

This is behind Settings > Advanced > Labs > Show Preview Features (labs.previewFeatures, off by default), following the no-prototype-UI rule. It is fully functional, but not yet styled.

  • Lanes view on the Agent Activity page, with a Lanes | Computer use switch:
    • lists every acpmux session on this Mac and on the acpmux peers it mirrors;
    • groups them by machine, then by the coordinator that started them (mux.parent, headed by the coordinator's own session);
    • orders each group: failed (with the error text, e.g. "Credit balance too low"), lost, waiting on permission, idle (longest first, "Idle · 5h"), then working.
    • The filter also matches error text.
    • A click opens the chat through the cmux://session/<id> path every session link takes. It reveals the tab that shows the chat, or opens one in the focused pane.
  • Sidebar: a client-only Lanes item next to What's New, shown only while the flag is on. It quietly counts the sessions that need a person (failed, lost, waiting on permission); a click opens the page.
  • Data path: the existing _acpmux/watch feed (AgentTurnStateFeed) also decodes each summary's lane into AgentLaneStore. No new connection and no polling.
  • New target CmuxNextAgentLanes (for the CmuxNextApp size cap). It now holds AgentTurnStateFeed, moved unchanged except for public entry points and a drain-timing hook for debug.timings, plus the sidebar's Lanes item. The lanes observation is AgentActivityModel.follow. CmuxNextApp is 164 lines under its cap.
  • Strings: 13 new, in 21 locales (non-English marked needs_review). The sidebar item reuses the page's "Lanes".
  • Gallery: a new lanes variant on pages.agent-activity.

Not in this PR:

  • Sessions on remote cmux machines (Cloud, SSH, servers). Their chats are reachable only one tab at a time through agent-session-attach-v1, so listing them needs a new read-only daemon verb.
  • Verifying that opening a peer's session works end to end.

Verification

  • Web, red then green. test/agent-activity-lanes.test.tsx renders the page with one fixture per lane state across this Mac and a peer.
    • Red at 514c0af (test only): 6 fail, 1 pass. The one pass is the flag-off case, already true without the view.
    • Green at 7f8309f: 7 pass.
    • Covered: order, grouping, state words and durations, the error text, the attention count, click → jump, filter by error text, the view switch, and flag off.
  • Swift, AgentLanesTests. The real watch feed runs against a stand-in acpmux on a socket.
    • It checks: lanes decoded, the badge at 3 (failed, waiting, lost), live pushes moving the badge, a closed session leaving, and the Lanes item shown only while labs.previewFeatures is on.
    • On the fleet at 7f8309f: PASS ^CmuxNextAppTests\.AgentLanesTests/.
    • It uses new API, so it can't compile on base; there is no separate red run.
  • Release compile on the fleet at 7e6d0a5 (the merged head, with #20408): passed (aws-m4pro-6). Earlier at 7f8309f and 0869fbe: passed.
  • Full Swift suites on the fleet at 7e6d0a5: 286 passed, 0 failed.
    • Passes include AgentLanesTests and the moved feed's suites: AgentChatDoneDotTests, AgentChatMuteTests, AgentChatTabTitleTests.
    • The step exits 1 only because AcpmuxBundleReplacedTests (daemon) skipped for want of the same-tree cmux-tui. This PR doesn't touch it.
  • Release compile on the fleet at 7ef7eca (base with #20362 and #20659): passed (xcodebuild exit status: 0). The final head ce89f66 differs only by #20641's home-channels web files.
  • Before/after, watched (--builder mac DEV builds on capture slots). Base is 3f4c100, which has #20362's lane field but not the view. Seven acpmux sessions were seeded through a fake agent (chief working, op-docs idle, op-billing failed, op-deploy asking, op-search working, op-flaky's process died, scratch with no parent). Labs previewFeatures was set by a per-run config file, never the shared one.
    • Before: no Lanes item, and Agent Activity shows only Computer use.
    • After: the sidebar Lanes item shows a badge of 3. A real click opens Agent Activity on Lanes | Computer use. The page reads "Needs you: 3", then This Mac with the chief group and "On their own". Each row shows Working (green), Failed with its reason (red), Waiting on you (red) or Idle (grey), with its duration.
    • Labs off: the head build matches base pixel for pixel.
    • Design call: red marks everything that needs the person, failed or waiting, and the words tell them apart.
    • Not shown: the Lost state. The fake's process died between turns, which acpmux reports as failed with its reason; lost needs a death mid-turn (views.rs). Durations read "1m" after about 30 s.

plan image 20363/before-agent-activity.png
plan image 20363/after-lanes-page.png
plan image 20363/side-by-side-sidebar.png
plan image 20363/labs-off-head-sidebar.png
plan gif 20363/before-recording.gif (from before-recording.mp4)
plan video 20363/before-recording.mp4
plan gif 20363/after-recording.gif (from after-recording.mp4)
plan video 20363/after-recording.mp4
uploaded 20363/before-agent-activity.png
uploaded 20363/after-lanes-page.png
uploaded 20363/side-by-side-sidebar.png
uploaded 20363/labs-off-head-sidebar.png
uploaded 20363/before-recording.gif
uploaded 20363/before-recording.mp4
uploaded 20363/after-recording.gif
uploaded 20363/after-recording.mp4

before agent activity

after lanes page

side by side sidebar

labs off head sidebar

before recording

Full quality:

after recording

Full quality:

  • Swift suites on the fleet at ce89f66 (exact head): 310 passed, 0 failed; PASS ^CmuxNextAppTests\.AgentLanesTests/.
  • Local web checks: bun run check, tsc, ui-rules and gallery-coverage pass.
  • Repo checks: check-concurrency, crash_ratchet, check-system-blue and check-no-godfiles are ok.

Open question

Should the badge also count idle child lanes (under a coordinator)? It counts only failed, lost and waiting sessions, so a normal set of idle chats doesn't keep a number up. On the page, idle shows as "Idle · 5h", longest first.

Changelog

none (behind Labs preview features)

🤖 Generated with Claude Code