Skip to content

cmux NEXT Home: no stale divider line through the Chief chat after the list clamps - #23998

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
chief-ui-split-divider
Oct 22, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
chief-ui-split-divider

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

live-qa on nightly 3a63d6d (Home/Chief pane 655-1100 px wide): a 1 px full-height line ran through the Chief chat at the list's old 320 pt place, black in light and dark, while the real divider sat at the clamped width.

Why

HomeSidebarSplitView.layout() calls super.layout() first, and NSSplitView places its divider's layer there, at the current position. Then the split clamps the list (place(target) → setPosition), which moves the columns but not the divider layer until a later layout. The chat column is see-through, so the stale layer showed through it.

Change

After place(target) in layout(), lay out once more so the divider layer follows. Widths, clamps and behavior don't change. (setWidth and resetWidth go through a normal layout and were already correct; a test pins both.)

Tests

HomeSidebarSplitDividerTests reads the split's divider layers (the split view's own sublayers) after a clamp, and after a width set outside layout, in light and dark.

  • Red at the test-only commit a2bf972: cmux-ci run --class light --script scripts/ci/package-test-lane.sh --ref a2bf9726ead37c9e9c2ef32a12401d3143b5cfbf --arg=suite --arg=Packages/macOS/CmuxNext --arg=HomeSidebarSplitDividerTests: aClampedDividerLeavesNoLineAtItsOldPlace fails in light and dark (a divider layer stays at 320 pt and isn't at the list's width); the width-set test passes.
  • Green at the head a1b4d1b: the same command with --ref a1b4d1b641b96519e1a695e0bacb4e8498b594cc --arg=HomeSidebarSplitDividerTests,HomeNarrowSidebarTests: both suites pass (aws-m4pro-7).
  • cmux-ci compile-check --ref a1b4d1b641b96519e1a695e0bacb4e8498b594cc --app: passed.

Observed / Not run

Observed: the red and green runs above on the aws fleet (Xcode 26.6), and the app compile. Not run: the app on screen; a capture-mini before/after follows in a comment.

Changelog

Fixed: no stray line through the Chief chat when its pane is narrow.

No capture: the fix is a layer position, which the divider-layer frame tests read directly in light and dark; the real-app before/after is being taken on a capture mini and will be added as a comment.

live-qa report: the stray 1 px line at x=974 (feat-cmux-next nightly 3a63d6d).

Agent session: cosmic-gray

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits October 21, 2026 17:56
…pt place

live-qa on nightly 3a63d6d: a Home column too narrow for the list's 320 pt
clamps the divider left, and a 1 px line stays at the old place, drawn
through the see-through Chief chat. NSSplitView draws its divider in a
layer of its own; the test reads those layers' frames after the clamp and
after a width set outside layout, light and dark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray
NSSplitView places its divider's layer in its own layout pass. The Home
split clamps the list after that pass (place() in layout()), so the layer
stayed at the old position and drew a 1 pt line through the see-through
Chief chat. Lay out once more after placing. No width, clamp or behavior
changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

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

Review a1b4d1b: 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=pr23998 -f ref=chief-ui-split-divider -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 5363032; does not block

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by chief-ui on cosmic-gray · session

@teamleaderleo teamleaderleo added the risk:low Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 12 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpb3fj3rfk/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpkgois0tx/summary-fail.json (live):/summary-fail.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
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
nightly cmux-tui resolve/nightly cmux-tui resolve View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')
View Logs

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

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

@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:low Risk tier (docs/ci/risk-tiers.md) labels Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next crash-class rules / cmux-next crash-class rules is red on 11 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (claude-reviewer-23998): SHIP at a1b4d1b

Correctness first, read-only review of 0ba602a4...a1b4d1b6 (no build run here).

  • HomeSidebarSplitView.swift:90: the second super.layout() is a static call to NSSplitView's implementation, so it can't re-enter our layout(). It runs only inside the !placed || mismatch branch. If AppKit marks the view as needing layout again, the next pass finds sidebarWidth == target and does nothing more, so it can't loop. No new loop risk beyond what place() already had.
  • splitViewDidResizeSubviews (:151-157): the extra pass runs after placing is reset. The width is still not saved, because the guard needs NSSplitViewDividerIndex, and a layout or adjust pass doesn't set it. The first super.layout() at :77 already ran on every pass outside placing, so the save behavior is unchanged. ResizeInvariantTests.theHomeTranscriptKeepsItsMinimumThroughResizes (clamp to 76, then grow back to 320) would catch a clamped width being saved by mistake. That test should be green on this head.
  • Behavior: widths, clamps, holding priority and drag paths are unchanged. A drag runs no layout pass, and setWidth/resetWidth don't touch the new line.
  • Test: the !frames.isEmpty check stops it from passing when no divider layers exist. If a future macOS stops hosting dividers as split-owned sublayers, the test fails loudly rather than silently passing, which is acceptable. #if DEBUG around setWidth matches the source and is fine, since tests build Debug. Swift 6: $0.delegate === split (CALayerDelegate? vs NSView) and \.frame on @MainActor are fine. The local split shadowing Self.split is legal.

No blocking findings. CI on this head was still running at review time.

@teamleaderleo
teamleaderleo merged commit ab08d8a into feat-cmux-next Oct 22, 2026
@teamleaderleo
teamleaderleo deleted the chief-ui-split-divider branch October 22, 2026 02:06
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Oct 22, 2026
…n; the chat gets the width (#24006)

* cmux NEXT Home: regression test, a lone Chief in a narrow column gets no avatar-only column

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

* cmux NEXT Home: a lone Chief in a narrow column takes no avatar-only column; the chat gets the width

The avatar-only list holding one conversation (and no note or requests) is hidden in
HomeSidebarSplitView, with its divider, so the chat spans the split and compose stays at its
top-left. A second conversation or a column wide enough for names brings the list back.
Debug Settings > Home > "Avatar list for one conversation" (home.loneConversationRail, off)
keeps the column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

* cmux NEXT Home: a list the person dragged to avatars keeps its column and divider

Fold the lone conversation's list only when the window squeezes the person's own width to
avatars; a width they dragged there keeps the divider to drag it back out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

* cmux NEXT Home: the resize invariant test lists two conversations

ResizeInvariantTests.theHomeTranscriptKeepsItsMinimumThroughResizes used an
empty list, which now folds away once it would show avatars only (a lone
Chief takes no column). The test checks the list shrinking to its avatar
minimum, so it gives the list two conversations, as HomeLoneChiefRailTests
does for the list that keeps its avatar column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

* cmux NEXT Home: the split divider tests cover the clamp and the lone-conversation fold

HomeSidebarSplitDividerTests (from #23998) built the split around an empty
list. On this branch an empty list folds away once the clamp would leave it
avatars only, so the clamp test was really testing the fold. Its list now
holds two conversations, as in ResizeInvariantTests. A new folded variant
(one conversation, 400 pt) checks that the list folds and that no divider
line stays at the old 320 pt place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

* cmux NEXT Home: a folding list's divider layer moves in the same layout

After the merge of #23998, layout() runs NSSplitView's layout a second time
after place() so that the divider's layer follows a clamp. The lone-
conversation fold returned before that second pass, so the hidden divider's
layer could stay at the list's old edge. The fold now runs the same extra
pass when it hides or shows the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16057-0fea-7933-80f2-cec81447d873&host=cosmic-gray

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — a1b4d1b6 Deployed Oct 22, 2026 by teamleaderleo
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