cmux NEXT: Go to What Needs Me, and marked tabs in Needs you

Closed
TE
3d ago
+2505-23

HOLD: Current palette captures are blank; replace and visually verify them before landing.

Leo, 2026-10-22:

idk where things are man i dont see anything other than the current workspace which is you and you have a cmux next github brwoser tab open (we need to have cmux expose this harder if it isn't already/hve better instructions)

Leo-ask: ask-12231fbe5e

Third slice of "needs you here". #24286 adds the daemon mark (cmux attention request --tab T --reason R, tab.update {attention}). #24311 draws it with the existing blue unread dot and ring. This PR adds two ways to get to a marked tab from anywhere:

  • Needs you list. Each marked tab is a kind: "tab" item. It shows the agent's reason, then the workspace and tab titles (never an id). Go to shows that tab. A marked tab offers no answers and no Ask about this, because it belongs to no chat.
    • Native side: AgentPaneAttentionTabs pushes [{kind, tabId, reason, workspaceTitle, tabTitle, atMs}] to every agent page as the attentionTabs host event, at load, at handshake and on every change.
    • Go to calls chat.attention.open {tabId}. It shows only a tab the page was listed, through the user jump revealTab.
  • Palette: Go to What Needs Me (attention.goTo). A page of the marked tabs, newest first. Return goes through the same Go to. It has no default key, so it takes no Ghostty-reserved key. It is also in the Window menu.

AttentionTabsWatch observes the daemon store across every connected machine and updates the list. Nothing polls; it reads only the marked tabs' titles. A mark never moves focus: only the person's Go to or Return does.

The attention projection, navigation, machine-scoped clear behavior, and regression tests stay together because they share the same mark lifecycle. Most additional lines are localized strings and tests.

The webview diff stays inside the item data and its row: model.ts, useNeedsYou.ts, the row in NeedsYou.tsx, plus a gallery variant. It does not touch needsYou.css, so it does not collide with #24068's popover restyle. The branch is reconciled with the current base recorded below.

Changelog

Added: Go to What Needs Me in the command palette, and tabs an agent marked for you in the Needs you list.

Tests

  • Tests/CmuxNextAgentPaneTests/AgentPaneAttentionTabsTests.swift:
    • chat.attention.open decodes and refuses malformed params.
    • The pushed shape.
    • Go to opens only a listed tab, and only once the App has wired the jump.
  • Tests/CmuxNextAppTests/AttentionTabsTests.swift:
    • The watch lists only marked tabs, newest first, by their titles, and a cleared mark leaves the list.
    • The palette page lists each mark with no id shown, listing it jumps nowhere, and its row jumps to the tab.
    • The action is in the palette with no default key.
  • webviews/test/agent-pane-needs-you-tabs.test.tsx:
    • The push is parsed and malformed entries are dropped.
    • A marked tab becomes one tab item.
    • The panel row shows the titles but not the id, with Go to and no Ask about this.
    • Go to calls chat.attention.open only.
    • A cleared mark leaves the list.
  • Gallery: agent-pane.needs-you variant marked-tab.

Validation and remaining work

Observed PR head: 4b0cc7fb1af0be03f8cebb102530cc4ee7531c4f, based on f8bd6ac189bc193a2b66ce3eea1c13db91b8f791; merged prerequisite #27497 is included.

  • The Home inbox routes marked tabs through chat.attention.open, retaining empty-session tab items and avoiding fallback chat selection.
  • Focused Home inbox tests passed in run 41140214713. Web lint and changed-code prepush checks passed.
  • Independent gpt-6-astra review returned BLOCK at 4b0cc7fb1af0be03f8cebb102530cc4ee7531c4f: both palette captures were blank. An earlier SHIP at 491a6027 does not cover this head.
  • The capture driver completed its steps and privacy check, but that is not visual acceptance. The current images below are failed evidence, and the visual HOLD remains.
  • The dropped DEBUG palette snapshot route has been restored in committed local work, with a stronger inbox regression that asserts no fallback selection. These repairs have not been confirmed pushed: SSH stalled, a bounded HTTPS push timed out, and the focused red/green test snapshot push timed out before CI dispatch. Fresh runtime capture and exact-head review remain pending publication of those repairs.
  • No merge is approved by the existing evidence.

Real before/after attention palette capture

The current head was captured on the fleet at 2x in a clean fixture. It creates a workspace, marks its current tab with “Confirm demo access,” opens the command palette, searches “What Needs Me,” and opens the marked tab page. The driver accepted every step and the privacy scan passed, but visual inspection found both palette images blank; these images are failed evidence.

Capture steps-3842a30fea-2x at 491a60270189 (fleet build, capture mini, text checked for private data)

LightDark
lightdark
attention-palette lightattention-palette dark

Viewed after image: yes
Visual verdict: BLOCK — both palette captures are blank and do not prove the marked-tab layout.


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


Summary by cubic

Tabs an agent marked for you (cmux attention request) now appear in the Needs you list and in a new Go to What Needs Me palette command, so you can reach them from anywhere. Both paths go through chat.attention.open {tabId}, which shows only a tab the page listed, and AttentionTabsWatch keeps the lists current by observing the daemon store across connected machines without polling.

New Features

  • A marked tab is a tab item in Needs you: it shows the agent's reason, then the workspace and tab titles, never an id, and offers no answers or Ask about this.
  • Go to What Needs Me (attention.goTo) lists the marked tabs newest first, has no default key, and is in the Window menu.

Bug Fixes

  • Opening a marked tab from the Home inbox shows it without leaving the tab selected.
  • A click, keystroke, or strip press resolves on the machine and window that began it, so a remote tab id never clears a matching local mark.
  • The debug window dump renders floating palette panels with the palette renderer, so captured fixtures show the panel's content without Screen Recording permission.

Agent session: agent session