Repository navigation
cmux NEXT: unread ring appears steady, stays until its pane is clicked, then blinks out (classic parity, GUI agents too) - #22678
Conversation
|
Correctness review (subagent), head 8c42df8 Round 1 on the first version: FIX
Round 2: PASS. Workspace switches re-run the pass through My own check: the branch diff is 4 files (two notification service files, |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Not verified: macOS jobs did not run: compile and app tests were skipped on CI passes on Written by web and size checks: green |
This comment has been minimized.
This comment has been minimized.
|
Bead |
…ped in (red) Austin (2026-10-20): the ring must persist until he clicks into that specific pane. The default dismissal, focus, read a pane when it merely took focus, and a mouse-down read the window's focused tab whatever lay under the pointer. noteMouseDown now takes the click location (still unused here), so these tests fail until the fix: the default is still focus, and a click in the other pane or outside the panes reads the focused pane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed in Austin (2026-10-20), on the dev build of the previous approach: the ring cleared without a click; it must persist until he goes in and clicks on that specific pane. Lawrence's u2414 words (2026-10-19) were the same: "you click and it gets dismissed". - notifications.dismissal defaults to click: a click in the pane, a key typed in it, or opening the notification reads it. Focus alone (a workspace switch, a keyboard move, Cmd+1-9, the palette) keeps the ring. focus stays a choice in Settings. - A mouse-down reads the pane under the pointer (layout hit test over the visible panes), not the window's focused tab: a click on the sidebar, the titlebar or another pane no longer clears the focused pane's ring. A page's own window or a top page keeps the focused-tab read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8c42df8 to
4dc3b8f
Compare
…age window hit-test its pane Review findings on the click default: - A turn that finished, or an OSC 7501 done, in a pane on screen was read at arrival whatever the dismissal mode, so its ring never showed. That read on sight is now the focus mode's; under click it posts no banner (cx-kxa2, cx-slk1h) and keeps the ring until the pane is clicked or typed in. WatchedDoneReadTests pin both modes. - A click in a child window (a Chromium page's) hit-tests the pane in the workspace window it belongs to, instead of reading the focused tab. - Overlapping panes where the click moved no focus read nothing rather than an arbitrary pane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
… gets its timeout Re-review of fc67117: the early return for a finish seen in a visible pane skipped the feed driver's not-alerted note (the item could then be mirrored to the iPhone though the person watched it) and the timeout dismissal's deadline. One helper, keepSeenUnread, does both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… pane is read (red) Austin (2026-10-20): in cmux classic a blue ring just appears when the agent is done, and the blink plays when he goes into the pane and it dismisses; cmux NEXT had the order switched (blink on arrival, a plain fade on read). The overlay now hears whether its pane is focused, and a dismiss animation seam exists that returns nothing yet, so these tests fail until the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pane is read Austin (2026-10-20), on the click-only dev build: cmux NEXT had classic's order switched. The ring blinked when the agent finished and simply vanished when he went into the pane. In cmux classic a blue ring just appears, and the flash plays as the notification is dismissed. - notifications.attention.style defaults to steady (blink and pulse stay choices): the ring appears clearly visible with no blink. - MotionGate.attentionDismissAnimation: blinkCount blinks at the peak, ending with no ring (one fade under Reduce Motion, none with animations off or no ring style). - PaneOverlayView plays it when the mark goes away while its pane is focused (the person clicked or typed into it); a ring read elsewhere (Mark Read in the sidebar, a mute) just fades. ScreenContentView passes the pane's focus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of f47f16e: the flash keyed on the pane having focus, so a ring on the focused pane also blinked when Mark Read, a timeout, a mute, Dismiss Highlight or another device cleared it. NotificationCenterService now records tabs read by a click, a key or an open (entryReads), and WorkspaceContentController hands the layout the panes whose mark that read removed (LayoutModel.attentionReadByEntry) just before it removes them; only those blink. Static status indicators (cx-sya4n) get one fade instead of blinks. BlinkRateCapTests covers the dismiss flash; stale "blink is the default" comments updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Austin (2026-10-20): the blue attention ring should also mark a GUI agent chat pane when the agent finishes, as it does a terminal agent's. acpmux reads a turn that ends in a shown chat at once (cx-n8ou) and posts no notification for it, so nothing marked the pane. - AgentTurnStateStore.onTurnEnded: a session's turn went from working to anything else (the watch closing is not an end). - NotificationCenterService.agentFinished: the chat tabs of that session, by ring generation; attentionMarks rings their panes. Going into the pane under the dismissal policy (click, key, open by default) clears it with the dismiss blink; Mark Read and Dismiss Highlight clear it quietly; a muted workspace draws no ring. New behavior rather than a regression, so AgentTurnRingTests land with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Correctness reviews (subagents) since the first review comment. Head 65aae85.
Fleet run on 65aae85: 12 suites green (step 454e5af5). Not labeled ready-to-land: waiting on Austin's dogfood and the docs/mdm autofix. |
…made it stale (defaults-snapshot base red) (#23056) * test: check-stamp fails a pull request only for the settings sources it changed Red: defaults-snapshot fails every pull request and base push while the base autofix catches up (base 6143f81: stale for Localizable.xcstrings, NotificationModes.swift, NotificationPreferences.swift and SettingsSchema+Appearance.swift, none of them changed by those PRs), and the message points at a REPAIR.md row this repository does not have. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c6d-a1d2-7fc2-9458-92c6bdcb7b4d&host=huge-blue * cmux-next guards: a stale settings export fails only the event that changed its source defaults-snapshot ran check-stamp on the whole tree, so once a merge landed a settings source without its exports (d986b17, #22678, #23028; none changed a default), every pull request and every base push was red until the base autofix caught up, which merges minutes apart kept from happening for hours. check-stamp --base now fails only for sources changed since the base (the merge commit's base tip, or a push's parent) and prints the inherited ones as a warning. The stale message names the PR autofix and regenerate-settings-exports.sh instead of a REPAIR.md row this repository does not have. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c6d-a1d2-7fc2-9458-92c6bdcb7b4d&host=huge-blue * cmux-next generated files: inherited stale settings exports warn here too; #22275 follow-ups The generated-files job's check-stamp failed every pull request on the base's stale exports the same way; it now passes --base HEAD^1 as defaults-snapshot does. #22275's review follow-ups: autofix-areas.sh, regenerate-settings- exports.sh and the generated-files comments still described check-fresh and the snapshot, and the fork hint's `git commit -am` left files the patch adds unstaged (now `git apply --index`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c6d-a1d2-7fc2-9458-92c6bdcb7b4d&host=huge-blue * test: check-stamp --base fails a head's own stamp edit and passes past 20 inherited sources Red (review of #23056): a head that takes an old stamp passes as stale on the base, and with over 20 stale sources the "and N more" line fails every head. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c6d-a1d2-7fc2-9458-92c6bdcb7b4d&host=huge-blue * defaults guard: check-stamp --base judges each stale source before the list is cut The inherited split ran on the printed lines: a head whose own stamp entry differs from the base's passed as stale on the base, and past 20 sources the "and N more" line failed every head. stamp_freshness now splits the full list and needs both the source bytes and the stamp entry to be the base's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c6d-a1d2-7fc2-9458-92c6bdcb7b4d&host=huge-blue --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…unread tab The pane attention ring (notification blue) drew around any pane with an unread tab, so a Markdown file shown in front of a background agent tab got a blue ring it never asked for. Classic's ring lived on the notifying terminal; now the ring marks a pane only while the tab the window shows in it is unread, or is an agent chat whose turn ended (#22678). The background tab keeps its own dot. Co-Authored-By: Claude <noreply@anthropic.com>
Fleet export (run-swift-testing-suites.sh export-settings) at e29cfed, then defaults_guard.py snapshot; check-fresh passes. The export also catches up source changes already on feat-cmux-next that were never exported: the notification defaults of #22678 (dismissal click, attention style steady, moveToTop off), sidebar.sessionTree (#21814), agents.trust.*, and the inactive tab style help text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#22678 made the ring appear steady and blink out when the person goes into its pane. Classic also had: the dismiss flash as a double blink at full strength (0, 1, 0, 1, 0, ease-out rises, ease-in falls), a glow on the ring and a stronger one on the flash, settings that turn the flash off (notifications.paneFlash) and keep typing from flashing (paneFlashOnTyping). Reduce Motion must show a static ring with no flash. These tests fail until the next commit.
…low, flash settings, static under Reduce Motion #22678 made the ring appear steady and blink out when the person goes into its pane. This brings over what classic's ring still had: - The dismiss flash is classic's FocusFlashPattern.doubleBlink: opacity 0, 1, 0, 1, 0 at even key times, ease-out rises, ease-in falls, full strength. Classic took 0.9 s; the 2 Hz cap holds it at one flash period (1 s). - The ring glows in its color as classic's did (0.35 opacity, 3 pt at rest; 0.6, 6 pt while it flashes out), with a precomputed shadow path. - notifications.attention.flash and notifications.attention.flashOnTyping (Settings > Notifications > Attention Ring, cmux.json); classic's notifications.paneFlash and paneFlashOnTyping migrate to them. - Reduce Motion: the ring shows static at its rest and goes with no flash. The color is notifications.attention.color, default Palette.notificationBlue (the unread dot's token).
|
Shipped in:
|
…23754) Leo (2026-10-21): "the model response does a double blue ring pulse", which was agreed not to be the default. #22678 made an agent chat's pane ring in the notification blue when its turn ends, even in the chat being watched, and blink twice as the person clicks or types into it. - The agent turn ring is opt-in: Debug Settings notifications.attention.agentTurnRing (AgentTurnRing.tunable), off by default. Off, a turn that ends in a shown chat rings nothing, as before #22678 (acpmux reads it at once). Terminal notification rings are unchanged. - On, the ring is a hairline (one device pixel) in the pane border color with no glow, never the notification blue, through its dismiss flash too (AttentionMark.hairline). - AgentTurnRingTests: a finished turn rings nothing by default; the opt-in ring is a neutral hairline and a later notification's ring is blue again. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…chats stay calm (#23968) * cmux NEXT: a finished reply no longer rings its chat pane by default Leo (2026-10-21): "the model response does a double blue ring pulse", which was agreed not to be the default. #22678 made an agent chat's pane ring in the notification blue when its turn ends, even in the chat being watched, and blink twice as the person clicks or types into it. - The agent turn ring is opt-in: Debug Settings notifications.attention.agentTurnRing (AgentTurnRing.tunable), off by default. Off, a turn that ends in a shown chat rings nothing, as before #22678 (acpmux reads it at once). Terminal notification rings are unchanged. - On, the ring is a hairline (one device pixel) in the pane border color with no glow, never the notification blue, through its dismiss flash too (AttentionMark.hairline). - AgentTurnRingTests: a finished turn rings nothing by default; the opt-in ring is a neutral hairline and a later notification's ring is blue again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * cmux NEXT: the attention ring is themed and set per pane kind; agent chats stay calm Leo (2026-10-21): "I don't think we should have blinky on turn end for GUI... and if we have any kind of blinky, it should be themed/customizable." - Color: the ring and its dismiss flash default to the theme accent (Palette.accentFill), never the fixed notification blue; a picked notifications.attention.color or source color still wins. The sidebar unread dot keeps the notification blue. - notifications.attention.ringStyle: glow (classic's, default), ring (the stroke alone, no glow at rest or in the flash) or none (no ring layer). - notifications.attention.terminals (on) and agentChats (off): which panes ring. agentChats replaces #23754's Debug agentTurnRing toggle and its hairline look, so there is one switch; off, a turn end in an agent chat rings and flashes nothing, and turning it off clears a ring showing. - blinkCount keeps setting the flashes; Reduce Motion stays static. - Settings rows, cmux.json parser, agent-settable keys and strings in 21 languages; AttentionThemedFlashTests covers the defaults, the accent, ring style none and ring, the count and Reduce Motion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * cmux NEXT showcase: seeded notifications never land on the Home dock tab live-qa (nightly 3a63d6d): the Home/Chief dock pane showed the attention ring and its tab the unread dot with an empty chat, in scene-composer, scene-settings and steps captures. DebugShowcase.seed posted its three sample notifications to the focused pane's first tab, which on a showcase launch is the home-dock page tab. They now go to the first non-page tab, or to the ledger alone when there is none; the panel still lists them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * cmux NEXT: each pane kind has its own ring look and count; agent chats ring as cmuxterm-hq#2959 says The debate verdict (cmuxterm-hq#2959): agent chat off by default (none); on, a ring, not a glow, one short pulse then steady until clicked or typed in, only on panes not being looked at; accent color, count 1, bursts coalesced; Reduce Motion static. - notifications.attention.terminals and agentChats are now looks (glow, ring, none): terminals glow, agent chats none. They replace the single ringStyle and the two toggles, so each kind has one setting. notifications.attention.agentChatBlinkCount (1) is the chat's flash count; blinkCount (2) stays the terminal's. - AttentionMark.agentChat picks the pane's look in the overlay (AttentionSettings.surface), also through its dismiss flash. - A turn end in the chat the person is looking at rings nothing; a finish within 900 ms of the last pulse rings at rest (AttentionMark.quiet). - Tests: no mark, ring, glow, pulse or flash on an agent pane at the defaults; its own look and count when on; the viewed chat and the burst. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * cmux NEXT: drop the AgentTurnRing toggle the base merge brought back; catalog in base order The squash of #23754 moved the merge base before it, so the merge took the base's AgentTurnRing Debug tunable back (nothing reads it; agentChats replaces it) and wrote Localizable.xcstrings in the branch's key order. Remove the tunable again, and take the base catalog with the four new keys inserted, so the diff is the 528 added lines only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * Rebuild the settings catalog from base plus the four attention keys The merge driver reordered the catalog again; take base's copy and insert only this PR's keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * Attention ring: look none stops a running flash; seed a terminal; prune quiet finishes Codex review at 278ff23: switching the look to none mid dismiss-flash left the flash and its glow running; the showcase seed could pick an agent chat tab; quietAgentFinishes kept ids after a read, ack or dismiss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray * Attention ring: a look without glow stops a running flash glow Codex re-review at 02cbd03: switching glow to ring mid dismiss-flash left the flash glow animating over the zeroed shadow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
UnreadRingDismissTests and AgentTurnRingTests asserted the click default from #22678; they now expect focus to read the tab and keep the click-mode checks under an explicit .click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ixes #25662) (#25701) * test(next): attention clears on selection and a showing ring stays as it is (red, #25662) Fails on the base: the default dismissal is click, so selecting the pane or entering its workspace keeps the ring and an event on the watched pane rings it again; a further event on a showing ring replays its arrival swell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(next): pane attention is one on/off state, cleared on selection (#25662) Attention stacked: after the pane was selected the ring came back several times before it cleared. Since #22678 the default dismissal was click, so selecting the pane or entering its workspace kept the ring, every later event on the pane the person was looking at rang it again, and each event on a ring that already showed replayed its arrival swell. - notifications.dismissal defaults to focus again, as in cmux classic: selecting the pane, including by entering its workspace, reads it at once and fully, and an event on the viewed pane sets no ring. click stays a choice in Settings. - A ring that already shows stays as it is on a further event (no replayed animation); once cleared, a new event turns it on again. Takes back #22678's click default at the request of its author. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Ring tests: focus is the default dismissal again UnreadRingDismissTests and AgentTurnRingTests asserted the click default from #22678; they now expect focus to read the tab and keep the click-mode checks under an explicit .click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Overlay: a mark that arrived with no ring still shows when the look turns on Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Regenerate settings exports: focus is the default dismissal; release note says when workspace entry clears Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
This makes cmux NEXT's blue unread pane ring behave the way Austin asked on 2026-10-20, matching cmux classic's ring.
notifications.attention.stylenow defaults tosteady;blinkandpulsestay available.notifications.dismissalnow defaults toclick;focusstays a choice. Then the ring blinksblinkCounttimes and goes away, as classic's dismiss flash does. A ring cleared any other way (Mark Read, a timeout, a mute, Dismiss Highlight, another device) fades without the blink.donethat finishes in a visible pane keeps its ring underclick. It posts no banner (cx-kxa2, cx-slk1h), the feed is told it didn't alert, and the timeout dismissal still gets its deadline.AgentTurnStateStore.onTurnEndedfeedsNotificationCenterService.agentFinished. Mark Workspace Read, Mark All Read and Clear All clear those rings too.Takes back 78680d5 (pushed directly on 2026-10-19, no PR), which set the
focusdismissal default. Why: Austin dogfooded it and rings cleared before he clicked the pane. Lawrence's u2414 words were also "you click and it gets dismissed".Changelog
Testing
Command:
cmux-ci run --class light --script scripts/ci/package-test-lane.sh --arg=suite --arg=Packages/macOS/CmuxNext --arg=<suites>UnreadRingClickReadTestsfails. A click in the other pane read the focused pane (ack surface:1), and a click outside the panes read one too. The default tests fail onfocus.blink.scripts/cmux-next/prepush-gate.py: no new violations.Observed / Not run
22678-unread-ring-click-onlyand22678-unread-ring-steady-flash, which led to these changes. Tag22678-unread-ring-gui-agents(1549a2a) is with him now.docs/mdm/*still list the old defaults until the autofix regenerates them. TheagentTurnEndedtab lookup and theobserveAttentionentry-read collection have no direct test. Nothing was run on the full CmuxNext suite.🤖 Generated with Claude Code