Skip to content

Notifications: agents that finish together share one banner per workspace (cx-kz6m0.1) - #20960

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
feat-cmux-next-notification-digest
Oct 15, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
feat-cmux-next-notification-digest

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

When several agents finish in one workspace within a few seconds, cmux NEXT posted one banner per agent. Now they share one: the first finish posts as usual, and each other agent that finishes in the same workspace within 10 s replaces the delivered banner with one titled "3 agents finished", subtitled with the workspace, whose click opens the agent that finished last. The digest's body is the newest notification's body. This is parity row 3 of cmuxterm-hq#2099 (the old app's coalescing queue) and proposal 3 of #20891.

  • Only finished turns join a burst. Approvals, questions, plan reviews and errors keep their own banners, and so do reply banners and OSC 7501 alerts.
  • One agent finishing twice isn't a burst; both banners post as before.
  • An agent the user has read (banner click, a look at the pane, a timeout) leaves its burst, so a later finish in that workspace posts on its own, with its sound.
  • The digest withdraws every banner the burst still shows, including an agent's earlier banner when it finished twice.
  • The digest is filed under the newest agent's tab. Reading that tab withdraws it, while reading an older agent's tab leaves it showing.
  • Bursts are per workspace, so another workspace's finish keeps its own banner.
  • The notification list keeps every row. Only the macOS banners are replaced, and the replacement is silent because the first banner already played the sound.
  • The window is a one-shot DemandTimer with the service's injectable clock, so there are no polling timers.

The logic lives in CmuxNextBridge/FinishedBannerBursts.swift, outside CmuxNextApp (SW14 size cap). DaemonNotification.isFinishedTurn and TabModel.holdsUnreadAsk(besides:) moved there from NotificationCenterService, which keeps only the wiring: join on a finished turn, withdraw what the digest replaces, and leave the burst on acknowledge. The digest title is a new plural string in NotificationsPanel.xcstrings with all 21 locales (machine translated, needs_review). CmuxNextApp shrinks by 5 lines: on the merge with current feat-cmux-next, check-app-size.sh reports 113727 lines, 8 under the cap of 113735. Package.swift is unchanged.

Verification

  • Red at 557d83b (test only, plus the withdrawn record it reads): run-swift-testing-suites.sh Packages/macOS/CmuxNext, fleet step 590700b67f366a85eca9a763. FinishedBannerBurstTests failed with 2 issues: five separate banners showed and no "3 agents finished" banner was posted. It was the only failing suite.
  • Green at 3693906: fleet step 513783524f4ce9d20e09f062, where FinishedBannerBurstTests passed. The only other red there was SidebarInsertWhileDisplayAsleepTests (motion alpha on a headless worker), which doesn't touch this change.
  • Before pushing, these passed locally: check-concurrency, crash_ratchet, check-no-godfiles, check-state-roots, check-system-blue, check-test-notification-centers and check-l10n.
  • Second green at the same head: fleet step 373554004465860d05cd8af6, where FinishedBannerBurstTests passed and the same unrelated sidebar motion suite was the only red.
  • Release compile (check-release-compile.sh) at 3693906: fleet step 095d574134b9752c716d7270, BUILD SUCCEEDED.
  • Review fixes: the red commit adds two cases for a read agent and for an agent that finishes twice. At that red (fleet step 44707ebf36255d07159be374), FinishedBannerBurstTests failed with 3 issues: the read agent was still counted in a silent digest, and the first agent's earlier banner stayed beside the digest.
  • After the fix, at 36e60b7: green twice (fleet steps 9de40ed5f134c90c039869d0 and a6da7951f80b8ffa5aa5ab55), with every suite green. Release compile is fleet step d8c52f9ab3cc53a34a0fce30, BUILD SUCCEEDED. The pre-push checks above passed again.
  • After the move to CmuxNextBridge, at 6469478: green twice (fleet steps b45d9e57f0f1c4687eaeb7de and ca77a940a7e4750ec0b1ff25), with every suite green. Release compile is fleet step c9bca8148f4914fbf77ba508, BUILD SUCCEEDED. The pre-push checks and freeze-check passed. The tests now read the replaced banners from the burst rather than from a DesktopNotifier.withdrawn field, which is gone.
  • Not done: no capture of real banners in a running app yet.

Bead: cx-kz6m0.1 (parent cx-kz6m0).

Base reds in cmux-next checks, not this change and not gating (coordinator): No literal state roots (LegacyChannelSession.swift), Type scale (BrowserFitFrameView.swift), Package conventions lint (BuiltInAdBlockerSetting.swift). The compile queue check is stuck and does not gate; the fleet Release compile above covers it.

Changelog

  • Changed: Agents that finish in one workspace within a few seconds now share one notification banner that counts them, instead of one banner each.

🤖 Generated with Claude Code

teamleaderleo and others added 3 commits October 15, 2026 00:33
…r per workspace

Red: three agents finishing in one workspace still post three banners.
DesktopNotifier now records withdrawn banner ids (debug and tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agents that finish in one workspace within 10 s share one banner
("3 agents finished", subtitled with the workspace) that replaces the
delivered one and opens the newest. Approvals, questions and errors keep
their own banners; the notification history keeps every row. The window
is a one-shot DemandTimer. debug.notifications lists withdrawn banners.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2172aecc-4c21-4fc8-a3a2-b448100c0929

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

all web/size checks green

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Not verified: macOS jobs did not run: compile and app tests were skipped on 646947834c; ci-status is green without them.

CI passes on 646947834c (run 38719579215 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

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.

@blacksmith-sh

blacksmith-sh Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs

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

cmux-autofix[bot] and others added 6 commits October 15, 2026 07:58
…es way to the digest

Red: a read agent still counts in a silent digest, and an agent's earlier
banner stays beside the digest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ry burst banner

Acknowledging a tab removes its agent from its burst (an empty burst
closes), so a later finish posts on its own with its sound. The burst
tracks every banner it still shows, and the digest withdraws them all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…App size cap)

FinishedBannerBursts moves out of CmuxNextApp into CmuxNextBridge; the App
keeps a few lines of wiring in NotificationCenterService (join on a
finished turn, withdraw what the digest replaces, read on acknowledge).
The burst records the banners it replaced for tests instead of a new
DesktopNotifier field. The digest body is now the newest notification's
body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…side the burst

DaemonNotification.isFinishedTurn and TabModel.holdsUnreadAsk(besides:) leave
NotificationCenterService, and the burst decides which notifications join,
so the App keeps only wiring under its size cap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo merged commit 062af3f into feat-cmux-next Oct 15, 2026
99 of 100 checks passed
@teamleaderleo
teamleaderleo deleted the feat-cmux-next-notification-digest branch October 15, 2026 12:40
teamleaderleo added a commit that referenced this pull request Oct 15, 2026
…tions

Keeps #20960's finished-banner bursts beside the approval wiring: an
acknowledge reads both, and approvals (warnings) never join a burst.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant