Skip to content

cmux NEXT: a tab an agent needs you in shows the blue dot, the ring and why (carries #24311) - #27962

Merged
cmux-bot[bot] merged 49 commits into
feat-cmux-nextfrom
lane/attn-24311-carry
Oct 30, 2026
Merged

cmux-bot[bot] merged 49 commits into
feat-cmux-nextfrom
lane/attn-24311-carry

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Carries #24311 (its owner session is gone and its branch sp-attn-b is outside the lane/ namespace this lane can push), with its commits and authorship, onto current feat-cmux-next, plus the fix for the review BLOCK at c27c81c826cf.

Carry changes

  • Merged current feat-cmux-next (latest at 06e35107b02). One conflict, in SidebarMapping.swift, where base now names the row's face tab face (cmux-next sidebar: a page a chat opened leaves the chat's row icon #23700/cmux NEXT: agent open makes a chat-only workspace; a chat names its row over an idle shell #26709). Kept base's code and this PR's attention dot and reason.
  • BLOCK fix (23ffe9524a7): a mark from a daemon without request ids ({reason, at_ms} only) stayed ringed until the agent cleared it, because going in and Dismiss Highlight skipped marks with no request_id. Hiding the ring is this client's view state, keyed by the client-local attention generation, so it now covers those marks. A press on a mark replaced since the press is still dropped: with no request id it compares the generation captured at the press. The owner clear still requires the id (tab-attention-request-id-v1). Test: TabAttentionTests.aLegacyMarksRingHidesOnEntryAndDismissHighlight.
  • Menu validation fix: a row this PR scopes to its machine (Dismiss Highlight, Mark Tab Unread) is now validated against that machine as well as run on it.

Scope. This PR scopes only its own two rows (Dismiss Highlight on a workspace row, Mark Tab Unread on a tab) to the right-clicked object's machine. Every other menu row, and every handler that resolves a tab or workspace id, works exactly as on base: by first match across machines. An attempt to scope every row here (44d10315..ad63a5fc) kept surfacing more first-match lookups downstream and mixed machines inside one action, so it is reverted. The general fix ((machine, id) resolution everywhere, plus a lint against bare locateTab(id)) is tracked in manaflow-ai/cmuxterm-hq#5338.


Leo-ask: ask-12231fbe5e

Leo: "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)"

Slice B of the "needs you here" surface: the app shows a tab an agent marked. The daemon half is #24286 (tab.update {attention}, cmux attention request|clear, tab-attention-v1), and this PR lands after it: the bundled-daemon capability check needs that daemon. The palette command and Needs you list item come in slice C, the agent instructions in #24299.

What changes

  • The tab record's extra.attention {reason, at_ms} becomes TabModel.attention (TabAttention, CmuxNextDaemon).
  • TabModel.showsUnread reads it, so the existing blue treatment shows it everywhere showsUnread is read. There is no new dot and no new drawing code:
    • the tab's dot (TabItemMapping);
    • the screen bar;
    • the sidebar tab list;
    • the pane's blue attention ring.
  • The workspace row gets its manual dot, and its text line shows the reason ("Confirm GitHub access") ahead of any notification text.
  • Going into the pane (a click or a key) or Dismiss Highlight hides the ring. The dot stays until the agent clears the mark, the page goes elsewhere or the tab closes. A new request (a newer at_ms) rings again.
  • Mark as Read on the tab also drops the mark (tab.update {attention: null}, when the daemon has tab-attention-v1).
  • notifications.attention.showOnSidebar = false hides it like any unread.

Tests

TabAttentionTests (CmuxNextAppTests):

  • parsing, including malformed values;
  • showsUnread follows the record;
  • the row's dot, the reason and the tab dot; showOnSidebar off hides it;
  • the ring rings, stays on focus, hides on a click and comes back for a new request; Dismiss Highlight hides it.

Fleet compile-check at 2ae8268: compile check app: passed.

Capture

Real captures at the head 9638e536 (after) and at the merge base 3f6df909 (before). Each one is a fleet build driven on a capture mini, in light and dark. Each state is a steps file: create an Attention workspace, run cmux attention request --tab current --reason "Confirm GitHub access", then the steps named below.

After: the marked workspace's row while another workspace is shown. Rows show their text line (sidebar.density expanded, sidebar.workspaceRow.notification true), then a Work workspace takes focus. The Attention row has the blue dot and the reason "Confirm GitHub access" as its text line. Its tab row has a dot.

Capture steps-1c499ee5bb at 9638e5361e28 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Before (same steps on base): the Attention row has no dot, and its text line is the folder (~). Its tab row has no dot.

Capture steps-1c499ee5bb at 3f6df9091dec (fleet build, capture mini, text checked for private data)

Light Dark
light dark

After: the marked pane, then split right (default compact rows, with the row collapsed by a click on its chevron). The marked left pane keeps the attention ring while focus is in the new right pane. Its tab in the strip and the workspace row show the blue dot.

Capture steps-f0b5afd4e4 at 9638e5361e28 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

After: a click into the marked pane (a debug.mouse click in the left pane). The ring is gone. The tab dot and the row dot stay until the agent clears the mark, as described above.

Capture steps-361ccfa69e at 9638e5361e28 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Before (the split steps on base): no ring, no tab dot, no row dot.

Capture steps-f0b5afd4e4 at 3f6df9091dec (fleet build, capture mini, text checked for private data)

Light Dark
light dark

The reason line shows only where a row shows its notification text: expanded rows with sidebar.workspaceRow.notification on, on a row other than the one shown. On default compact rows, and on the shown workspace's row, only the dot shows.

Viewed after image: yes
Visual verdict: Yes, the blue dot, the reason line and the pane ring reuse the existing unread treatment with no new chrome, and the click hides only the ring, so it would sit fine next to ChatGPT or Claude.

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 30 commits October 29, 2026 07:10
… why

tab-attention-v1 (the daemon half is #24286): the tab record's
extra.attention {reason, at_ms} becomes TabModel.attention, and
showsUnread reads it, so the tab's blue dot, the screen bar, the sidebar
tab list and the pane's blue ring all show it with no new drawing. The
workspace row gets its manual dot and shows the reason as its text line.
Going into the pane (a click or a key) or Dismiss Highlight hides the
ring; the dot stays until the agent clears the mark, the page changes or
the tab closes, and a new request rings again. Mark as Read on the tab
also drops the mark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray
interacted(_:tabID:) found tabs on this Mac's daemon only, while attentionMarks
rings marked tabs on every machine, so a click or a key in a Cloud or SSH tab
never dismissed its ring. A tab found on another machine now gets the ring's
dismissal, which is this app's own state; its notifications and Mark as Unread
keep their daemon's own paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray
…eject a bad at_ms

A tab on another machine can share an id with one here (a forked machine keeps its
tab ids). Interactions now find the tab in the workspace the window shows, on the
machine that owns it, and the hidden-ring state lives on the tab's own model, so
one machine's click or Dismiss Highlight never hides another's ring. A mark whose
at_ms is missing, negative, fractional or not a number is no mark.

Leo-ask: ask-12231fbe5e

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray
…ace mark here; tests prove the redraw and the untouched local tab

noteTyping's workspace Mark as Unread clear now runs only for a window that shows
this Mac's workspace (or none), so a key in a remote terminal never clears a local
workspace whose tab shares the id. The ring test checks that hiding the ring wakes
its observers, and the two-machine test checks that a click on the remote tab leaves
the local tab's Mark as Unread alone.

Leo-ask: ask-12231fbe5e

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray
Integrate the shared native request-ID contract from 9171431 and cecd056 while retaining machine-scoped dismissal state and client-local attention generation. Clear only the captured owner token and require the capability on the actual sending connection after handoff.

Regressions cover coalesced same-clock replacements, stale native mouse release, and legacy transport refusal. Fleet runtime validation is pending the backend-containing integration tree from #27497; no runtime result is claimed. Static verification: nine checks pass; unchanged localization inputs exceed existing debt. Swift #26809 and structural dogfood holds remain.
teamleaderleo and others added 5 commits October 30, 2026 13:58
The one part of the reverted 44d1031 that fixed this PR's own code: menu
validation rebuilt the invocation without targetMachineID, so a scoped
row's title and enablement were checked against a same-id object on
another machine.

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

cursor Bot commented Oct 30, 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 (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base f3ae1f8 to this head): SHIP at 5825e87.

No P1/P2 findings.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base f3ae1f8 to this head): BLOCK at 5825e87.

[P2] Packages/macOS/CmuxNext/Sources/CmuxNextApp/Notifications/NotificationCenterService.swift:432 - Opening/jumping to an attention-marked tab uses .open, but dismissAttention ignores that trigger, leaving the pane ring visible after the user has entered the tab - include .open in the dismissal triggers.

Sol review BLOCK at 5825e87 on #27962 (P2): jump to unread or a
banner click opens the tab with the .open trigger, which dismissAttention
ignored, so the ring stayed after the person went in.

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

Copy link
Copy Markdown
Collaborator Author

Review (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base f3ae1f8 to this head): SHIP at 8a0b088.

No P1/P2 findings.

…4311-carry

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextApp/SidebarContextMenus.swift
…p-type guardrail)

The type holds only daemon models (TabModel, DaemonStore) and its mark
check; nested in NotificationCenterService it grew a CmuxNextApp file.

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

Copy link
Copy Markdown
Collaborator Author

Review (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base 3f6df90 to this head): SHIP at 9638e53.

No P1/P2 findings.

@cmux-bot
cmux-bot Bot merged commit 8735e30 into feat-cmux-next Oct 30, 2026
168 of 174 checks passed
@cmux-bot
cmux-bot Bot deleted the lane/attn-24311-carry branch October 30, 2026 20:43
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 9638e536 Deployed Oct 30, 2026 by teamleaderleo via wait for same-key tree publisher #84622
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