Skip to content

Sidebar hover preview: count and name each agent's running subagents; History drops inbox notices - #30439

Merged
teamleaderleo merged 3 commits into
feat-cmux-nextfrom
lane/ux-hovercard-subagents
Nov 1, 2026
Merged

teamleaderleo merged 3 commits into
feat-cmux-nextfrom
lane/ux-hovercard-subagents

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Leo (2026-11-01), on the sidebar hover preview of a lead agent:

"e.g. this hover preview being able to see the # of associated subagents and whatnot would be a lot more useful / like the details aren't even very useful / there's a lot of low hanging fruit"

His screenshot showed the hover preview of a workspace called "UI lead". Collapsed, it listed one agent chat row (the lead agent session) with a spinner and "Show details". Expanded, it said "Agent running · 41s", "Prompts: 10 · Worked 26m 52s", the harness and model, the last prompt, and a History list in which several entries were "[inbox] New messages from other agents in 1 thread..." notices. That agent was running about ten background subagents at the time, and none of them showed in the card.

acpmux (Rust) counts the work. No counting or classifying is in Swift.

  • SubagentTree (subagents.rs) tracks every running subagent (foreground or background, at any depth, live updates only), oldest first, with a label (its name, else its task, one line, cut to 60 characters).
  • Each chat's summary gets three new fields:
    • subagentsRunning: how many run now. Between turns only background ones count, because a foreground subagent ends with its turn even when the harness never says so.
    • subagentNames: the first 5 labels.
    • commandsRunning: the chat's running background commands, from the process registry.
  • Each change in the count is a subagents_running mux record. That record and process_update are now session_changed kinds, so the app and peers hear changes live.
  • turn.notice: true while the running turn was started by acpmux's inbox notice or a digest (prompt_line::is_notice), not by anyone's words.

The card (Swift) only renders it.

  • Each tab row in the hover preview starts its second line with "3 subagents · 1 command" (tabular digits), then its folder. A compact row has no second line, so it shows no count.
  • The expanded details get a "3 subagents · 1 command" line (the running tray's glyph) and then one line per running subagent, by name. This is WorkspaceHoverCardWork.
  • A turn started by an inbox notice becomes a .started event marked isNotice. The History leaves it out, so it lists the person's prompts and what happened; the "Prompts / Worked" stats still count its work time.
  • Nothing is removed: the details section, the History and every row stay.

Design choice. The gallery's new "Running work" cards show three versions of the expanded card:

  • list (chosen): a count line, then each subagent named on its own line.
  • summary: the count line alone.
  • inline: the count, then the names wrapped onto two lines.

I picked list because Leo's point was that the details should tell him something. A count alone says little more than the spinner already does, and names joined on one line get cut at the card's 280 pt width. The list follows the sidebar rule against repeating a type label on every row: the header line names the kind, and each line is just a name with an icon. Each chat sends at most 5 names; the count line always gives the total, and there is no "Show N more" (sidebar.md).

Follows leo-workspace design/sidebar.md (Hover previews; never "Show N more"; spinner for working state; no status words in rows), design/running-tray.md (the app.sample.runningagents glyph, tabular numerals) and design/overlay-surfaces.md (the card's existing glass and tokens; no new motion). The spec update is a separate leo-workspace notes PR.

Prior art:

Changelog

Added: the sidebar hover preview shows how many subagents and background commands each agent is running and names them in its details; its History no longer lists inbox notices.

Tests

  • Swift: WorkspaceHoverCardRunningWorkTests (an agent with N running subagents shows N in its tab row and the count and names in its details; an inbox-notice turn is absent from History, and the stats keep its work; the summary fields parse, and an older acpmux gives 0).
  • Rust: subagents::running_subagents_are_counted_with_their_names_from_start_to_end, hub::work_below_tests::running_subagents_reach_the_summary_and_each_change_is_recorded, prompt_line_tests::inbox_notices_and_digests_are_notices_and_messages_are_not, change_kind::running_work_changes_publish_a_session_change.

Observed / Not run

  • Observed: python3 scripts/cmux-next/prepush-gate.py reported no new violations.
  • Results of the fleet compile, the Swift suite and the cargo tests are posted as comments.
  • No capture yet. The gallery cards are debug.hover_cards {gallery} "Running work · list/summary/inline".

Agent session: agent session

🤖 Generated with Claude Code


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


Summary by cubic

Making the sidebar hover preview show what each agent is actually running: tab rows count each agent's running subagents and background commands, and the expanded details name the subagents. Inbox-notice turns drop out of History while their work still counts in the stats.

  • acpmux tracks every running subagent at any depth and adds subagentsRunning, subagentNames (first 5), and commandsRunning to each chat's summary; count changes and background-command updates now publish live as session changes. Subagent labels are their name or task, masked and cut to 60 characters so no credential reaches the summary.
  • Tab rows lead their second line with "3 subagents · 1 command" (tabular digits) before the folder; expanded details add the count and one line per named subagent.
  • Between turns only background subagents count, since a foreground subagent ends with its turn even when the harness never says so; a restarted turn keeps its History line because no provenance survives the restart.
  • A turn started by an inbox notice is now a non-prompt .started event: History omits it, and the Prompts/Worked stats still count its work.

Written for commit 10ea2a9. Summary will update on new commits.

View guided diff Turn on auto-fix

…m in details, drop inbox notices from History

acpmux counts what each chat runs below its turn on its summary: subagentsRunning
(every running subagent, any depth; between turns only background ones),
subagentNames (first 5), commandsRunning (running background commands), a
subagents_running mux record per count change and process_update as session
changes, and turn.notice for a turn acpmux's inbox notice or a digest started.

The hover card's tab rows lead their second line with "3 subagents · 1 command"
(tabular digits); the expanded details add the count line and one line per
running subagent (WorkspaceHoverCardWork, list style, chosen over summary and
inline in the gallery). An inbox-notice turn is a non-prompt start: History
leaves it out, the stats keep its work.

Sidebar-Look: e.g. this hover preview being able to see the # of associated subagents and whatnot would be a lot more useful / like the details aren't even very useful / there's a lot of low hanging fruit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@cursor

cursor Bot commented Nov 1, 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 teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Fleet compile: cmux-ci compile-check --package CmuxNext at 9678ef0 passed (job 89569824aaa968e3a39f3a7d, 339 s).

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11 issues found across 29 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceHoverCardGallery.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceHoverCardGallery.swift:87">
P2: This adds three cards to the sidebar gallery, so `theGalleryShowsEveryKind(tabs: false)` now gets 13 cards and fails its `count == 10` check. Update the expected sidebar count in `HoverCardSharedRowsTests.swift` to 13, and add a note that the count includes the running-work cards.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/WorkspaceHoverCardRunningWorkTests.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/WorkspaceHoverCardRunningWorkTests.swift:52">
P3: `contains("1")` also matches "10m", so this check passes even if the prompt count is wrong. Assert the exact prefix instead, e.g. `card.stats?.hasPrefix("Prompts: 1") == true`.</violation>
</file>

<file name="cmux-tui/crates/acpmux/src/hub/auto_resume.rs">

<violation number="1" location="cmux-tui/crates/acpmux/src/hub/auto_resume.rs:412">
P2: `prompted` defaults `notice` to false, and the carried-turn path that builds the next turn from a steer never sets it. A notice or digest steered into a running turn and then carried into the next turn would still show in History. Carry the steer's notice flag in `SteerSent` and apply `.noticed(...)` in `carried_turn`.</violation>
</file>

<file name="cmux-tui/crates/acpmux/src/hub/turns.rs">

<violation number="1" location="cmux-tui/crates/acpmux/src/hub/turns.rs:587">
P2: The `noticed` flag is computed from the head's provenance before the digest is built, so a digest turn whose head is a plain agent message is not marked as a notice and stays in History. In the `if digested` block below, also set `t.notice` from the digest provenance, next to `t.show(&line)`.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextBridge/SidebarMapping+Detail.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextBridge/SidebarMapping+Detail.swift:34">
P3: The workspace-level `subagentNames` concatenates each chat's five-name list without a cap, so a workspace with several agent chats shows far more than five subagent lines in the hover card. Cap the combined list at five to match the per-chat limit.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceTabHoverCardRow.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceTabHoverCardRow.swift:36">
P2: The `.monospacedDigit` design switches the whole `cwd` line from the bundled UI font (Inter, via `Typography.caption`) to the system monospaced-digit font. This line now carries folder paths and status words too, so they change typeface, not just the counts. Keep `Typography.caption` for the line, or apply tabular figures through a font feature without changing the family.</violation>

<violation number="2" location="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceTabHoverCardRow.swift:89">
P2: `cwd` truncates with `.byTruncatingMiddle` over the whole combined string, so the counts are not protected. The `tabCaption` comment says they "never cut", but a long folder can middle-elide the leading counts text. Render the counts in their own label or truncate only the folder portion.</violation>
</file>

<file name="cmux-tui/crates/acpmux/src/hub/tap.rs">

<violation number="1" location="cmux-tui/crates/acpmux/src/hub/tap.rs:297">
P2: `running_changed` compares only the count, so late labels or same-count child replacements never notify watchers and leave `subagentNames` stale. Track changes to the running snapshot, including labels, when deciding whether to publish.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextBridge/WorkspaceTimelineReader.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextBridge/WorkspaceTimelineReader.swift:42">
P2: The reader applies its event limit before the hover card removes `isNotice`, so inbox notices consume the read budget and can hide older real History entries. Filter notices while collecting or over-fetch until the requested number of non-notice entries is available.</violation>
</file>

<file name="cmux-tui/crates/acpmux/src/subagents.rs">

<violation number="1" location="cmux-tui/crates/acpmux/src/subagents.rs:214">
P2: Clearing `running` on harness shutdown changes the summary without publishing `subagents_running`, so hover watchers can keep showing subagents that no longer run. Emit the count change when `end_background` is applied.</violation>
</file>

<file name="cmux-tui/crates/acpmux/src/hub/hosts.rs">

<violation number="1" location="cmux-tui/crates/acpmux/src/hub/hosts.rs:1207">
P2: Restart recovery clears the notice flag for an in-flight inbox or digest turn, so the restored summary makes Swift record its notice text as a normal History prompt. Persist and restore the notice provenance (or derive it from the durable turn record) instead of forcing `false`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

return (name, HoverCardGalleryHost(body: card) { [weak card] in card?.applyColors() })
}
return tabCards + richCards
return tabCards + workCards(now: now) + richCards

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This adds three cards to the sidebar gallery, so theGalleryShowsEveryKind(tabs: false) now gets 13 cards and fails its count == 10 check. Update the expected sidebar count in HoverCardSharedRowsTests.swift to 13, and add a note that the count includes the running-work cards.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceHoverCardGallery.swift, line 87:

<comment>This adds three cards to the sidebar gallery, so `theGalleryShowsEveryKind(tabs: false)` now gets 13 cards and fails its `count == 10` check. Update the expected sidebar count in `HoverCardSharedRowsTests.swift` to 13, and add a note that the count includes the running-work cards.</comment>

<file context>
@@ -84,7 +84,39 @@ public struct WorkspaceHoverCardGallery {
             return (name, HoverCardGalleryHost(body: card) { [weak card] in card?.applyColors() })
         }
-        return tabCards + richCards
+        return tabCards + workCards(now: now) + richCards
+    }
+
</file context>

turn_seq: 0,
control,
doing: Default::default(),
notice: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: prompted defaults notice to false, and the carried-turn path that builds the next turn from a steer never sets it. A notice or digest steered into a running turn and then carried into the next turn would still show in History. Carry the steer's notice flag in SteerSent and apply .noticed(...) in carried_turn.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/acpmux/src/hub/auto_resume.rs, line 412:

<comment>`prompted` defaults `notice` to false, and the carried-turn path that builds the next turn from a steer never sets it. A notice or digest steered into a running turn and then carried into the next turn would still show in History. Carry the steer's notice flag in `SteerSent` and apply `.noticed(...)` in `carried_turn`.</comment>

<file context>
@@ -409,6 +409,7 @@ impl TurnInfo {
             turn_seq: 0,
             control,
             doing: Default::default(),
+            notice: false,
         }
         .shown_as(&super::prompt_line::prompt_line(text, client, None))
</file context>

Comment thread cmux-tui/crates/acpmux/src/hub/turns.rs Outdated
let turn = TurnInfo::prompted(client, &text, &turn_id, &prompt_id, control)
.shown_as(&super::prompt_line::prompt_line(&text, client, provenance.as_ref()));
.shown_as(&super::prompt_line::prompt_line(&text, client, provenance.as_ref()))
.noticed(super::prompt_line::is_notice(provenance.as_ref()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The noticed flag is computed from the head's provenance before the digest is built, so a digest turn whose head is a plain agent message is not marked as a notice and stays in History. In the if digested block below, also set t.notice from the digest provenance, next to t.show(&line).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/acpmux/src/hub/turns.rs, line 587:

<comment>The `noticed` flag is computed from the head's provenance before the digest is built, so a digest turn whose head is a plain agent message is not marked as a notice and stays in History. In the `if digested` block below, also set `t.notice` from the digest provenance, next to `t.show(&line)`.</comment>

<file context>
@@ -583,7 +583,8 @@ impl Hub {
         let turn = TurnInfo::prompted(client, &text, &turn_id, &prompt_id, control)
-            .shown_as(&super::prompt_line::prompt_line(&text, client, provenance.as_ref()));
+            .shown_as(&super::prompt_line::prompt_line(&text, client, provenance.as_ref()))
+            .noticed(super::prompt_line::is_notice(provenance.as_ref()));
         let retry = super::subagent_retry::is_retry(run.provenance.as_ref());
         if let Err(e) = self.start_turn(session, after_turn.as_deref(), no_queue, retry, turn) {
</file context>

Comment thread cmux-tui/crates/acpmux/src/hub/views.rs Resolved
// The second line: the chat's running subagents and commands, then the folder. A compact
// row (one line tall) has no second line.
let caption = showsFolder ? WorkspaceHoverCardWork.tabCaption(tab) : nil
cwd.stringValue = caption ?? ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: cwd truncates with .byTruncatingMiddle over the whole combined string, so the counts are not protected. The tabCaption comment says they "never cut", but a long folder can middle-elide the leading counts text. Render the counts in their own label or truncate only the folder portion.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceTabHoverCardRow.swift, line 89:

<comment>`cwd` truncates with `.byTruncatingMiddle` over the whole combined string, so the counts are not protected. The `tabCaption` comment says they "never cut", but a long folder can middle-elide the leading counts text. Render the counts in their own label or truncate only the folder portion.</comment>

<file context>
@@ -82,16 +83,20 @@ final class WorkspaceTabHoverCardRow: NSView {
+        // The second line: the chat's running subagents and commands, then the folder. A compact
+        // row (one line tall) has no second line.
+        let caption = showsFolder ? WorkspaceHoverCardWork.tabCaption(tab) : nil
+        cwd.stringValue = caption ?? ""
+        cwd.isHidden = caption == nil
         let status = Self.statusText(tab.state)
</file context>

Comment thread cmux-tui/crates/acpmux/src/subagents.rs Resolved
control,
doing: work.doing.clone(),
// A restart keeps no provenance of the turn: its History line stays.
notice: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Restart recovery clears the notice flag for an in-flight inbox or digest turn, so the restored summary makes Swift record its notice text as a normal History prompt. Persist and restore the notice provenance (or derive it from the durable turn record) instead of forcing false.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/acpmux/src/hub/hosts.rs, line 1207:

<comment>Restart recovery clears the notice flag for an in-flight inbox or digest turn, so the restored summary makes Swift record its notice text as a normal History prompt. Persist and restore the notice provenance (or derive it from the durable turn record) instead of forcing `false`.</comment>

<file context>
@@ -1203,6 +1203,8 @@ impl Hub {
                         control,
                         doing: work.doing.clone(),
+                        // A restart keeps no provenance of the turn: its History line stays.
+                        notice: false,
                     });
                     session.floor.last_turn_web.store(control == Control::Web, Ordering::SeqCst);
</file context>

#expect(!card.timeline.contains { $0.isNotice }, "the History lists no inbox notice")
#expect(card.timeline.map(\.text) == [nil, "Fix the build"])
// The stats count the person's one prompt, and the notice turn's work.
#expect(card.stats?.contains("1") == true, "stats: \(card.stats ?? "nil")")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: contains("1") also matches "10m", so this check passes even if the prompt count is wrong. Assert the exact prefix instead, e.g. card.stats?.hasPrefix("Prompts: 1") == true.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/WorkspaceHoverCardRunningWorkTests.swift, line 52:

<comment>`contains("1")` also matches "10m", so this check passes even if the prompt count is wrong. Assert the exact prefix instead, e.g. `card.stats?.hasPrefix("Prompts: 1") == true`.</comment>

<file context>
@@ -0,0 +1,88 @@
+        #expect(!card.timeline.contains { $0.isNotice }, "the History lists no inbox notice")
+        #expect(card.timeline.map(\.text) == [nil, "Fix the build"])
+        // The stats count the person's one prompt, and the notice turn's work.
+        #expect(card.stats?.contains("1") == true, "stats: \(card.stats ?? "nil")")
+        #expect(card.stats?.contains("10m") == true, "stats: \(card.stats ?? "nil")")
+    }
</file context>
Suggested change
#expect(card.stats?.contains("1") == true, "stats: \(card.stats ?? "nil")")
#expect(card.stats?.hasPrefix("Prompts: 1") == true, "stats: \(card.stats ?? "nil")")

// What every agent chat in the workspace runs below its turn, as acpmux counts it.
for chat in tabs.compactMap({ $0.agentSession.flatMap(turns.detail(for:)) }) {
detail.subagentsRunning += chat.subagentsRunning
detail.subagentNames += chat.subagentNames

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The workspace-level subagentNames concatenates each chat's five-name list without a cap, so a workspace with several agent chats shows far more than five subagent lines in the hover card. Cap the combined list at five to match the per-chat limit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextBridge/SidebarMapping+Detail.swift, line 34:

<comment>The workspace-level `subagentNames` concatenates each chat's five-name list without a cap, so a workspace with several agent chats shows far more than five subagent lines in the hover card. Cap the combined list at five to match the per-chat limit.</comment>

<file context>
@@ -28,9 +28,22 @@ extension SidebarMapping {
+        // What every agent chat in the workspace runs below its turn, as acpmux counts it.
+        for chat in tabs.compactMap({ $0.agentSession.flatMap(turns.detail(for:)) }) {
+            detail.subagentsRunning += chat.subagentsRunning
+            detail.subagentNames += chat.subagentNames
+            detail.commandsRunning += chat.commandsRunning
+        }
</file context>
Suggested change
detail.subagentNames += chat.subagentNames
detail.subagentNames = Array((detail.subagentNames + chat.subagentNames).prefix(5))

Comment thread cmux-tui/crates/acpmux/src/hub/tap.rs Resolved
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 10ea2a9: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30439 -f ref=lane/ux-hovercard-subagents -f platform=macos -f backend_mode=local

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

CI passes on 10ea2a9084 (run 41288546447 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.

Default changes

This pull request changes 9 defaults at 10ea2a908473 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardContent.swift:facts: "2afb5954795d3e3c2fd0a2377b9839bd6e62af50616bb5996862d04229a8724d" -> "d6385a5eabe45c951775809d959b8e8646aea09054c4d1ebaedb60be67b89957"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardContent.swift:make#: "78ec844d8c76889f2e3be019ac1d9177dbcab75d96b8cdd36be06ff786b433b3" -> "c43803aded11f32a79eb63b3786aa5586d19f466997537c67e9d00761b7d147b"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardWork.swift:countKind: (none) -> "9565cccab46b24f8925bbf81c947384a9fc304c2999e961547ef853a7587755b"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardWork.swift:counts: (none) -> "a2da9710b3fb201c511fcade68a9a48e2775ac6e504a05e466d617b8212958f2"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardWork.swift:facts: (none) -> "b7934a022ff9c4df739cb90928411ca73f5123ca1bde4e2c15619f26d7b9a59d"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardWork.swift:shipped: (none) -> "da98af3634fa7c4f768a331e0746af2e2b1835e805eed69e256f44c3972c2f2d"
  • tunable-source.CmuxNextSidebar/Logic/WorkspaceHoverCardWork.swift:subagentKind: (none) -> "112f9bd8c27dead39f72b9ac195bd7a456b3fa50f04e6ffe85613767bb1f655e"
  • tunable-source.CmuxNextSidebar/Strings+HoverCard.swift:commandsRunning: (none) -> "5b934d8597d52eb4c80b0922aa6c04e330d7e4216379cdc7229665b855011c88"
  • tunable-source.CmuxNextSidebar/Strings+HoverCard.swift:subagentsRunning: (none) -> "87c5624798119a0f3423505dea4b7ad6fba5570d645c554e7c39f7e69ffbdc20"

Signed off on this commit by review (subagent claude-opus-5-5 medium, post-merge).

Merge receipt: merged as 229803e8c54f with these defaults changed, signed off by review (subagent claude-opus-5-5 medium, post-merge).

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

Shipped in:

…heir turn

A subagent named by its task (its prompt) is masked with secret_scan::mask before it is
normalized and cut, so no credential reaches subagentNames. A new turn drops the turn
before's foreground subagents, so running_now(true) no longer shows them again.

Sidebar-Look: "e.g. this hover preview being able to see the # of associated subagents and whatnot would be a lot more useful"

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

Copy link
Copy Markdown
Collaborator Author

Review (codex, rev-30439-r2): SHIP at 8003d60

…ercard-subagents

# Conflicts:
#	cmux-tui/crates/acpmux/src/hub/auto_resume.rs
#	cmux-tui/crates/acpmux/src/hub/hosts.rs
#	cmux-tui/crates/acpmux/src/hub/mod.rs
#	cmux-tui/crates/acpmux/src/hub/tap.rs
#	cmux-tui/crates/acpmux/src/hub/turn_attestation_tests.rs
#	cmux-tui/crates/acpmux/src/hub/turns.rs
#	plans/cmux-next/sidebar-owner.md

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread cmux-tui/crates/acpmux/src/subagents.rs Resolved
@lawrencecchen

Copy link
Copy Markdown
Contributor

This PR added a new panic-ratchet hit on feat-cmux-next. #30439 added summary["turn"] in acpmux hub/views.rs and self.running[at] in subagents.rs, which made acpmux indexing_slicing 689 > 686. #30464 added &text[prefix.len()..] in link/seed/github.rs, which made cmux-tui string_slice 83 > 82. Job 1764d0cc925c9f12951dc4c3 shows both. #30478 fixes them forward with get/get_mut/split_at_checked and does not change behavior. Before you land, run cmux-ci run --class light --script scripts/ci/cmux-tui-rust-check.sh --arg panic --os linux --ref SHA.

lawrencecchen added a commit that referenced this pull request Nov 1, 2026
…x, cmux-host, cmux-tui, cmux-tui-core) (#30478)

* base red: panic ratchet, #30361's new JSON index reads use get

The Rust panic ratchet is red on feat-cmux-next since 72dc85d (#30361,
Cloud repository discovery), tip watcher job 63b147f0938fdb56741e7c83 at
4cd800a: clippy::indexing_slicing over the baseline in four crates
(acpmux 694 > 686, cmux-host 1 > 0, cmux-tui 836 > 831,
cmux-tui-core 880 > 853). The other commits in 4b15acd..4cd800a
add no index or slice in production code.

This rewrites every serde_json index read #30361 added in production code
(cloud_repo_mcp.rs, github_repos.rs, cli/cloud_repo.rs, cloud_repos/
engine.rs, local.rs, runtime.rs, store.rs) as get / pointer reads, the one
IndexMut as get_mut, and the `command[..2]` slice in cli.rs as
`command.get(..2)`. Behavior is the same: a missing key read through get
compares and converts the same as the Null that indexing returned
(`v["k"] == "x"` is `as_str() == Some("x")`, `v["ok"] != true` is
`as_bool() != Some(true)`, `v["ref"] != json!(r)` keeps Null for a missing
key). The baseline is not raised.

* base red: panic ratchet, #30439's and #30464's new index and string slice use checked forms

After the merge of feat-cmux-next 1dfc4dd, the panic ratchet at
9d4a172 (job 1764d0cc925c9f12951dc4c3) is still red on two rows
that later base commits added:
- acpmux indexing_slicing 689 > 686: #30439 (229803e) added
  `summary["turn"].is_object()` in hub/views.rs and two
  `self.running[at]` in subagents.rs.
- cmux-tui string_slice 83 > 82: #30464 (1b7b01c) added
  `&text[prefix.len()..]` in link/seed/github.rs.

Now `summary.get("turn").is_some_and(Value::is_object)`,
`self.running.get_mut(at)` (`at` is a position in the same Vec, found
just above with no change between, so the slot is always there), and
`text.split_at_checked(prefix.len())` (None exactly where the old
`text.get(..prefix.len())` was None). No behavior change.
@cursor

cursor Bot commented Nov 1, 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.

@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026

Copy link
Copy Markdown

Found 13 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp648yam1s/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpx0wk_inp/summary-missing.json (live):/summary-missing.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs

...and 3 more test failures. View all on Blacksmith

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

@teamleaderleo
teamleaderleo merged commit 229803e into feat-cmux-next Nov 1, 2026
124 of 137 checks passed
@teamleaderleo
teamleaderleo deleted the lane/ux-hovercard-subagents branch November 1, 2026 09:39
lawrencecchen added a commit that referenced this pull request Nov 1, 2026
…lice use checked forms

After the merge of feat-cmux-next 1dfc4dd, the panic ratchet at
9d4a172 (job 1764d0cc925c9f12951dc4c3) is still red on two rows
that later base commits added:
- acpmux indexing_slicing 689 > 686: #30439 (229803e) added
  `summary["turn"].is_object()` in hub/views.rs and two
  `self.running[at]` in subagents.rs.
- cmux-tui string_slice 83 > 82: #30464 (1b7b01c) added
  `&text[prefix.len()..]` in link/seed/github.rs.

Now `summary.get("turn").is_some_and(Value::is_object)`,
`self.running.get_mut(at)` (`at` is a position in the same Vec, found
just above with no change between, so the slot is always there), and
`text.split_at_checked(prefix.len())` (None exactly where the old
`text.get(..prefix.len())` was None). No behavior change.
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium, post-merge): SHIP at 10ea2a9

This PR merged with no review at its head, so this is an after-the-fact review. No blocking findings.

Follow-ups:

  • [follow-up] SidebarMapping+Detail.swift:31-35: the workspace's subagentNames combines every chat's list with no overall limit, so N busy chats give a card 5×N lines tall. Trim the combined list to 5; the count line already shows the total.
  • [follow-up] SidebarMapping+Detail.swift:41-45 and SidebarMapping.swift:204: Self.running(tab) falls back to AgentTurnStateStore.shared instead of the turns that is passed in. Pass turns through.
  • [follow-up] acpmux/src/subagents.rs:211-215: end_background clears running but writes no subagents_running record. Write one when the count changes.
  • [follow-up] acpmux/src/hub/hosts.rs:1212: a turn rebuilt after a daemon restart gets notice: false, so an in-flight notice prompt can show up in History again. Log notice in turn_started and restore it on replay.
  • [follow-up] acpmux/src/server/change_kind.rs:46: process_update pushes a full summary for every background command. Merge these pushes if the volume grows.

cmux-bot Bot added a commit that referenced this pull request Nov 1, 2026
…-work cards (#30985)

theGalleryShowsEveryKind(tabs: false) expected 10 workspace cards; #30439
added one Running work card per WorkspaceHoverCardWork.Style on purpose, so
the gallery has 13. The expectation now counts those styles.


Agent-Session: https://cmux.com/deeplink/agent?id=aid-9124da39adbff74677d9

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was successfully deployed

2 inactive deployments
artifacts — 10ea2a90 Deployed Nov 1, 2026 by teamleaderleo via add the Windows daemon to the tree #94939
ci-routing-agent — 10ea2a90 Deployed Nov 1, 2026 by teamleaderleo via cmux-tui tree preflight #94939
sentry-dsyms — 10ea2a90 Deployed Nov 1, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #94939
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.

2 participants