Repository navigation
cmux-next: a new workspace draws at its place from the first frame; add Before Current Workspace - #23071
cmux-next: a new workspace draws at its place from the first frame; add Before Current Workspace#23071austinywang wants to merge 93 commits into
Conversation
…y frame (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… selected; add Before Current Workspace - workspaces.newPlacement gets beforeCurrent (app slot, settings choice and strings, daemon slot) - a create that waits for the daemon (link, folder, browser workspace) reads the rule at the request, not after its hop - a window showing a top page has no current workspace (the parked one is not selected) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- top-page test uses History (Home is no longer a top page) - quick-press test requires each press to select its workspace - daemon list order: the current workspace anchors only from the machine section and never as Home; the fallback stays below a leading Home row - rustfmt; document the top-page exception and the daemon's own first place Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me and state; rustfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lawrence 2026-10-18 on NIGHTLY: the new row drew above the Accounts & billing group, then moved below Scratch. Red: on the sidebar document the placement goes to the personal order, which the document does not show. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in the turn it lists (cx-qbktz) From #21914: the document took the placement (SidebarDocWiring.handle(.reorder), since #22593), but the sidebar rebuilt shown only an observation turn later, so a new row drew in the document's unplaced tail, after every group, for a frame, then jumped to its slot. SidebarBridge.place now rebuilds shown in the same turn (SidebarDocStore.reshow). Unlike 21914's version, reshow rebuilds only shown: no adopt and no remote-close check over a stale machine set (its review's finding 1). Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g presses and give the daemon the test's settings - SidebarDocStore keeps the items of the last show (lastShownItems) for the remote-close check, so a reshow in between no longer hides a remote workspace that closed meanwhile - the quick-press test samples the sidebar while the presses run - the daemon reads the test's cmux.json (CMUX_NEXT_CONFIG_FILE) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Correctness review (subagent), findings and resolutionRound 1, at
Round 2, at The reviewer traced the path.
|
|
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)
Unclear: CI failed on
Failures:
A web test can import code this PR changes without being one of its files: Matched log linesNot re-run automatically: Written by red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 0ae1413 to compare; do not merge until green; see lane-rules Tour of Default changesNo defaults change at |
|
|
This comment has been minimized.
This comment has been minimized.
|
Base finding, not from this PR: Status at head
|
…rent workspace The daemon placed a new workspace by workspaces.newPlacement against the session's active workspace, a legacy default the app's windows never move. With afterCurrent or beforeCurrent its first place was beside another workspace, which showed for a frame before the app's placement moved it (Austin: "it thinks I selected a different workspace"). create-workspace now takes current: the workspace key the creating window shows. The app sends it from every create that places by the setting, and the daemon places the new row against it: beforeCurrent/afterCurrent beside it, and top/bottom inside its group (right after it, last), as the app does. An older daemon ignores the field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…create name none Review of cba8533 (REVISE): - the create's client current is captured into WorkspaceCommitIntent at prepare and re-scoped around its apply, as EffectCommitKind::Patch carries the placement, so it survives the commit moving to the journal writer thread (cx-ags0) - create-workspace takes places_by_setting: the client places by the setting with current, or with none when its window shows a top page; before, a create from Home named no current and the daemon fell back to its active workspace - the app sends the rule (WorkspaceCreation placedBy:); a wire test of create-workspace over JSON; the command spec lists both params; stale comment in NewWorkspacePlacements.rule Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ewhere goes first, not last sync_row anchored a new workspace after its previous row in the personal order; when that row was not a sibling in the document (Home in its own section, a pinned row, a row the document does not place), the new row went to the end of the machine section. With top (right after Home) and beforeCurrent the confirmed row drew at the bottom for a frame before the app's placement moved it. sync_row now anchors after the nearest earlier sibling, else first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…document places it Fleet traces: the confirmed row of a new workspace still drew once at the bottom when the workspace list reached the app before the document placed it. Two client-side causes, both fixed: - SidebarDocStore.show adopted every unplaced live workspace at the end of its section; a workspace the window is about to place (pendingPlacements) now gets its adopt with that placement's move instead (placesItself) - PendingWorkspaceRows dropped the press row as soon as the window listed the workspace, while the document still listed it last (unplaced); the press row now stands in until the document places it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a workspace It kept a create's press row for as long as the sidebar document did not place the workspace, and fleet step bb243d5833cfb7061e3c7617 showed no create settling at all (every NewWorkspacePositionTests setup and RapidWorkspaceCreateTests timed out). The document's auto-adopt skip (placesItself) stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fleet cb6ee59849c1ca5095e4568d at 3786955 compiled native test targets and passed all four managed-preference and six settings-export tests. Apply the exact generated schema; the only delta is the Look and Feel localization key.
|
Review (review_23071): SHIP at 42aaf90 Fresh correctness-first subagent review of PR #23071, owner manaflow-ai, agent review_23071, base The generated schema matches fleet artifact SHA-256 The primary agent independently checked the exact generated delta, worktree, remote head and plain-push gate. Fleet generation compiled native test targets and passed four managed-preference and six settings-export tests at parent |
|
Current head:
The remaining failed logs were read on this head. Chief fails the same The release-notary job has the two known RunsOnFallbackTests failures and an additional external Glaeda signing-hook-list freshness failure. The PR changes none of those test, hook-list or workflow inputs. The base run already shows signing-routing failures; the current hook hash is a moving external dependency, not a workspace-placement change. Additional executed Windows base evidence: base job at dcc7e59db6a46bac9a28d66ec1b2e7003f35f6de fails with the same 35 cmux-automations Unix-only API errors. That crate is unchanged by this PR. This supersedes the earlier limitation that only skipped base artifact jobs had been found. Autoland refreshed this head at 07:35Z and still classifies the Windows artifact job as its own red. Existing base repairs are Windows #29075 and Chief eval #28888. They are outside this PR. The base-red scanner currently leaves Chief and clippy entries without step signatures ( |
WorkspaceSpawn.start: keep the base's row/rule split (New Workspace in New Group draws its pending row at the setting's place) and this branch's beforeCurrent exemption that keeps the current workspace for the rule.
|
Merged feat-cmux-next into this branch to clear conflicts (merge commit d5208fa). One file had a conflict:
All other files merged with no conflict. prepush-gate: no new violations. Fleet compile 30f4bee85d9fe107f564f45e: passed (CmuxNext, app, cmux-tui). |
|
Review (claude-rereview): FIX at d5208fa The code is correct. The merge is correct. But this head has stale generated settings files, and they cause reds of this PR's own. Regenerate them, then get a new review at the new head. Findings
What I checked
What I did not check
|
Conflicts resolved: - Workspace creation now goes through the base's WorkspaceSpawner (createAndShow, AgentSessionWorkspace.expectPlacement); the placement rule and ledger ride on those paths. AgentSessionWorkspace sends its rule to the daemon only when no explicit slot is set, as WorkspaceSpawner does. - windows.forgetCreate releases the placement ledger too (NewWorkspacePlacements.forget), so every base failure path frees it. - NewWorkspaceDefaultSlot (moved to CmuxNextBridge here) gains the base's `named` flag (agents chat new --top). - The unplaced-neighbour anchor reads the per-app SidebarDocument (services.sidebarDoc) instead of the removed SidebarDocWiring static. - SDK bindings regenerated with cmux-tui/bindings/codegen/generate.py. - Settings exports taken from the base; they are regenerated next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge routed WindowManager.forgetCreate through NewWorkspacePlacements.forget to release the placement ledger too, which rewrote a line #30961 landed this week (risk evidence's take-back hold). forgetCreate is back to the base's line; WorkspaceSpawner's two failure paths release the ledger beside it, as they did on this branch before the merge (an anchor `expect` armed for a create that never ran). Creates that reach WorkspaceCreation release it there already. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WorkspaceCreation.swift: the base's a06897f moved withTerminal onto EmptyWorkspaceRepair (repair.withTerminal); the PR's placement fields on the create (placesBySetting, current, placement) stay on the calls. CmdNRowSlotTests: the serialization comment names only the state that is still process-wide (PendingWorkspaceRows.shared); the sidebar document is per app now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Regenerated on the fleet (cmux-ci step 1e61b63af79672883880a155) from 74cc648. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The base's WorkspaceSpawner creates a workspace whose pin names a missing space in the window's own space instead of refusing it, so the test now fails the create through createAndShow's first-terminal step and checks the same release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: - Package.swift: CmuxNextBridge keeps the base's CCmuxAppFFI and this branch's CmuxNextSettings. - AgentTabs+OptimisticWorkspace.swift, AgentSessionWorkspace.swift: the base's firstTabKeyed and this branch's placedBy/ledger both pass through. - PersonalSidebar.swift: this branch's unplacedAnchor with the base's cached personal.workspacesInOrder. - NewWorkspaceDefaultSlot.swift: the slot rules live in CmuxNextBridge on this branch; the base's #33045 change (an afterCurrent create always moves, so from Home it takes the top, #32731) is ported there and applies to beforeCurrent too. NewWorkspaceFromHomePageTests covers beforeCurrent. - SDK bindings: regenerated with cmux-tui/bindings/codegen/generate.py --write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Regenerated on the fleet (cmux-ci step b8e6abd5da7cb704e7061c84, artifact sha256:40fc484ce6d8b55c16b2960847091a76514eb9e9caf00f92b4c037da15991658) from 0500d56. The merge had kept this branch's settings exports, dropping the base's new settings rows; against the base they now differ only by beforeCurrent (window.titlebar's default follows WindowTitlebarSetting.fallback, as on the newer base). NewWorkspaceFromHomePageTests: say which daemons anchor a before/after current create to their active workspace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…acement ledger as it was The test only compared groupAnchors, which a top create never sets, so it passed with no release at all. It now also checks anchors and placedByDaemon: a capable daemon's create marks it placed by the daemon, and the failed first terminal must release that mark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review (review_23071): SHIP at d7d50b4 Correctness-first subagent review of PR #23071. Owner manaflow-ai, PR author austinywang, agent review_23071, base Scope:
Findings and resolutionRound 1, at
Round 2, at
Round 3, at
Merge resolutions checked
Known gap, outside this merge
Not checkedThe reviewer did not build or run anything. The fleet runs are in the verification comment. |
No conflicts. The generated SDK bindings check fresh (generate.py --check). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n in-flight create never lists it again Regression tests that fail on 7fd2790 (the fix follows): - NewRowOneSlotTests: bottom lists below a trailing group; every placement waits for the current row while the rows catch up; an anchor outlives more than 16 creates in flight and ends when placed or closed. - CloseDuringCreateNoReappearTests: Cmd-N then Close Workspace with the daemon stopped never lists the closed workspace again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ws once at its slot Close (the workspace came back for a second, then left): - A close that takes an in-flight create hides the workspace itself (ClosingWorkspaces.hide(untilGone:)), not only its pending row: the store's copy listed in the row's place until the close landed. - A close that went through keeps its row hidden until no store holds the workspace (releaseGone, in the sidebar's tracked rows pass), not until a reply that can precede the store (resync, reconnect, batch). - Pending rows obey the close hide (PendingWorkspaceRows.shown). New row (the row animated a second move): - WorkspaceSlot.bottom without an anchor is last in the section, below a trailing group, where the daemon appends and the document lists it. - Every placement waits for the current row while the rows catch up, not only beforeCurrent/afterCurrent. - A neighbour anchor ends when the document places its workspace or the listed workspace is gone, never by a count prune that dropped the anchor of a create not yet sent. No delay, debounce or throttle: each change shows in one frame. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…top pending row waits for the current row Fail on 0ea0e3c (the fix follows): - WorkspaceLanesTests.aTakenCreateStaysOutstandingUntilItsCloseHasRun - NewRowOneSlotTests.aTopPendingRowWaitsForTheCurrentRowWhileCatchingUp Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w slot - A refused close of a taken create lists the workspace again (WorkspaceSpawn's lane close ends its hide on a failure); it stayed hidden until relaunch. - A taken create stays outstanding while its close runs (WorkspaceLanes.closing): a rows pass in the gap between the create's end and its close released the hide, and the row showed again. - A close that takes a create moves the window's selection at the press (InstantClose.begin), as any close does. - A pending row checks the current-row wait before its slot: under top the slot fell back to the section's top and the row moved into the group once the rows caught up. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s lane Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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. |
Sidebar polish: closed workspaces never come back, new rows draw oncePR: #23071 · login austin@manaflow.ai · agent Claude Code (Opus 5.5) · base feat-cmux-next 7cd4eb6 (merged) · head 65a5634 Dogfood feedback: "sometimes it over animates more than necessary, sometimes it's not optimistic and the workspace comes back on the sidebar for a second before disappearing again." Fixes (no delay, debounce or throttle; each change shows in one frame)
Red before, green after (fleet, Xcode 26.6,
|
This adds Before Current Workspace (
workspaces.newPlacement = "beforeCurrent") alongside Top, After Current Workspace, and Bottom. The app captures the current workspace before asynchronous creation and sends that placement to capable daemons, to align the preview with persisted order. Final-order assertions are strict; four per-frame assertions still document known intermittent row jumps.Top and Bottom retain the current group's first/last-slot behavior. Before/After Current fall back to the machine section's top when the selected workspace is Home, pinned, absent, or on another machine. Explicit Above/Below placements keep their existing fallback. Failed creates release their placement ledger entries, including agent entrypoints. Before Current also preserves group slots when dense saved positions must be renumbered. Placement calculations and transient ledger state live in the Bridge domain; window/machine wiring stays in the app.
The base's ordered pending-placement queue, cold-sidebar anchor deferral, shared document refresh, indefinite late-terminal-start handling, first-tab chat behavior, and remote-close baseline are preserved.
Size: First-frame placement requires a coordinated app, daemon, protocol-binding, localization, and regression-test change; splitting it would leave those placement rules inconsistent.
Takes back #26153: replaces its inline failed-create pending-placement cleanup in
WorkspaceSpawn.swiftwith the sharedNewWorkspacePlacements.forgethelper. The helper still removes the pending entry and registration order, and also releases the placement ledger. The ordered queue and shared placement sequencing remain intact.Validation
37869556602714dd37a5d7a9f7cc9d7f1cdd667b, formatting, 45 focused placement tests, and clippy forcmux-tui-core --all-targets -D warningspassed.162aa7637e51a34472460b3breproduced missing-current fallback and failed-first-tab cleanup;e33acb70687a488d0de6252dreproduced trailing-group corruption and two registration leaks at their expected assertions.4fe8b5d563f4954b500aadbacompiled all native test targets and passed four managed-preference plus six settings-schema tests on2881639c1d62eda40d8226bee48af3a701725f14. Its generated patch restores the base's sidebar text-size entry and theme copy.ba3e178df2439353c90dc633passed all 11 requested suites (46 executed tests) atc86bcabdb57ccdf57b83dedd4d6b04c37b6ac709. Exact-head fleet step556201a3433cf1233b755242also passed all 11 suites ataaf91a901c9411ada04d13b63bcc16f38700d647(exit 0).42aaf9034c2c39e9772ae5a523003539cb514f21merges base5aee3770f46ec7534f81fac338bd549aa3b261b5and applies the fleet-generated schema. Export stepcb6ee59849c1ca5095e4568dcompiled all native test targets and passed all four managed-preference and six settings-export tests at its parent37869556602714dd37a5d7a9f7cc9d7f1cdd667b. The generated delta is one localization key; it does not change the settings reference text.fe842e7101806ae9e74da2b6passed all 11 focused Swift suites (46 tests, exit 0) at42aaf9034c2c39e9772ae5a523003539cb514f21; summary artifactsha256:1a5547860c1e4f7aa2f5a79a4c6695b139aaaaf92da201f2707e9e5569b33198.af95a3fe1965909c4c0b04d8completed successfully. The fleet Release compile check and defaults guard rerun also passed.Focused Swift command (on the fleet):
Focused Rust command (on rbx):
cargo nextest run --locked -p cmux-tui-core -p cmux-tui-util -E 'test(sidebar_doc_order) | test(personal_order) | test(mixed_order) | test(workspace_create_current) | test(placement)'Observed / Not run
Observed: red-before regressions; Rust placement tests and clippy at
37869556602714dd37a5d7a9f7cc9d7f1cdd667b; all 11 scoped Swift suites (46 tests) at current head42aaf9034c2c39e9772ae5a523003539cb514f21; fleet compilation of test targets and passing settings exporters at 378; SDK/syntax/static checks; earlier independent SHIP and visual reviews. The current head adds only the generated localization-key repair after the 378 base merge.Not run: OS 14/15 interaction checks and controlled placement-latency measurements. Freestyle web validation is unavailable because this Mac lacks its runner configuration; no heavy web checks were run locally for this repair.
Native capture at
aaf91a901c9411ada04d13b63bcc16f38700d647, fleet build4fc178e1d193307352013c50: all eight fixture steps passed. Independent visual review passed light and dark; the stills show Before Two immediately before selected Two. The capture mini's text scan and the trusted main-branch privacy check approved both images before upload. These stills predate the latest base merge and schema-only repair; they do not establish latency or a before/after comparison. No new runtime change followed that base merge, so no recapture was requested for the schema-key repair.Inherited failures: base-red evidence covers Chief
eval_upselland the Rust panic-ratchet debt outside this PR. Release-notary fails the same twoRunsOnFallbackTestsas base run; this PR changes neither workflows nor the routing tests. Only PR-caused failures are repaired here.Performance
No perf numbers: the frame-order sampling and behavioral regressions establish placement correctness, not an input-to-frame latency distribution. No performance improvement is claimed.
Changelog
Added: Before Current Workspace as a new workspace position, with consistent initial sidebar placement and failure cleanup.