Skip to content

cmux NEXT sidebar: a workspace opened into a named group appears straight in its group, never loose first - #33578

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
lane/new-ws-placement
Nov 3, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
lane/new-ws-placement

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-11-03: "likewise, i hate it when you guys make new worksapces or whatever and they appear for a split second and it's just bloop and then it goes into presumably whichever group... idk how we wanna solve that it's just weird how it flickers into some top level group or whatever then goes away"

leo-named-fix: land on push.

What happened

acpmux new --group / cmux agent open --group run agent.openSessionWorkspace. The daemon's workspace.create lists the new workspace with the loose rows; the app's join (AgentSessionWorkspace.join, a sidebar-document move or group.create) runs only once the daemon reports the workspace (WindowManager.applyPendingPlacements). So the sidebar drew a pass with the row at top level, then a pass with it in its group: two sidebar renders of two daemon states (created, then grouped).

Regressing PR: #30583 removed the first stop (Cmd-N's slot in the window's current group) but left this one, since the join has always followed the create (#24162 / #22809 made the join a post-create move).

Fix (mechanism b: a bounded hold)

  • GroupJoinHold / GroupJoinRows (CmuxNextSidebar, pure logic + one DemandTimer): a workspace opened with --group is held. While a pass lists it outside every group, the pass leaves its row out; the first pass that lists it in a group releases it, so it draws once, in its group, and no other row moves. Bound: 2 s from its first loose listing (a slow create spends none of it), then it shows where it lists; a one-shot deadline re-runs the pass so it shows even with no other change. A create that fails or is closed releases it (PendingWorkspaceRows.remove). Only while the sidebar document is active (the join path that moves an unlisted row).
  • SidebarEdits.group(named:accepting:in:machine:): the join reads the window's rows, which now leave the held row out, so a named group takes it by its machine (the same canPlace rule a drag uses).
  • SidebarEdits.removing(_:from:) moved out of the App (pure); App Swift lines −17.

Mechanism (a) (the create carrying the group) would need workspace.create to take a document group placement in its commit; the hold covers every create that does not.

Spec: plans/cmux-next/sidebar-owner.md ("A new row appears once, in its final place").

Tests

GroupJoinHoldTests (CmuxNextAppTests): every intermediate pass of a grouped create (create, passes between, join) never draws the row outside a group, and no other row is left out; the limit's fallback shows a row whose join never lands; a slow create is held from its first listing; a released create is not held; a held row's group is found by its machine. Red on base: the type does not exist there, and without the hold the create's pass draws n loose.

Observed / Not run

  • Ran: scripts/cmux-next/prepush-gate.py --base origin/feat-cmux-next --head HEAD: no new violations.
  • Not run yet: the Swift suite and compile (this host has no fleet client); they run in PR CI. Not tried in a DEV build yet.

Changelog

Fixed: A workspace an agent opens into a sidebar group appears straight in that group instead of flashing at the top level first.

Agent session: agent session

🤖 Generated with Claude Code


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


Summary by cubic

Fixes the sidebar flicker where a workspace opened with --group (via acpmux new or cmux agent open) appeared at the top level briefly before jumping into its named group. The row is now held out of the sidebar while the daemon lists it loose, and it draws from the first pass that lists it in its group.

  • The hold is bounded at 2 seconds from the row's first loose listing; a join that never lands shows the row once the limit passes, and a failed or closed create releases the hold.
  • The join picks the named group by the workspace's machine, since its held row is absent from the listing.
  • GroupJoinHoldTests covers intermediate passes, the limit fallback, slow creates, released creates, and machine-based group lookup.

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

View guided diff Turn on auto-fix

…ight in its group, never loose first

Leo, 2026-11-03: "it's just weird how it flickers into some top level group or whatever then goes away".
The daemon's create lists an `acpmux new --group` workspace loose and its join moves it a hop later; the
sidebar now leaves the row out while it lists loose (bounded: 2 s from its first loose listing).

Sidebar-Look: "i hate it when you guys make new worksapces or whatever and they appear for a split second and it's just bloop and then it goes into presumably whichever group"

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

cursor Bot commented Nov 3, 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 Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

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

Review f402795: 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=pr33578 -f ref=lane/new-ws-placement -f platform=macos -f backend_mode=local

Shipped in:

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/41619934635 at 092736d failed: cmux-next fleet Release compile.
Those jobs last passed at 8cc02ce. This pull request is one of 5 merged since: #33578, #33567, #33411, #33407, #33405.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

Sidebar-Look: no visual change

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-afd6b50010c3928f80c9
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 3, 2026
@blacksmith-sh

blacksmith-sh Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Found 7 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp3yed_yff/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmp6_fml4o7/summary-missing.json (live):/summary-missing.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
test_every_compile_job_names_its_warm_sources (main.ThisTree.test_every_compile_job
_names_its_warm_sources)/
test_every_compile_job_names_its_warm_sources (main.ThisTree.test_every_compile_job
_names_its_warm_sources)
View Logs

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

@teamleaderleo teamleaderleo added the leo-named-fix An obvious fix to something Leo named: lands on push, review runs in parallel label Nov 3, 2026
@teamleaderleo
teamleaderleo merged commit f0db136 into feat-cmux-next Nov 3, 2026
179 of 192 checks passed
@teamleaderleo
teamleaderleo deleted the lane/new-ws-placement branch November 3, 2026 10:26
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…hold

Follow-up from the #33578 review: a grouped create that fails or is undone left its
hold in place, so every later sidebar pass walked the rows for it. A hold whose
workspace has not listed within 3 minutes (past the 2-minute create budget) goes.

Sidebar-Look: no visual change

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-afd6b50010c3928f80c9
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…own limit

Codex review of #33578: the limit timer always waited a full 2 s, so a second hold
first listed a second after the first stayed hidden about 3 s. The deadline is now
the earliest loose-listed hold's remaining time, and a hold past its bound goes even
when the pass no longer lists it, so the next deadline is never one already past.

Sidebar-Look: no visual change

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-afd6b50010c3928f80c9
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
f0db136 (#33578) declared a public @observable type with an internal
import of Observation, so CmuxNextSidebar did not emit its module
(compile check of the dot-size landing at 526f2a1).

Sidebar-Look: no visual change
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
f0db136 (#33578) declared a public @observable type with an internal
import of Observation, so CmuxNextSidebar did not emit its module
(compile check of the dot-size landing at 526f2a1).

Sidebar-Look: no visual change
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at f402795

SHIP at f402795
Visual verdict: no images; Leo tries the build

  1. [P2] [follow-up] GroupJoinHold.swift:82: Schedule the earliest remaining expiry instead of another full two seconds. With loose rows first listed at t=0 and t=1, the t=2 callback schedules t=4; the second row stays hidden for three seconds if its join fails. Add coverage for staggered holds.
  2. [P2] [follow-up] PendingWorkspaceRows.swift:105: Supply a native capture of grouped creation; no after images were provided.

Native compilation and Swift tests were unavailable in this box.

Follow-ups:

  • Correct the timer’s remaining-deadline scheduling and test staggered holds.
  • Capture the grouped-create transition.

lawrencecchen added a commit that referenced this pull request Nov 3, 2026
…0db136 #33578)

GroupJoinRows is a public @observable class, so its Observable conformance
needs Observation imported publicly; the internal import broke the
CmuxNextSidebar module build (compile-check 3927077c39feeffed036e12c).

Sidebar-Look: no visual change
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
f0db136 (#33578) declared a public @observable type with an internal
import of Observation, so CmuxNextSidebar did not emit its module
(compile check of the dot-size landing at 526f2a1).

Sidebar-Look: no visual change
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…e compile red since #33578)

GroupJoinRows is a public @observable class, so its Observable conformance needs a public import of Observation
(GroupJoinHold.swift:85: "cannot use protocol 'Observable' in a public or '@usableFromInline' conformance"), as
SidebarDocStore.swift already does.

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

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


For awareness: this merge (f0db136) turned the cmux-next Release compile red on feat-cmux-next: GroupJoinHold.swift:85: cannot use protocol 'Observable' in a public ... conformance; 'Observation' was not imported publicly. The one-line fix-forward is #33680 (public import Observation).

lawrencecchen added a commit that referenced this pull request Nov 3, 2026
…vation import (CmuxNextSidebar did not build after #33578)

f0db136 (#33578) made GroupJoinRows public with @observable while
GroupJoinHold.swift imported Observation internally, so emitting the
CmuxNextSidebar module failed: "cannot use protocol 'Observable' in a public
conformance; 'Observation' was not imported publicly" (cmux-ci compile check
aacf17673abf288f0b6bed77, gallery step e1a631e765ee6876eba91b29).

Sidebar-Look: no visual change (import only)
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…e compile red since #33578)

GroupJoinRows is a public @observable class, so its Observable conformance needs a public import of Observation
(GroupJoinHold.swift:85: "cannot use protocol 'Observable' in a public or '@usableFromInline' conformance"), as
SidebarDocStore.swift already does.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-6b98f3ccf38f5d4bc316
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
…0db136 #33578)

GroupJoinRows is a public @observable class, so its Observable conformance
needs Observation imported publicly; the internal import broke the
CmuxNextSidebar module build (compile-check 3927077c39feeffed036e12c).

Sidebar-Look: no visual change
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
f0db136 (#33578) declared a public @observable type with an internal
import of Observation, so CmuxNextSidebar did not emit its module;
dbd397c (#33621) called WorkspaceIcon.emoji without its chip: label,
so CmuxNextAppTests did not compile (compile checks of the dot-size
landing, a8598cb7ad990ce789cded11).

Sidebar-Look: no visual change
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…e compile red since #33578) (#33680)

GroupJoinRows is a public @observable class, so its Observable conformance needs a public import of Observation
(GroupJoinHold.swift:85: "cannot use protocol 'Observable' in a public or '@usableFromInline' conformance"), as
SidebarDocStore.swift already does.

Sidebar-Look: no visual change

Agent-Session: https://cmux.com/deeplink/agent?id=aid-6b98f3ccf38f5d4bc316

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
…ion import

#33578 (f0db136) left feat-cmux-next's CmuxNext emit-module red: 'cannot use protocol
Observable in a public conformance; Observation was not imported publicly'.

Sidebar-Look: no visual change
lawrencecchen added a commit that referenced this pull request Nov 3, 2026
f0db136 (#33578) declared a public @observable type with an internal
import of Observation, so CmuxNextSidebar did not emit its module;
dbd397c (#33621) called WorkspaceIcon.emoji without its chip: label,
so CmuxNextAppTests did not compile (compile checks of the dot-size
landing, a8598cb7ad990ce789cded11).

Sidebar-Look: no visual change
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…pile red from #33578) (#33653)

GroupJoinRows is a public @observable class, so its Observable conformance
needs Observation imported publicly; the Release compile failed with
'Observation was not imported publicly'.


Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64

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

Copy link
Copy Markdown
Contributor

Swift logic follow-up (tip watcher swift-logic row, STATUS 13027 "SWIFT LOGIC CULPRITS"; lead order).

This PR raised swift_logic_lines by +78 at its merge commit f0db136: scripts/cmux-next/swift-logic-lines.py before and after the merge, with the same table (the tip's, c6be943). The largest declarations of the rise:

  • struct GroupJoinHold in Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/GroupJoinHold.swift: +49 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)
  • extension SidebarEdits in Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift: +27 lines counted as Swift logic (its row counts it as logic)
  • class GroupJoinRows in Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/GroupJoinHold.swift: +21 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)

plans/cmux-next/layer-ownership.md says Rust owns every state, list and rule and Swift is the platform shell. Please move the new logic of this PR in a follow-up: to Rust (the crate that owns the area; the owner lists in STATUS 12147-12165 name the target per area), or at least out of the app into its package. If a declaration above is platform code (AppKit, Core Animation, OS calls, strings, tokens, DEBUG tooling), reply here and the table gets a PLATFORM row with your reason instead.

The swift-logic row is a report, not a gate: nothing blocks on this comment.

This branch was previously deployed

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

Labels

leo-named-fix An obvious fix to something Leo named: lands on push, review runs in parallel risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants