cmux next layout: closing a column beside a chat no longer leaves a blank workspace

Merged
LU
17d ago
+266-5

closing a tab beside a chat could leave the whole workspace blank until you went home and back. two causes, both in the layout's pane motion:

Summary

  • hidden workspace kept a frozen spring. a collapse that started while the workspace was hidden left its pane mid-motion, parked off screen. hiding a layout now ends its pane motion, and showing one restarts any motion left over (ScreenContentView settle, LayoutRootView live).
  • closing a column did not clamp the strip's shown offset. with the strip scrolled to the column being closed (the files tree beside a chat, for example), the shown offset stayed past the new end, so the chat drew off screen. removing a column now clamps the shown offset as well as the target, and a carried pane keeps animating (ColumnScrollReducer, ScreenContentView+Scrolling).

split out of #21315, where these landed while dogfooding the chat viewer; nothing here is chat-specific.

Testing

  • red first, then the fix, for each: LayoutHiddenMotionTests (b7f015d4201 then fb09e22d4c4) and ColumnCloseMotionTests (57af02221d0 then a763d4fd82d). swift tests run in ci only.
  • lint-ios-package-conventions.sh clean. check-concurrency.sh and crash_ratchet.py report nothing in this pr's files; their current hits are all on feat-cmux-next itself (HomeEngine, Browser, cmux-tui-core and others).
  • scripts/verify-local.py --affected origin/feat-cmux-next: swift syntax, defaults parity and feature flags pass; package-groups fails on the base's workspace file, which this pr does not touch.

Changelog

Fixed: closing a tab beside a chat no longer leaves the workspace blank.


Summary by cubic

Fixes a cmux next layout bug where closing a column (for example, the files tree) beside a chat left the whole workspace blank until you went home and back; the branch also carries a few unrelated changes that landed while the fix was in review.

Layout fix

  • Hiding a workspace now ends its pane motion, and showing one restarts any leftover motion plus a pending screen switch, so a collapse that started while hidden no longer parks its pane off screen.
  • Removing a column clamps the strip's shown offset as well as its target; the clamp is column-only, so closing a row springs the survivor into view.

Also on this branch

  • New acpmux cli-agent makes any prompt-in, reply-out CLI an ACP harness, with a unii example profile and end-to-end tests.
  • ghostty-vt ports tmux's terminal-emulator regression tests as golden tests and enables grapheme clustering (DEC mode 2027) by default to match the Ghostty viewer.
  • The opencode Chief now enables and switches implementation based on the model its turns really run on, refuses an owner off the paid list with 409 chief_claude_unavailable, and posts "This model is not available for your team" instead of ending a refused turn silently.
  • The CI autofix registers the CmuxNextMobileHost targets and drops the stale key.browser.focusSearch binding and setting.mobile.allowIPhoneConnections default.