Repository navigation
Sidebar hover preview: count and name each agent's running subagents; History drops inbox notices - #30439
Conversation
…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
Bugbot needs on-demand usage enabledBugbot 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. |
|
Fleet compile: |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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>
| 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())); |
There was a problem hiding this comment.
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>
| // 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 ?? "" |
There was a problem hiding this comment.
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>
| control, | ||
| doing: work.doing.clone(), | ||
| // A restart keeps no provenance of the turn: its History line stays. | ||
| notice: false, |
There was a problem hiding this comment.
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")") |
There was a problem hiding this comment.
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>
| #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 |
There was a problem hiding this comment.
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>
| detail.subagentNames += chat.subagentNames | |
| detail.subagentNames = Array((detail.subagentNames + chat.subagentNames).prefix(5)) |
|
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 Default changesThis pull request changes 9 defaults at
Signed off on this commit by Merge receipt: merged as Regenerate the snapshot with 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
|
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
There was a problem hiding this comment.
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
|
This PR added a new panic-ratchet hit on feat-cmux-next. #30439 added |
…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.
Bugbot needs on-demand usage enabledBugbot 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. |
|
Found 13 test failures on Blacksmith runners: Failures
...and 3 more test failures. View all on Blacksmith
|
…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.
|
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:
|
…-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>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Leo (2026-11-01), on the sidebar hover preview of a lead agent:
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).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.subagents_runningmux record. That record andprocess_updateare nowsession_changedkinds, 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.
WorkspaceHoverCardWork..startedevent markedisNotice. The History leaves it out, so it lists the person's prompts and what happened; the "Prompts / Worked" stats still count its work time.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
listbecause 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(theapp.sample.runningagentsglyph, tabular numerals) anddesign/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:
usageStatsin the same files, but it does not count running subagents in the card. ItssubagentsLivecomes from harness transcript reads every 5 s, only when a client asks for usage. Whichever PR lands second will have additive conflicts to resolve.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
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).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
python3 scripts/cmux-next/prepush-gate.pyreported no new violations.debug.hover_cards {gallery}"Running work · list/summary/inline".Agent session: agent session
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith 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.
subagentsRunning,subagentNames(first 5), andcommandsRunningto 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..startedevent: History omits it, and the Prompts/Worked stats still count its work.Written for commit 10ea2a9. Summary will update on new commits.