Skip to content

cmux NEXT sidebar: harness icons with stable colours on agent rows, no routine status words - #27586

Closed
teamleaderleo wants to merge 7 commits into
feat-cmux-nextfrom
lane/sidebar-think-tank
Closed

teamleaderleo wants to merge 7 commits into
feat-cmux-nextfrom
lane/sidebar-think-tank

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Leo (2026-10-29): "all of these icons that are literally all the same icon, that is terrible ... one of these is Codex, one of these is Claude ... randomize the colors."

Applies the merged sidebar design spec (leo-workspace #1513): every agent or session row shows a harness icon with a stable per-item colour fallback, no type label repeated on child rows, no routine status words in row text, and hover controls held while their menu is open.

Root cause

Remote chats and Chief subagents passed the raw acpmux harness id as the row's brand id. A harness id is not a brand id: codex maps to the OpenAI mark only through AgentBrandCatalog.brand(for:). So Codex sessions resolved to no mark and drew the generic glyph. SidebarItemInfo.agentBrand(forHarness:) now maps the id at each source (remote chats, Chief subagents, Priority).

What changes

  • Harness marks. Priority rows now draw their session's mark (SidebarPriorityEntry.brand, filled in by AgentPriorityRanking). Codex, Claude and other catalog harnesses draw their own marks. When a harness has no registered mark, the row falls back to a person glyph.
  • Stable fallback colours. When a harness has no registered brand mark, the glyph is tinted with SidebarItemInfo.stableAgentColor(for: id). That is GroupColor.unset, an FNV hash, so a session keeps one colour across launches and machines. This covers Priority rows, Chief subagent rows, remote machine chats, and harness workspaces' agent marks. Registered marks keep their current tint.
  • No status words. Priority rows used to show a chip with "Needs you", "Done", "Failed" and the like. Now they show only a working duration, and the indicator dot carries the state. The words stay in the accessibility label.
  • Untitled Chief children. A subagent with no task title used to read "Subagent" on every row under the Chief header. Now its title is empty, it is identified by its icon, and "Subagent" stays in its accessibility label (and in the pane's More menu).
  • Workspace marks. A harness workspace with no registered icon or brand now draws its kind's symbol in its stable colour, where before it drew no mark.
  • Hover-menu hold. A workspace item's more and close controls stay revealed while the menu opened by its hover more button is open (showsMenu). The right-click context menu is left as it is: the spec rule covers a menu opened by the hover-revealed control, and holding the pill on right-click would be a new look nobody asked for.

Geometry

Row heights, insets and the trailing column are unchanged. The Priority row's new mark uses the sidebar's shared columns (SidebarStyle.iconColumnCenterX / leadingTextX, the same columns Home, pinned and workspace rows use). It adds no local inset. Its title and preview start on that text column.

Overlap

pr-overlap was read through REST PR file lists, because the broker refuses GraphQL. None of these PRs makes the same fix; they touch the same files:

Chief precautions: no changed path is in the rulebook's Chief list. SidebarTransientItem+Chief.swift and ChiefPaneTools.swift live in CmuxNextAgentLanes.

Tests

  • SidebarAgentIdentityTests (new): Codex and Claude sessions resolve to their own marks (Priority and Chief rows); stable, differing fallback colours; the Priority mark and title on the shared columns; no visible status word, with the words kept in accessibility; the hover controls held while the menu is open.
  • ChiefSidebarItemTests: untitled children have an empty title.
  • HomeDockTabRowToolsTests: the subagents menu keeps "Subagent" for an untitled child, while its sidebar row stays icon-led.

Observed / Not run

  • Observed: scripts/cmux-next/prepush-gate.py reports no new violations.
  • Observed: independent Codex reviews (gpt-6-astra, high, fast). The first three returned FIX, and each finding is fixed in this branch: a cross-file private read; the menu-title test; a fallback NSColor resolved outside the theme scope; raw harness ids used as brand ids. The verdict at the final head follows in a comment.
  • Not run from this lane: this is a broker-only lane VM with no fleet client, so cmux-ci here runs only test. Swift compile and tests run in this PR's CI (fleet test-compile). The before/after capture is requested from the coordinator: cmux-ci capture e5a2e56a4feb5758276275a4c652336e4552a2de --state scripts/cmux-next/media/states/sidebar-icon-column.json --pr 27586 (before) and the same at the head (after).
  • Not covered by a capture fixture: the Priority view needs live agent chats. The unit tests above cover its mark and columns.

Capture

The earlier sidebar-icon-column.json capture showed no agent rows, so it can't show this change. Capture-only commits add a DEBUG fixture, debug.sidebar_agent_fixture plus scripts/cmux-next/media/states/sidebar-agent-identity.json. It seeds Codex, Claude and an unregistered acme-agent harness across every Priority state, and adds two untitled Chief subagents and one titled one. The commits sit on their own branches and are not part of this PR's head:

  • before = e5a2e56a + fixture: cmux-ci capture da54380d547db72fea2e1ac12ee4156e9d26a32c --state scripts/cmux-next/media/states/sidebar-agent-identity.json --pr 27586 (lane/sidebar-agent-fixture-before)
  • after = 4c2b948e + fixture: cmux-ci capture 58926031dfe8be62e03f7c39657247d551410d2e --state scripts/cmux-next/media/states/sidebar-agent-identity.json --pr 27586 (lane/sidebar-agent-fixture-after)

The printed Markdown for both goes here once a capture host runs them. This lane VM has no fleet client.

Capture at the head

cmux-ci capture 6a1cf77759209812215bea418f36b51f8c6f9ca2 --state scripts/cmux-next/media/states/sidebar-icon-column.json --pr 27586 (the showcase sidebar with the Debug row badge preview rows; it has no agent rows, so it shows the unchanged geometry, not the new marks):

Capture steps-fce8c13efa at 6a1cf7775920 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Changelog

  • Changed: Sidebar agent rows show each session's harness icon, with a stable colour when the harness has no icon; Priority rows no longer repeat status words.

risk: normal

Agent session: agent session

🤖 Generated with Claude Code

…atus words

Priority rows draw their harness mark on the sidebar's shared icon and text
columns; a harness with no registered mark tints its glyph with a stable
per-session color. Untitled Chief children drop the repeated "Subagent"
label (kept in accessibility), Priority rows show only a working duration
(status words move to the accessibility label), and a workspace item's
hover controls stay revealed while its menu is open.

Sidebar-Look: Leo 2026-10-29 "all of these icons that are literally all the same icon, that is terrible ... one of these is Codex, one of these is Claude ... randomize the colors"
Agent-Session: https://cmux.com/deeplink/agent?id=aid-435b44433b52d27a4338
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r-think-tank

# Conflicts:
#	plans/cmux-next/sidebar-owner.md
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@cursor

cursor Bot commented Oct 29, 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.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 6a1cf77: 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=pr27586 -f ref=lane/sidebar-think-tank -f platform=macos -f backend_mode=local

@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Found 22 test failures on Blacksmith runners:

Failures

Test View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='', primary='failure')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='', primary='failure')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='', primary='success')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='', primary='success')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-16vcpu-ubuntu-2404', primary='failure')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-16vcpu-ubuntu-2404', primary='failure')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-16vcpu-ubuntu-2404', primary='success')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-16vcpu-ubuntu-2404', primary='success')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-32vcpu-ubuntu-2404', primary='failure')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-32vcpu-ubuntu-2404', primary='failure')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-32vcpu-ubuntu-2404', primary='success')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-32vcpu-ubuntu-2404', primary='success')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-4vcpu-ubuntu-2404', primary='failure')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-4vcpu-ubuntu-2404', primary='failure')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-4vcpu-ubuntu-2404', primary='success')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='blacksmith-4vcpu-ubuntu-2404', primary='success')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='ubuntu-24.04', primary='failure')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='ubuntu-24.04', primary='failure')
View Logs
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='ubuntu-24.04', primary='success')/
test_every_linux_nightly_job_takes_a_runner_set_member (main.NightlyTrustedRouting.
test_every_linux_nightly_job_takes_a_runner_set_member) (job='attest-nightly-remote-dae
mon', runner='ubuntu-24.04', primary='success')
View Logs

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

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

@cursor

cursor Bot commented Oct 29, 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.

…tension; menu-title test

agentMarkFallbackColor was private to WorkspaceRowView.swift but read in
WorkspaceRowView+Rendering.swift (a compile error). The Chief subagent menu
keeps "Subagent" for an untitled child while its sidebar row stays
icon-led, so HomeDockTabRowToolsTests checks that split.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f
@cursor

cursor Bot commented Oct 29, 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.

…heme scope

The row cached a resolved NSColor at configure time, so an unknown
harness's mark kept a stale light/dark variant. It keeps the GroupColor
and resolves it in updateLayer's performWithTheme.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f
Remote chats, Chief subagents and Priority rows passed the raw harness id
("codex") as the brand id, so Codex sessions resolved to no mark and drew
the generic glyph. SidebarItemInfo.agentBrand(forHarness:) maps it through
AgentBrandCatalog.brand(for:) at each source, and SidebarPriorityEntry
carries the brand.

Sidebar-Look: Leo 2026-10-29 "all of these icons that are literally all the same icon, that is terrible ... one of these is Codex, one of these is Claude ... randomize the colors"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f
@cursor

cursor Bot commented Oct 29, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra, high, fast; independent of the authoring Claude lane): SHIP at 4c2b948

The reviewer checked the full diff against e5a2e56a4feb: brand normalization, package dependencies, theme-scoped tint resolution, reuse state, menu behavior and affected test expectations. It ran no build or tests. Earlier rounds at 2d86568, 4b63191 and d7fb9f0 returned FIX; their findings are fixed in this branch (listed in the description).

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Sidebar icon column: before and after

Both captures use the state scripts/cmux-next/media/states/sidebar-icon-column.json, taken from each commit.

Before: e5a2e56

Capture steps-fce8c13efa at e5a2e56a4feb (fleet build, capture mini, text checked for private data)

Light Dark
light dark

After: 4c2b948

Capture steps-fce8c13efa at 4c2b948edea3 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Agent session: agent session

…r-think-tank

# Conflicts:
#	plans/cmux-next/sidebar-owner.md
@teamleaderleo

teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

Resolves the WorkspaceRowView.configure conflict with #27530: the harness
fallback glyph moves into Self.agentMarkImage (so the offscreen title column
matches the drawn mark), and the stable fallback colour comes from
Self.agentMarkFallbackColor.

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

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol high, next-review): SHIP at 6a1cf77

No blocking findings.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Ownership moved to the agent session that took the claim above: the previous owner's host is unreachable. The new owner carries these commits onto its own branch with a base merge (it keeps #27912's identical isHovered || showsMenu line), opens a carry PR linking this one, and this PR closes with a link once the carry lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 24 h, and no lane holds a lease on it. The orphan sweep could not merge feat-cmux-next in: conflicts in Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceRowView+Rendering.swift, plans/cmux-next/sidebar-owner.md. Listed for a lane to resolve.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Carried in #28327 (same commits on current base, authorship kept). Closing this in favour of #28327.

teamleaderleo added a commit that referenced this pull request Nov 1, 2026
…arries #27586) (#28327)

* Sidebar: harness marks and stable colors on agent rows, no routine status words

Priority rows draw their harness mark on the sidebar's shared icon and text
columns; a harness with no registered mark tints its glyph with a stable
per-session color. Untitled Chief children drop the repeated "Subagent"
label (kept in accessibility), Priority rows show only a working duration
(status words move to the accessibility label), and a workspace item's
hover controls stay revealed while its menu is open.

Sidebar-Look: Leo 2026-10-29 "all of these icons that are literally all the same icon, that is terrible ... one of these is Codex, one of these is Claude ... randomize the colors"
Agent-Session: https://cmux.com/deeplink/agent?id=aid-435b44433b52d27a4338
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Sidebar: workspace mark fallback color readable from its rendering extension; menu-title test

agentMarkFallbackColor was private to WorkspaceRowView.swift but read in
WorkspaceRowView+Rendering.swift (a compile error). The Chief subagent menu
keeps "Subagent" for an untitled child while its sidebar row stays
icon-led, so HomeDockTabRowToolsTests checks that split.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f

* Sidebar: resolve a workspace mark's fallback color inside the row's theme scope

The row cached a resolved NSColor at configure time, so an unknown
harness's mark kept a stale light/dark variant. It keeps the GroupColor
and resolves it in updateLayer's performWithTheme.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f

* Sidebar: map a session's harness id to its brand before drawing its mark

Remote chats, Chief subagents and Priority rows passed the raw harness id
("codex") as the brand id, so Codex sessions resolved to no mark and drew
the generic glyph. SidebarItemInfo.agentBrand(forHarness:) maps it through
AgentBrandCatalog.brand(for:) at each source, and SidebarPriorityEntry
carries the brand.

Sidebar-Look: Leo 2026-10-29 "all of these icons that are literally all the same icon, that is terrible ... one of these is Codex, one of these is Claude ... randomize the colors"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-70a6853e5c9cdac5cc9f

* fix(sidebar): a harness kind change re-anchors an offscreen workspace's tabs

The carried fallback mark makes a harness workspace with no registered mark
draw its kind's symbol beside the title, so the kind is a title-column input:
SidebarRowIndex re-lays out the unchanged child tabs when it changes, and
the offscreen-parent test covers it.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-f8805b2d0f3b1303441e

---------

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

Copy link
Copy Markdown
Collaborator Author

Superseded: its commits were carried, with authorship kept, in #28327, which merged as e758a4d on current feat-cmux-next. The cut-short swift test and crash-class reds at 6a1cf77 are this stale head's; #28327 passed the CmuxNext compile and crash-class rules at its own head. Closing.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 6a1cf777 Deployed Oct 30, 2026 by teamleaderleo via wait for same-key tree publisher #81342
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant