Skip to content

fix(sidebar): empty groups show only their header - #30298

Merged
teamleaderleo merged 3 commits into
feat-cmux-nextfrom
lane/sidebar-empty-header
Nov 1, 2026
Merged

teamleaderleo merged 3 commits into
feat-cmux-nextfrom
lane/sidebar-empty-header

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Empty workspace groups now show only their header at rest. The header's + stays reachable on hover, keyboard focus and accessibility actions; dragging a workspace into an empty group highlights that header. Full layout and fast fold no longer insert “No workspaces · drag one here”.

Leo, 2026-11-01: “what do you feel about this placeholder situation? idk doesn't that plceholder text seem a bit wack?”

The gallery compares three native versions: the previous placeholder row, header-only (chosen), and an always-visible header +. Each includes rest, hover and drop states in light and dark at 2x. Header-only avoids an extra row while keeping the existing creation and drop actions.

Validation: focused tests cover header-only geometry, fold/full-layout agreement, dropping on the empty header, transient drag highlight, and hover + creation. Test-only red reference: 86fa5cfa7461; implementation head follows it. Fleet compile/test evidence follows. Static prepush gate passes; the lane has no Swift compiler. Gallery artifacts are follow-up visual evidence, not a merge gate.

Risk: limited to projecting an empty group and its drop highlight. Group persistence and last-workspace close behavior are handled separately in #30292. No new settings or defaults.

Design: leo-workspace design/sidebar.md; recorded in plans/cmux-next/sidebar-owner.md. Replaces the old placeholder treatment, preserving its create/drop actions. Prior art checked: #7061, #23182, #24581, #25669 and #21835; none duplicates this presentation fix.

Changelog: Empty sidebar groups keep a compact header with creation available on hover.

Agent session: agent session


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


Summary by cubic

Empty sidebar groups now show only their header; the placeholder row is removed from both full layout and fast fold. The header’s + remains available on hover, keyboard focus, and accessibility actions, and highlights when a workspace is dragged into the group.

Written for commit dd4841a. Summary will update on new commits.

View guided diff Turn on auto-fix

Sidebar-Look: what do you feel about this placeholder situation? idk doesn’t that plceholder text seem a bit wack?
Agent-Session: https://cmux.com/deeplink/agent?id=aid-f310a9408dab5731f3da
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent read-only): SHIP at fb8af65. No code blockers; fleet compile pending. The owner independently checked the source diff and preserved header creation and drop paths.

@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 dd4841a: 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=pr30298 -f ref=lane/sidebar-empty-header -f platform=macos -f backend_mode=local

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

CI passes on dd4841a415 (run 41281281342 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 2 defaults at dd4841a415d5 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextSidebar/Logic/SidebarLayout+EmptyGroup.swift:appendEmptyRow: "600ffab8948486fda70d191d6b92203e152808fe83cf6b60fb0e8387d4d14437" -> (none)
  • tunable-source.CmuxNextSidebar/Logic/SidebarLayout.swift:make: "ff7cca0a50ab2cce281680dc12d8948a3a56bb18d4083f38e31f842a3ad8916b" -> "adaaf8b1228691f756abda0cfe4491bbfd70f966733aaa2be8a698e2fdc66142"

Signed off on this commit by review (subagent read-only).

Merge receipt: merged as eff592676b41 with these defaults changed, signed off by review (subagent read-only).

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

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent read-only): SHIP at dd4841a. Rechecked against merged base ff74759: the source/test delta is unchanged; only the sidebar design-log conflict needed resolution. No blocking findings. The original head app compile passed; merged-head compile is in flight. Design/sidebar.md update merged as leo-workspace#2164.

@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.

2 issues found and verified against the latest diff

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/Tests/CmuxNextAppTests/SidebarEmptyGroupGalleryTests.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/SidebarEmptyGroupGalleryTests.swift:77">
P3: This gallery writes `sidebar-empty-group-gallery/` and `sidebar-empty-group-gallery.tar` into `Packages/macOS/CmuxNext`, but `.gitignore` has no entries for them. Add `Packages/macOS/CmuxNext/sidebar-empty-group-gallery/` and `Packages/macOS/CmuxNext/sidebar-empty-group-gallery.tar` next to the other gallery entries.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/SidebarListView+PointerEnd.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/SidebarListView+PointerEnd.swift:127">
P2: The check uses the cached model members, so it misses groups made empty by the current drag's excluded workspace. Use the displayed header's filtered `childCount` so a one-member group still highlights when its member is being dragged out.</violation>
</file>

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

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

func highlightsDropGroup(_ id: GroupID) -> Bool {
if drag?.target == .intoGroup(id) || external?.proposal == .intoGroup(id) { return true }
guard case let .position(position)? = drag?.target, position.group == id,
groups[id]?.members.isEmpty == true else { return 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: The check uses the cached model members, so it misses groups made empty by the current drag's excluded workspace. Use the displayed header's filtered childCount so a one-member group still highlights when its member is being dragged out.

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/SidebarListView+PointerEnd.swift, line 127:

<comment>The check uses the cached model members, so it misses groups made empty by the current drag's excluded workspace. Use the displayed header's filtered `childCount` so a one-member group still highlights when its member is being dragged out.</comment>

<file context>
@@ -119,6 +119,15 @@ extension SidebarListViewComponents {
+    func highlightsDropGroup(_ id: GroupID) -> Bool {
+        if drag?.target == .intoGroup(id) || external?.proposal == .intoGroup(id) { return true }
+        guard case let .position(position)? = drag?.target, position.group == id,
+              groups[id]?.members.isEmpty == true else { return false }
+        return true
+    }
</file context>
Suggested change
groups[id]?.members.isEmpty == true else { return false }
displayed.row(for: .group(id))?.childCount == 0 else { return false }

@Test(.enabled(if: ProcessInfo.processInfo.environment["CMUX_TEST_REQUIRE_GUI"] == "1"))
func renderThreeVersions() throws {
let root = AANestedGroupsGalleryTests.packageRoot
let out = root.appending(path: "sidebar-empty-group-gallery")

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: This gallery writes sidebar-empty-group-gallery/ and sidebar-empty-group-gallery.tar into Packages/macOS/CmuxNext, but .gitignore has no entries for them. Add Packages/macOS/CmuxNext/sidebar-empty-group-gallery/ and Packages/macOS/CmuxNext/sidebar-empty-group-gallery.tar next to the other gallery entries.

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/SidebarEmptyGroupGalleryTests.swift, line 77:

<comment>This gallery writes `sidebar-empty-group-gallery/` and `sidebar-empty-group-gallery.tar` into `Packages/macOS/CmuxNext`, but `.gitignore` has no entries for them. Add `Packages/macOS/CmuxNext/sidebar-empty-group-gallery/` and `Packages/macOS/CmuxNext/sidebar-empty-group-gallery.tar` next to the other gallery entries.</comment>

<file context>
@@ -0,0 +1,100 @@
+    @Test(.enabled(if: ProcessInfo.processInfo.environment["CMUX_TEST_REQUIRE_GUI"] == "1"))
+    func renderThreeVersions() throws {
+        let root = AANestedGroupsGalleryTests.packageRoot
+        let out = root.appending(path: "sidebar-empty-group-gallery")
+        try FileManager.default.createDirectory(at: out, withIntermediateDirectories: true)
+        var html = "<meta charset='utf-8'><title>Empty group designs</title><style>body{font:16px system-ui}section{display:flex;gap:16px}img{width:280px;height:500px}figure{margin:0}</style><h1>Empty group designs</h1><p>Chosen: headerOnly. No extra row; + on hover; group highlight during a drop.</p>"
</file context>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Validation at dd4841a: fleet app compile passed (job bd27666713acc32241d7d7a8, 57 s). Static prepush gate passed. Independent exact-head SHIP is above. Current checks report no failures; this Swift-only change does not route the webview suites. Native gallery/test step 3c6c1125d06b39226723a3cc continues at the original head fb8af65 (source/test delta identical after the base merge); its artifact is follow-up evidence.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo
teamleaderleo merged commit eff5926 into feat-cmux-next Nov 1, 2026
137 of 148 checks passed
@teamleaderleo
teamleaderleo deleted the lane/sidebar-empty-header branch November 1, 2026 06:50
@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026

Copy link
Copy Markdown

Found 2 test failures on Blacksmith runners:

Failures

Test View Logs
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g/
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g
View Logs
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)/
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)
View Logs

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

This branch was previously deployed

1 inactive deployment
ci-routing-agent — dd4841a4 Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #94271
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